]> err.no Git - util-linux/commitdiff
lib: add fallback for libc (uClibc) without CPU_ALLOC
authorKarel Zak <kzak@redhat.com>
Thu, 27 May 2010 11:32:12 +0000 (13:32 +0200)
committerKarel Zak <kzak@redhat.com>
Tue, 1 Jun 2010 09:09:23 +0000 (11:09 +0200)
Signed-off-by: Karel Zak <kzak@redhat.com>
configure.ac
include/cpuset.h
lib/Makefile.am
lib/cpuset.c

index 7fe91a1a6c4263a3e2e72589f688750431bee876..fae8db145d175cfb9798e80b969328b2af33a7d0 100644 (file)
@@ -682,6 +682,17 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
 ])
 
 
+AC_CHECK_TYPES([cpu_set_t], [have_cpu_set_t=yes], [], [[
+#include <sched.h>
+]])
+
+AM_CONDITIONAL(HAVE_CPU_SET_T, [test "x$have_cpu_set_t" = xyes])
+
+AC_CHECK_DECLS([CPU_ALLOC], [], [], [[
+#include <sched.h>
+]])
+
+
 dnl UTIL_SET_ARCH(ARCHNAME, PATTERN)
 dnl ---------------------------------
 AC_DEFUN([UTIL_SET_ARCH], [
index bc7961cad770dad010560e564e0a658ff4013abc..197476ed96057d0c477662090309767060bd0a32 100644 (file)
@@ -3,6 +3,51 @@
 
 #include <sched.h>
 
+/*
+ * Fallback for old or obscure libcs without dynamically allocated cpusets
+ *
+ * The following macros are based on code from glibc.
+ *
+ * The GNU C Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ */
+#if !HAVE_DECL_CPU_ALLOC
+
+# define CPU_ZERO_S(setsize, cpusetp) \
+  do {                                                                       \
+    size_t __i;                                                                      \
+    size_t __imax = (setsize) / sizeof (__cpu_mask);                         \
+    __cpu_mask *__bits = (cpusetp)->__bits;                                  \
+    for (__i = 0; __i < __imax; ++__i)                                       \
+      __bits[__i] = 0;                                                       \
+  } while (0)
+
+# define CPU_SET_S(cpu, setsize, cpusetp) \
+   ({ size_t __cpu = (cpu);                                                  \
+      __cpu < 8 * (setsize)                                                  \
+      ? (((__cpu_mask *) ((cpusetp)->__bits))[__CPUELT (__cpu)]                      \
+        |= __CPUMASK (__cpu))                                                \
+      : 0; })
+
+# define CPU_ISSET_S(cpu, setsize, cpusetp) \
+   ({ size_t __cpu = (cpu);                                                  \
+      __cpu < 8 * (setsize)                                                  \
+      ? ((((__cpu_mask *) ((cpusetp)->__bits))[__CPUELT (__cpu)]             \
+         & __CPUMASK (__cpu))) != 0                                          \
+      : 0; })
+
+extern int __cpuset_count_s(size_t setsize, const cpu_set_t *set);
+# define CPU_COUNT_S(setsize, cpusetp) __cpuset_count_s(setsize, cpusetp)
+
+# define CPU_ALLOC_SIZE(count) \
+         ((((count) + __NCPUBITS - 1) / __NCPUBITS) * sizeof (__cpu_mask))
+# define CPU_ALLOC(count)      (malloc(CPU_ALLOC_SIZE(count)))
+# define CPU_FREE(cpuset)      (free(cpuset))
+
+#endif /* !HAVE_DECL_CPU_ALLOC */
+
 
 #define cpuset_nbits(setsize)  (8 * (setsize))
 
index 93b79a5a75665dbd02b24da65e5977050fb38982..c66deef0b84dc22e12ecede9cf027423e449fd24 100644 (file)
@@ -3,7 +3,10 @@ include $(top_srcdir)/config/include-Makefile.am
 AM_CPPFLAGS += -DTEST_PROGRAM
 
 noinst_PROGRAMS = test_blkdev test_ismounted test_wholedisk test_mangle \
-                 test_strtosize test_cpuset
+                 test_strtosize
+if HAVE_CPU_SET_T
+noinst_PROGRAMS += test_cpuset
+endif
 
 test_blkdev_SOURCES = blkdev.c
 test_ismounted_SOURCES = ismounted.c
index 189c23ea3181fc710d664dea4d5fe8bdf281addf..d6cbf5d3042495b3fb86dca12f8d3c26851056d3 100644 (file)
@@ -74,6 +74,39 @@ void cpuset_free(cpu_set_t *set)
        CPU_FREE(set);
 }
 
+#if !HAVE_DECL_CPU_ALLOC
+/* Please, use CPU_COUNT_S() macro. This is fallback */
+int __cpuset_count_s(size_t setsize, const cpu_set_t *set)
+{
+       int s = 0;
+       const __cpu_mask *p = set->__bits;
+       const __cpu_mask *end = &set->__bits[setsize / sizeof (__cpu_mask)];
+
+       while (p < end) {
+               __cpu_mask l = *p++;
+
+               if (l == 0)
+                       continue;
+# if LONG_BIT > 32
+               l = (l & 0x5555555555555555ul) + ((l >> 1) & 0x5555555555555555ul);
+               l = (l & 0x3333333333333333ul) + ((l >> 2) & 0x3333333333333333ul);
+               l = (l & 0x0f0f0f0f0f0f0f0ful) + ((l >> 4) & 0x0f0f0f0f0f0f0f0ful);
+               l = (l & 0x00ff00ff00ff00fful) + ((l >> 8) & 0x00ff00ff00ff00fful);
+               l = (l & 0x0000ffff0000fffful) + ((l >> 16) & 0x0000ffff0000fffful);
+               l = (l & 0x00000000fffffffful) + ((l >> 32) & 0x00000000fffffffful);
+# else
+               l = (l & 0x55555555ul) + ((l >> 1) & 0x55555555ul);
+               l = (l & 0x33333333ul) + ((l >> 2) & 0x33333333ul);
+               l = (l & 0x0f0f0f0ful) + ((l >> 4) & 0x0f0f0f0ful);
+               l = (l & 0x00ff00fful) + ((l >> 8) & 0x00ff00fful);
+               l = (l & 0x0000fffful) + ((l >> 16) & 0x0000fffful);
+# endif
+               s += l;
+       }
+       return s;
+}
+#endif
+
 /*
  * Returns human readable representation of the cpuset. The output format is
  * a list of CPUs with ranges (for example, "0,1,3-9").