From: Karel Zak Date: Thu, 27 May 2010 11:32:12 +0000 (+0200) Subject: lib: add fallback for libc (uClibc) without CPU_ALLOC X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ee32c514b5d61765a3ca6305d247b91fc8d15d0e;p=util-linux lib: add fallback for libc (uClibc) without CPU_ALLOC Signed-off-by: Karel Zak --- diff --git a/configure.ac b/configure.ac index 7fe91a1a..fae8db14 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 +]]) + +AM_CONDITIONAL(HAVE_CPU_SET_T, [test "x$have_cpu_set_t" = xyes]) + +AC_CHECK_DECLS([CPU_ALLOC], [], [], [[ +#include +]]) + + dnl UTIL_SET_ARCH(ARCHNAME, PATTERN) dnl --------------------------------- AC_DEFUN([UTIL_SET_ARCH], [ diff --git a/include/cpuset.h b/include/cpuset.h index bc7961ca..197476ed 100644 --- a/include/cpuset.h +++ b/include/cpuset.h @@ -3,6 +3,51 @@ #include +/* + * 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 93b79a5a..c66deef0 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 189c23ea..d6cbf5d3 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").