summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--configure.ac11
-rw-r--r--include/cpuset.h45
-rw-r--r--lib/Makefile.am5
-rw-r--r--lib/cpuset.c33
4 files changed, 93 insertions, 1 deletions
diff --git a/configure.ac b/configure.ac
index 7fe91a1a6..fae8db145 100644
--- a/configure.ac
+++ b/configure.ac
@@ -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], [
diff --git a/include/cpuset.h b/include/cpuset.h
index bc7961cad..197476ed9 100644
--- a/include/cpuset.h
+++ b/include/cpuset.h
@@ -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))
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 93b79a5a7..c66deef0b 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -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
diff --git a/lib/cpuset.c b/lib/cpuset.c
index 189c23ea3..d6cbf5d30 100644
--- a/lib/cpuset.c
+++ b/lib/cpuset.c
@@ -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").