diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2021-06-19 17:42:35 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2021-06-19 17:42:35 +0200 |
commit | 25128176c46b169cdec2c18b5730c36a940f6eb0 (patch) | |
tree | e32adf3b8c49e1b797f4e3c374287699d28d6f44 | |
parent | 97c3b5e3ff252b3399d10835d5c906886a7499f4 (diff) | |
download | busybox-w32-25128176c46b169cdec2c18b5730c36a940f6eb0.tar.gz busybox-w32-25128176c46b169cdec2c18b5730c36a940f6eb0.tar.bz2 busybox-w32-25128176c46b169cdec2c18b5730c36a940f6eb0.zip |
taskset: implement -a
function old new delta
process_pid_str - 854 +854
.rodata 103363 103378 +15
packed_usage 33654 33658 +4
taskset_main 936 190 -746
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 2/1 up/down: 873/-746) Total: 127 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | util-linux/taskset.c | 108 |
1 files changed, 69 insertions, 39 deletions
diff --git a/util-linux/taskset.c b/util-linux/taskset.c index b542f8c83..abec04933 100644 --- a/util-linux/taskset.c +++ b/util-linux/taskset.c | |||
@@ -34,10 +34,12 @@ | |||
34 | //kbuild:lib-$(CONFIG_TASKSET) += taskset.o | 34 | //kbuild:lib-$(CONFIG_TASKSET) += taskset.o |
35 | 35 | ||
36 | //usage:#define taskset_trivial_usage | 36 | //usage:#define taskset_trivial_usage |
37 | //usage: "[-p] [HEXMASK] PID | PROG ARGS" | 37 | //usage: "[-ap] [HEXMASK"IF_FEATURE_TASKSET_CPULIST(" | -c LIST")"] { PID | PROG ARGS }" |
38 | //usage:#define taskset_full_usage "\n\n" | 38 | //usage:#define taskset_full_usage "\n\n" |
39 | //usage: "Set or get CPU affinity\n" | 39 | //usage: "Set or get CPU affinity\n" |
40 | //usage: "\n -p Operate on an existing PID" | 40 | //usage: "\n -p Operate on PID" |
41 | //usage: "\n -a Operate on all threads" | ||
42 | //usage: "\n -c Affinity is a list, not mask" | ||
41 | //usage: | 43 | //usage: |
42 | //usage:#define taskset_example_usage | 44 | //usage:#define taskset_example_usage |
43 | //usage: "$ taskset 0x7 ./dgemm_test&\n" | 45 | //usage: "$ taskset 0x7 ./dgemm_test&\n" |
@@ -205,42 +207,18 @@ static void print_cpulist(const ul *mask, unsigned mask_size_in_bytes) | |||
205 | } | 207 | } |
206 | #endif | 208 | #endif |
207 | 209 | ||
208 | int taskset_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 210 | enum { |
209 | int taskset_main(int argc UNUSED_PARAM, char **argv) | 211 | OPT_p = 1 << 0, |
212 | OPT_a = 1 << 1, | ||
213 | OPT_c = (1 << 2) * ENABLE_FEATURE_TASKSET_CPULIST, | ||
214 | }; | ||
215 | |||
216 | static void process_pid_str(const char *pid_str, unsigned opts, char *aff) | ||
210 | { | 217 | { |
211 | ul *mask; | 218 | ul *mask; |
212 | unsigned mask_size_in_bytes; | 219 | unsigned mask_size_in_bytes; |
213 | pid_t pid = 0; | ||
214 | const char *current_new; | 220 | const char *current_new; |
215 | char *aff; | 221 | pid_t pid = xatoi_positive(pid_str); |
216 | unsigned opts; | ||
217 | enum { | ||
218 | OPT_p = 1 << 0, | ||
219 | OPT_c = (1 << 1) * ENABLE_FEATURE_TASKSET_CPULIST, | ||
220 | }; | ||
221 | |||
222 | /* NB: we mimic util-linux's taskset: -p does not take | ||
223 | * an argument, i.e., "-pN" is NOT valid, only "-p N"! | ||
224 | * Indeed, util-linux-2.13-pre7 uses: | ||
225 | * getopt_long(argc, argv, "+pchV", ...), not "...p:..." */ | ||
226 | |||
227 | opts = getopt32(argv, "^+" "p"IF_FEATURE_TASKSET_CPULIST("c") | ||
228 | "\0" "-1" /* at least 1 arg */); | ||
229 | argv += optind; | ||
230 | |||
231 | aff = *argv++; | ||
232 | if (opts & OPT_p) { | ||
233 | char *pid_str = aff; | ||
234 | if (*argv) { /* "-p <aff> <pid> ...rest.is.ignored..." */ | ||
235 | pid_str = *argv; /* NB: *argv != NULL in this case */ | ||
236 | } | ||
237 | /* else it was just "-p <pid>", and *argv == NULL */ | ||
238 | pid = xatoul_range(pid_str, 1, ((unsigned)(pid_t)ULONG_MAX) >> 1); | ||
239 | } else { | ||
240 | /* <aff> <cmd...> */ | ||
241 | if (!*argv) | ||
242 | bb_show_usage(); | ||
243 | } | ||
244 | 222 | ||
245 | mask_size_in_bytes = SZOF_UL; | 223 | mask_size_in_bytes = SZOF_UL; |
246 | current_new = "current"; | 224 | current_new = "current"; |
@@ -255,13 +233,12 @@ int taskset_main(int argc UNUSED_PARAM, char **argv) | |||
255 | #endif | 233 | #endif |
256 | printf("pid %d's %s affinity mask: "TASKSET_PRINTF_MASK"\n", | 234 | printf("pid %d's %s affinity mask: "TASKSET_PRINTF_MASK"\n", |
257 | pid, current_new, from_mask(mask, mask_size_in_bytes)); | 235 | pid, current_new, from_mask(mask, mask_size_in_bytes)); |
258 | if (*argv == NULL) { | 236 | if (!aff) { |
259 | /* Either it was just "-p <pid>", | 237 | /* Either it was just "-p <pid>", |
260 | * or it was "-p <aff> <pid>" and we came here | 238 | * or it was "-p <aff> <pid>" and we came here |
261 | * for the second time (see goto below) */ | 239 | * for the second time (see goto below) */ |
262 | return EXIT_SUCCESS; | 240 | return; |
263 | } | 241 | } |
264 | *argv = NULL; | ||
265 | current_new = "new"; | 242 | current_new = "new"; |
266 | } | 243 | } |
267 | memset(mask, 0, mask_size_in_bytes); | 244 | memset(mask, 0, mask_size_in_bytes); |
@@ -331,8 +308,61 @@ int taskset_main(int argc UNUSED_PARAM, char **argv) | |||
331 | bb_perror_msg_and_die("can't %cet pid %d's affinity", 's', pid); | 308 | bb_perror_msg_and_die("can't %cet pid %d's affinity", 's', pid); |
332 | //bb_error_msg("set mask[0]:%lx", mask[0]); | 309 | //bb_error_msg("set mask[0]:%lx", mask[0]); |
333 | 310 | ||
334 | if (!argv[0]) /* "-p <aff> <pid> [...ignored...]" */ | 311 | if ((opts & OPT_p) && aff) { /* "-p <aff> <pid> [...ignored...]" */ |
312 | aff = NULL; | ||
335 | goto print_aff; /* print new affinity and exit */ | 313 | goto print_aff; /* print new affinity and exit */ |
314 | } | ||
315 | } | ||
316 | |||
317 | int taskset_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | ||
318 | int taskset_main(int argc UNUSED_PARAM, char **argv) | ||
319 | { | ||
320 | const char *pid_str; | ||
321 | char *aff; | ||
322 | unsigned opts; | ||
323 | |||
324 | /* NB: we mimic util-linux's taskset: -p does not take | ||
325 | * an argument, i.e., "-pN" is NOT valid, only "-p N"! | ||
326 | * Indeed, util-linux-2.13-pre7 uses: | ||
327 | * getopt_long(argc, argv, "+pchV", ...), not "...p:..." */ | ||
328 | |||
329 | opts = getopt32(argv, "^+" "pa"IF_FEATURE_TASKSET_CPULIST("c") | ||
330 | "\0" "-1" /* at least 1 arg */); | ||
331 | argv += optind; | ||
336 | 332 | ||
337 | BB_EXECVP_or_die(argv); | 333 | aff = *argv++; |
334 | if (!(opts & OPT_p)) { | ||
335 | /* <aff> <cmd...> */ | ||
336 | if (!*argv) | ||
337 | bb_show_usage(); | ||
338 | process_pid_str("0", opts, aff); | ||
339 | BB_EXECVP_or_die(argv); | ||
340 | } | ||
341 | |||
342 | pid_str = aff; | ||
343 | if (*argv) /* "-p <aff> <pid> ...rest.is.ignored..." */ | ||
344 | pid_str = *argv; /* NB: *argv != NULL in this case */ | ||
345 | else | ||
346 | aff = NULL; | ||
347 | |||
348 | if (opts & OPT_a) { | ||
349 | char dn[sizeof("/proc/%s/task") + 3 * sizeof(int)]; | ||
350 | DIR *dir; | ||
351 | struct dirent *ent; | ||
352 | |||
353 | sprintf(dn, "/proc/%s/task", pid_str); | ||
354 | dir = opendir(dn); | ||
355 | if (!dir) { | ||
356 | goto no_threads; | ||
357 | } | ||
358 | while ((ent = readdir(dir)) != NULL) { | ||
359 | if (isdigit(ent->d_name[0])) | ||
360 | process_pid_str(ent->d_name, opts, aff); | ||
361 | } | ||
362 | IF_FEATURE_CLEAN_UP(closedir(dir);) | ||
363 | } else { | ||
364 | no_threads: | ||
365 | process_pid_str(pid_str, opts, aff); | ||
366 | } | ||
367 | return EXIT_SUCCESS; | ||
338 | } | 368 | } |