summaryrefslogtreecommitdiffstats
path: root/lib/cpuset.c
diff options
context:
space:
mode:
authorKarel Zak2010-05-28 11:08:39 +0200
committerKarel Zak2010-06-01 11:11:26 +0200
commitbae91ecf07384f09fcf94903b7c3d7e565f4f66d (patch)
tree1395d6445a0e6871202c6042aba58dedf09fa850 /lib/cpuset.c
parentlscpu: improve --sysroot code (diff)
downloadkernel-qcow2-util-linux-bae91ecf07384f09fcf94903b7c3d7e565f4f66d.tar.gz
kernel-qcow2-util-linux-bae91ecf07384f09fcf94903b7c3d7e565f4f66d.tar.xz
kernel-qcow2-util-linux-bae91ecf07384f09fcf94903b7c3d7e565f4f66d.zip
taskset: move NR_CPUS determination to lib/cpuset.c
Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'lib/cpuset.c')
-rw-r--r--lib/cpuset.c41
1 files changed, 40 insertions, 1 deletions
diff --git a/lib/cpuset.c b/lib/cpuset.c
index d6cbf5d30..27b234988 100644
--- a/lib/cpuset.c
+++ b/lib/cpuset.c
@@ -18,6 +18,7 @@
#include <errno.h>
#include <string.h>
#include <ctype.h>
+#include <sys/syscall.h>
#include "cpuset.h"
@@ -54,6 +55,38 @@ static const char *nexttoken(const char *q, int sep)
}
/*
+ * 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
*/
cpu_set_t *cpuset_alloc(int ncpus, size_t *setsize, size_t *nbits)
@@ -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)