aboutsummaryrefslogtreecommitdiff
path: root/toys/other/taskset.c
diff options
context:
space:
mode:
Diffstat (limited to 'toys/other/taskset.c')
-rw-r--r--toys/other/taskset.c58
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);
}