summaryrefslogtreecommitdiff
path: root/posix
diff options
context:
space:
mode:
Diffstat (limited to 'posix')
-rw-r--r--posix/sched_cpucount.c40
1 files changed, 14 insertions, 26 deletions
diff --git a/posix/sched_cpucount.c b/posix/sched_cpucount.c
index b0ca4ea7bc..63d0e99590 100644
--- a/posix/sched_cpucount.c
+++ b/posix/sched_cpucount.c
@@ -17,36 +17,24 @@
#include <sched.h>
+/* Counting bits set, Brian Kernighan's way.
+ Using a open-coded routine is slight better for architectures that
+ do not have a popcount instruction (compiler might emit a library
+ call). */
+static inline int
+countbits (__cpu_mask v)
+{
+ int s = 0;
+ for (; v != 0; s++)
+ v &= v - 1;
+ return s;
+}
int
__sched_cpucount (size_t setsize, const cpu_set_t *setp)
{
int s = 0;
- const __cpu_mask *p = setp->__bits;
- const __cpu_mask *end = &setp->__bits[setsize / sizeof (__cpu_mask)];
-
- while (p < end)
- {
- __cpu_mask l = *p++;
-
-#ifdef POPCNT
- s += POPCNT (l);
-#else
- if (l == 0)
- continue;
-
- _Static_assert (sizeof (l) == sizeof (unsigned int)
- || sizeof (l) == sizeof (unsigned long)
- || sizeof (l) == sizeof (unsigned long long),
- "sizeof (__cpu_mask");
- if (sizeof (__cpu_mask) == sizeof (unsigned int))
- s += __builtin_popcount (l);
- else if (sizeof (__cpu_mask) == sizeof (unsigned long))
- s += __builtin_popcountl (l);
- else
- s += __builtin_popcountll (l);
-#endif
- }
-
+ for (int i = 0; i < setsize / sizeof (__cpu_mask); i++)
+ s += countbits (setp->__bits[i]);
return s;
}