From bae91ecf07384f09fcf94903b7c3d7e565f4f66d Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Fri, 28 May 2010 11:08:39 +0200 Subject: [PATCH] taskset: move NR_CPUS determination to lib/cpuset.c Signed-off-by: Karel Zak --- include/cpuset.h | 2 ++ lib/cpuset.c | 41 ++++++++++++++++++++++++++++++++++++++++- schedutils/taskset.c | 39 +++------------------------------------ 3 files changed, 45 insertions(+), 37 deletions(-) diff --git a/include/cpuset.h b/include/cpuset.h index 197476ed..5f6b5bbf 100644 --- a/include/cpuset.h +++ b/include/cpuset.h @@ -51,6 +51,8 @@ extern int __cpuset_count_s(size_t setsize, const cpu_set_t *set); #define cpuset_nbits(setsize) (8 * (setsize)) +extern int get_max_number_of_cpus(void); + extern cpu_set_t *cpuset_alloc(int ncpus, size_t *setsize, size_t *nbits); extern void cpuset_free(cpu_set_t *set); diff --git a/lib/cpuset.c b/lib/cpuset.c index d6cbf5d3..27b23498 100644 --- a/lib/cpuset.c +++ b/lib/cpuset.c @@ -18,6 +18,7 @@ #include #include #include +#include #include "cpuset.h" @@ -53,6 +54,38 @@ static const char *nexttoken(const char *q, int sep) return q; } +/* + * Number of bits in a CPU bitmask on current system + */ +int get_max_number_of_cpus(void) +{ + int n, cpus = 2048; + size_t setsize; + cpu_set_t *set = cpuset_alloc(cpus, &setsize, NULL); + + if (!set) + return -1; /* error */ + + for (;;) { + CPU_ZERO_S(setsize, set); + + /* the library version does not return size of cpumask_t */ + n = syscall(SYS_sched_getaffinity, 0, setsize, set); + + if (n < 0 && errno == EINVAL && cpus < 1024 * 1024) { + cpuset_free(set); + cpus *= 2; + set = cpuset_alloc(cpus, &setsize, NULL); + if (!set) + return -1; /* error */ + continue; + } + cpuset_free(set); + return n * 8; + } + return -1; +} + /* * Allocates a new set for ncpus and returns size in bytes and size in bits */ @@ -200,7 +233,13 @@ int cpumask_parse(const char *str, cpu_set_t *set, size_t setsize) CPU_ZERO_S(setsize, set); while (ptr >= str) { - char val = char_to_val(*ptr); + char val; + + /* cpu masks in /sys uses comma as a separator */ + if (*ptr == ',') + ptr--; + + val = char_to_val(*ptr); if (val == (char) -1) return -1; if (val & 1) diff --git a/schedutils/taskset.c b/schedutils/taskset.c index 66387c82..2f1bc745 100644 --- a/schedutils/taskset.c +++ b/schedutils/taskset.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include "cpuset.h" @@ -64,40 +63,6 @@ static void __attribute__((__noreturn__)) usage(FILE *out) exit(out == stderr ? EXIT_FAILURE : EXIT_SUCCESS); } -/* - * Number of bits in a CPU bitmask on current system - */ -static int max_number_of_cpus(void) -{ - int n, cpus = 2048; - size_t setsize; - cpu_set_t *set = cpuset_alloc(cpus, &setsize, NULL); - - if (!set) - goto err; - - for (;;) { - CPU_ZERO_S(setsize, set); - - /* the library version does not return size of cpumask_t */ - n = syscall(SYS_sched_getaffinity, 0, setsize, set); - - if (n < 0 && errno == EINVAL && cpus < 1024 * 1024) { - cpuset_free(set); - cpus *= 2; - set = cpuset_alloc(cpus, &setsize, NULL); - if (!set) - goto err; - continue; - } - cpuset_free(set); - return n * 8; - } -err: - errx(EXIT_FAILURE, _("cannot determine NR_CPUS; aborting")); - return 0; -} - int main(int argc, char *argv[]) { cpu_set_t *new_set, *cur_set; @@ -143,7 +108,9 @@ int main(int argc, char *argv[]) || (pid && (argc - optind < 1 || argc - optind > 2))) usage(stderr); - ncpus = max_number_of_cpus(); + ncpus = get_max_number_of_cpus(); + if (ncpus <= 0) + errx(EXIT_FAILURE, _("cannot determine NR_CPUS; aborting")); /* * cur_set is always used for the sched_getaffinity call -- 2.39.5