diff options
Diffstat (limited to 'toys/other/taskset.c')
-rw-r--r-- | toys/other/taskset.c | 58 |
1 files changed, 32 insertions, 26 deletions
diff --git a/toys/other/taskset.c b/toys/other/taskset.c index 2a9ae029..a3d0ffb3 100644 --- a/toys/other/taskset.c +++ b/toys/other/taskset.c @@ -2,7 +2,7 @@ * * Copyright 2012 Elie De Brauwer <eliedebrauwer@gmail.com> -USE_TASKSET(NEWTOY(taskset, "<1^pa", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_STAYROOT)) +USE_TASKSET(NEWTOY(taskset, "<1^pa", TOYFLAG_USR|TOYFLAG_BIN)) USE_NPROC(NEWTOY(nproc, "(all)", TOYFLAG_USR|TOYFLAG_BIN)) config NPROC @@ -34,36 +34,31 @@ config TASKSET #define FOR_taskset #include "toys.h" +// mask is array of long which makes layout a bit weird on big endian systems #define sched_setaffinity(pid, size, cpuset) \ syscall(__NR_sched_setaffinity, (pid_t)pid, (size_t)size, (void *)cpuset) #define sched_getaffinity(pid, size, cpuset) \ syscall(__NR_sched_getaffinity, (pid_t)pid, (size_t)size, (void *)cpuset) -// mask is an array of long, which makes the layout a bit weird on big -// endian systems but as long as it's consistent... - static void do_taskset(pid_t pid, int quiet) { unsigned long *mask = (unsigned long *)toybuf; - char *s = *toys.optargs, *failed = "failed to %s %d's affinity"; + char *s, *failed = "failed to %s pid %d's affinity"; int i, j, k; + // loop through twice to display before/after affinity masks for (i=0; ; i++) { if (!quiet) { - int j = sizeof(toybuf), flag = 0; - if (-1 == sched_getaffinity(pid, sizeof(toybuf), (void *)mask)) perror_exit(failed, "get", pid); printf("pid %d's %s affinity mask: ", pid, i ? "new" : "current"); - while (j--) { - int x = 255 & (mask[j/sizeof(long)] >> (8*(j&(sizeof(long)-1)))); - - if (flag) printf("%02x", x); - else if (x) { - flag++; - printf("%x", x); + for (j = sizeof(toybuf)/sizeof(long), k = 0; --j>=0;) { + if (k) printf("%0*lx", (int)(2*sizeof(long)), mask[j]); + else if (mask[j]) { + k++; + printf("%lx", mask[j]); } } putchar('\n'); @@ -71,6 +66,7 @@ static void do_taskset(pid_t pid, int quiet) if (i || toys.optc < 2) return; + // Convert hex strong to mask[] bits memset(toybuf, 0, sizeof(toybuf)); k = strlen(s = *toys.optargs); s += k; @@ -89,26 +85,25 @@ static void do_taskset(pid_t pid, int quiet) static int task_callback(struct dirtree *new) { - if (!new->parent) return DIRTREE_RECURSE; - if (isdigit(*new->name)) do_taskset(atoi(new->name), 0); + if (!new->parent) return DIRTREE_RECURSE|DIRTREE_SHUTUP|DIRTREE_PROC; + do_taskset(atoi(new->name), 0); return 0; } void taskset_main(void) { - if (!(toys.optflags & FLAG_p)) { + if (!FLAG(p)) { if (toys.optc < 2) error_exit("Needs 2 args"); do_taskset(getpid(), 1); xexec(toys.optargs+1); } else { - char *c; + char *c, buf[33]; pid_t pid = strtol(toys.optargs[toys.optc-1], &c, 10); - if (*c) error_exit("Not int %s", toys.optargs[1]); + if (*c) error_exit("Not int %s", toys.optargs[toys.optc-1]); - if (toys.optflags & FLAG_a) { - char buf[33]; + if (FLAG(a)) { sprintf(buf, "/proc/%ld/task/", (long)pid); dirtree_read(buf, task_callback); } else do_taskset(pid, 0); @@ -118,15 +113,26 @@ void taskset_main(void) void nproc_main(void) { unsigned i, j, nproc = 0; + DIR *dd; // This can only detect 32768 processors. Call getaffinity and count bits. - if (!toys.optflags && -1!=sched_getaffinity(getpid(), 4096, toybuf)) { + if (!toys.optflags && -1!=sched_getaffinity(getpid(), 4096, toybuf)) for (i = 0; i<4096; i++) if (toybuf[i]) for (j=0; j<8; j++) if (toybuf[i]&(1<<j)) nproc++; - } - // If getaffinity failed or --all, count cpu entries in proc - if (!nproc) nproc = sysconf(_SC_NPROCESSORS_CONF); + // If getaffinity failed or --all, count cpu entries in sysfs + // (/proc/cpuinfo filters out hot-unplugged CPUs, sysfs doesn't) + if (!nproc && (dd = opendir("/sys/devices/system/cpu"))) { + struct dirent *de; + char *ss; + + while ((de = readdir(dd))) { + if (smemcmp(de->d_name, "cpu", 3)) continue; + for (ss = de->d_name+3; isdigit(*ss); ss++); + if (!*ss) nproc++; + } + closedir(dd); + } - xprintf("%u\n", nproc); + xprintf("%u\n", nproc ? : 1); } |