lib: add fallback for libc (uClibc) without CPU_ALLOC
Signed-off-by: Karel Zak <kzak@redhat.com>
This commit is contained in:
parent
ff5a6d2067
commit
ee32c514b5
11
configure.ac
11
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], [
|
||||
|
|
|
@ -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))
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
33
lib/cpuset.c
33
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").
|
||||
|
|
Loading…
Reference in New Issue