lib: add fallback for libc (uClibc) without CPU_ALLOC

Signed-off-by: Karel Zak <kzak@redhat.com>
This commit is contained in:
Karel Zak 2010-05-27 13:32:12 +02:00
parent ff5a6d2067
commit ee32c514b5
4 changed files with 93 additions and 1 deletions

View 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], [

View 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))

View 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

View 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").