aboutsummaryrefslogtreecommitdiff
path: root/miscutils
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2014-08-17 19:36:22 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2014-08-17 19:36:22 +0200
commit962c4e822012a6d4c83b869eb47506881b4abc57 (patch)
tree6f23eaa2b896bcb65d081014682b564ffc0dd6fe /miscutils
parentfb8d1ef2d00db013eae3cc675fc8b34fd0a7a987 (diff)
downloadbusybox-w32-962c4e822012a6d4c83b869eb47506881b4abc57.tar.gz
busybox-w32-962c4e822012a6d4c83b869eb47506881b4abc57.tar.bz2
busybox-w32-962c4e822012a6d4c83b869eb47506881b4abc57.zip
taskset: support CPU masks for more than 64 CPUs
function old new delta taskset_main 522 631 +109 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'miscutils')
-rw-r--r--miscutils/Config.src16
-rw-r--r--miscutils/Kbuild.src1
-rw-r--r--miscutils/taskset.c86
3 files changed, 79 insertions, 24 deletions
diff --git a/miscutils/Config.src b/miscutils/Config.src
index 1b2a3ae9a..d69abf1a2 100644
--- a/miscutils/Config.src
+++ b/miscutils/Config.src
@@ -499,22 +499,6 @@ config STRINGS
499 strings prints the printable character sequences for each file 499 strings prints the printable character sequences for each file
500 specified. 500 specified.
501 501
502config TASKSET
503 bool "taskset"
504 default n # doesn't build on some non-x86 targets (m68k)
505 help
506 Retrieve or set a processes's CPU affinity.
507 This requires sched_{g,s}etaffinity support in your libc.
508
509config FEATURE_TASKSET_FANCY
510 bool "Fancy output"
511 default y
512 depends on TASKSET
513 help
514 Add code for fancy output. This merely silences a compiler-warning
515 and adds about 135 Bytes. May be needed for machines with alot
516 of CPUs.
517
518config TIME 502config TIME
519 bool "time" 503 bool "time"
520 default y 504 default y
diff --git a/miscutils/Kbuild.src b/miscutils/Kbuild.src
index 8eaa82de9..7b449e6e8 100644
--- a/miscutils/Kbuild.src
+++ b/miscutils/Kbuild.src
@@ -39,7 +39,6 @@ lib-$(CONFIG_RUNLEVEL) += runlevel.o
39lib-$(CONFIG_RX) += rx.o 39lib-$(CONFIG_RX) += rx.o
40lib-$(CONFIG_SETSID) += setsid.o 40lib-$(CONFIG_SETSID) += setsid.o
41lib-$(CONFIG_STRINGS) += strings.o 41lib-$(CONFIG_STRINGS) += strings.o
42lib-$(CONFIG_TASKSET) += taskset.o
43lib-$(CONFIG_TIME) += time.o 42lib-$(CONFIG_TIME) += time.o
44lib-$(CONFIG_TIMEOUT) += timeout.o 43lib-$(CONFIG_TIMEOUT) += timeout.o
45lib-$(CONFIG_TTYSIZE) += ttysize.o 44lib-$(CONFIG_TTYSIZE) += ttysize.o
diff --git a/miscutils/taskset.c b/miscutils/taskset.c
index 4a9e3230d..8bd32ed61 100644
--- a/miscutils/taskset.c
+++ b/miscutils/taskset.c
@@ -6,6 +6,25 @@
6 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 6 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
7 */ 7 */
8 8
9//config:config TASKSET
10//config: bool "taskset"
11//config: default n # doesn't build on some non-x86 targets (m68k)
12//config: help
13//config: Retrieve or set a processes's CPU affinity.
14//config: This requires sched_{g,s}etaffinity support in your libc.
15//config:
16//config:config FEATURE_TASKSET_FANCY
17//config: bool "Fancy output"
18//config: default y
19//config: depends on TASKSET
20//config: help
21//config: Add code for fancy output. This merely silences a compiler-warning
22//config: and adds about 135 Bytes. May be needed for machines with alot
23//config: of CPUs.
24
25//applet:IF_TASKSET(APPLET(taskset, BB_DIR_USR_BIN, BB_SUID_DROP))
26//kbuild:lib-$(CONFIG_TASKSET) += taskset.o
27
9//usage:#define taskset_trivial_usage 28//usage:#define taskset_trivial_usage
10//usage: "[-p] [MASK] [PID | PROG ARGS]" 29//usage: "[-p] [MASK] [PID | PROG ARGS]"
11//usage:#define taskset_full_usage "\n\n" 30//usage:#define taskset_full_usage "\n\n"
@@ -22,6 +41,11 @@
22//usage: "pid 6671's new affinity mask: 1\n" 41//usage: "pid 6671's new affinity mask: 1\n"
23//usage: "$ taskset -p 1\n" 42//usage: "$ taskset -p 1\n"
24//usage: "pid 1's current affinity mask: 3\n" 43//usage: "pid 1's current affinity mask: 3\n"
44/*
45 Not yet implemented:
46 * -a/--all-tasks (affect all threads)
47 * -c/--cpu-list (specify CPUs via "1,3,5-7")
48 */
25 49
26#include <sched.h> 50#include <sched.h>
27#include "libbb.h" 51#include "libbb.h"
@@ -128,17 +152,65 @@ int taskset_main(int argc UNUSED_PARAM, char **argv)
128 current_new += 8; /* "new" */ 152 current_new += 8; /* "new" */
129 } 153 }
130 154
131 { /* Affinity was specified, translate it into cpu_set_t */ 155 /* Affinity was specified, translate it into cpu_set_t */
156 CPU_ZERO(&mask);
157 if (!ENABLE_FEATURE_TASKSET_FANCY) {
132 unsigned i; 158 unsigned i;
159 unsigned long long m;
160
133 /* Do not allow zero mask: */ 161 /* Do not allow zero mask: */
134 unsigned long long m = xstrtoull_range(aff, 0, 1, ULLONG_MAX); 162 m = xstrtoull_range(aff, 0, 1, ULLONG_MAX);
135 enum { CNT_BIT = CPU_SETSIZE < sizeof(m)*8 ? CPU_SETSIZE : sizeof(m)*8 }; 163 i = 0;
164 do {
165 if (m & 1)
166 CPU_SET(i, &mask);
167 i++;
168 m >>= 1;
169 } while (m != 0);
170 } else {
171 unsigned i;
172 char *last_byte;
173 char *bin;
174 uint8_t bit_in_byte;
175
176 /* Cheap way to get "long enough" buffer */
177 bin = xstrdup(aff);
178
179 if (aff[0] != '0' && (aff[1]|0x20) != 'x') {
180/* TODO: decimal/octal masks are still limited to 2^64 */
181 unsigned long long m = xstrtoull_range(aff, 0, 1, ULLONG_MAX);
182 bin += strlen(bin);
183 last_byte = bin - 1;
184 while (m) {
185 *--bin = m & 0xff;
186 m >>= 8;
187 }
188 } else {
189 /* aff is "0x.....", we accept very long masks in this form */
190 last_byte = hex2bin(bin, aff + 2, INT_MAX);
191 if (!last_byte) {
192 bad_aff:
193 bb_error_msg_and_die("bad affinity '%s'", aff);
194 }
195 last_byte--; /* now points to the last byte */
196 }
136 197
137 CPU_ZERO(&mask); 198 i = 0;
138 for (i = 0; i < CNT_BIT; i++) { 199 bit_in_byte = 1;
139 unsigned long long bit = (1ULL << i); 200 while (last_byte >= bin) {
140 if (bit & m) 201 if (bit_in_byte & *last_byte) {
202 if (i >= CPU_SETSIZE)
203 goto bad_aff;
141 CPU_SET(i, &mask); 204 CPU_SET(i, &mask);
205 //bb_error_msg("bit %d set", i);
206 }
207 i++;
208 /* bit_in_byte is uint8_t! & 0xff is implied */
209 bit_in_byte = (bit_in_byte << 1);
210 if (!bit_in_byte) {
211 bit_in_byte = 1;
212 last_byte--;
213 }
142 } 214 }
143 } 215 }
144 216