X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;ds=inline;f=miscutils%2Ftaskset.c;h=77fc8643d5eba73bca5a613de9bb09db1eae80ba;hb=c13ee8c0f32fa816e12f1ac0c55a800066dc1560;hp=cd8ffc8400d5a3739b6b2a7862576ed638afeecf;hpb=b6adbf1be29841501cc49917249e85f273e1df7c;p=oweals%2Fbusybox.git diff --git a/miscutils/taskset.c b/miscutils/taskset.c index cd8ffc840..77fc8643d 100644 --- a/miscutils/taskset.c +++ b/miscutils/taskset.c @@ -1,99 +1,154 @@ /* vi: set sw=4 ts=4: */ /* * taskset - retrieve or set a processes' CPU affinity - * Copyright (c) 2006 Bernhard Fischer + * Copyright (c) 2006 Bernhard Reutner-Fischer * - * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. + * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ +//usage:#define taskset_trivial_usage +//usage: "[-p] [MASK] [PID | PROG ARGS]" +//usage:#define taskset_full_usage "\n\n" +//usage: "Set or get CPU affinity\n" +//usage: "\nOptions:" +//usage: "\n -p Operate on an existing PID" +//usage: +//usage:#define taskset_example_usage +//usage: "$ taskset 0x7 ./dgemm_test&\n" +//usage: "$ taskset -p 0x1 $!\n" +//usage: "pid 4790's current affinity mask: 7\n" +//usage: "pid 4790's new affinity mask: 1\n" +//usage: "$ taskset 0x7 /bin/sh -c './taskset -p 0x1 $$'\n" +//usage: "pid 6671's current affinity mask: 1\n" +//usage: "pid 6671's new affinity mask: 1\n" +//usage: "$ taskset -p 1\n" +//usage: "pid 1's current affinity mask: 3\n" + #include -#include /* optind */ #include "libbb.h" #if ENABLE_FEATURE_TASKSET_FANCY #define TASKSET_PRINTF_MASK "%s" -#define from_cpuset(x) __from_cpuset(&x) /* craft a string from the mask */ -static char *__from_cpuset(cpu_set_t *mask) +static char *from_cpuset(cpu_set_t *mask) { int i; - char *ret = 0, *str = xzalloc(9); + char *ret = NULL; + char *str = xzalloc((CPU_SETSIZE / 4) + 1); /* we will leak it */ for (i = CPU_SETSIZE - 4; i >= 0; i -= 4) { - char val = 0; + int val = 0; int off; for (off = 0; off <= 3; ++off) - if (CPU_ISSET(i+off, mask)) - val |= 1< */ - aff = p_opt; - p_opt = argv[optind]; - } - argv += optind; /* me -p */ - pid = xatoul_range(p_opt, 1, ULONG_MAX); /* -p */ - } else - aff = *++argv; /* */ - if (aff) { - unsigned i = 0; - unsigned long l = xstrtol_range(aff, 0, 1, LONG_MAX); - - CPU_ZERO(&new_mask); - while (i < CPU_SETSIZE && l >= (1< ...rest.is.ignored..." */ + aff = pid_str; + pid_str = *argv; /* NB: *argv != NULL in this case */ } + /* else it was just "-p ", and *argv == NULL */ + pid = xatoul_range(pid_str, 1, ((unsigned)(pid_t)ULONG_MAX) >> 1); + } else { + aff = *argv++; /* */ + if (!*argv) + bb_show_usage(); } - if (opt & OPT_p) { + current_new = "current\0new"; + if (opt_p) { print_aff: if (sched_getaffinity(pid, sizeof(mask), &mask) < 0) - bb_perror_msg_and_die("failed to %cet pid %d's affinity", 'g', pid); + bb_perror_msg_and_die("can't %cet pid %d's affinity", 'g', pid); printf("pid %d's %s affinity mask: "TASKSET_PRINTF_MASK"\n", - pid, state, from_cpuset(mask)); - if (!*argv) /* no new affinity given or we did print already, done. */ + pid, current_new, from_cpuset(&mask)); + if (!*argv) { + /* Either it was just "-p ", + * or it was "-p " and we came here + * for the second time (see goto below) */ return EXIT_SUCCESS; + } + *argv = NULL; + current_new += 8; /* "new" */ } - if (sched_setaffinity(pid, sizeof(new_mask), &new_mask)) - bb_perror_msg_and_die("failed to %cet pid %d's affinity", 's', pid); - if (opt & OPT_p) { - state += 8; - ++argv; - goto print_aff; + { /* Affinity was specified, translate it into cpu_set_t */ + unsigned i; + /* Do not allow zero mask: */ + unsigned long long m = xstrtoull_range(aff, 0, 1, ULLONG_MAX); + enum { CNT_BIT = CPU_SETSIZE < sizeof(m)*8 ? CPU_SETSIZE : sizeof(m)*8 }; + + CPU_ZERO(&mask); + for (i = 0; i < CNT_BIT; i++) { + unsigned long long bit = (1ULL << i); + if (bit & m) + CPU_SET(i, &mask); + } } - ++argv; - BB_EXECVP(*argv, argv); - bb_perror_msg_and_die("%s", *argv); + + /* Set pid's or our own (pid==0) affinity */ + if (sched_setaffinity(pid, sizeof(mask), &mask)) + bb_perror_msg_and_die("can't %cet pid %d's affinity", 's', pid); + + if (!argv[0]) /* "-p [...ignored...]" */ + goto print_aff; /* print new affinity and exit */ + + BB_EXECVP_or_die(argv); } -#undef OPT_p -#undef TASKSET_PRINTF_MASK -#undef from_cpuset