diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2017-07-01 07:29:19 -0700 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2017-07-01 07:29:32 -0700 |
commit | 8dc6133eff1c09382bc8f6f98c49fb807900eecd (patch) | |
tree | 3ca0c6660b09b6fdd51e2a45af626d8bd49019ee /posix/sched_cpucount.c | |
parent | Fix typo in glibc.tune.cpu name (diff) | |
download | glibc-8dc6133eff1c09382bc8f6f98c49fb807900eecd.tar.gz glibc-8dc6133eff1c09382bc8f6f98c49fb807900eecd.tar.bz2 glibc-8dc6133eff1c09382bc8f6f98c49fb807900eecd.zip |
Use __builtin_popcount in __sched_cpucount [BZ #21696]
posix/sched_cpucount.c assumes that size of __cpu_mask == size of long,
which is incorrect for x32. This patch uses __builtin_popcount, which
is availabe in GCC 4.9, in posix/sched_cpucount.c.
Tested on i686, x86-64 and x32 with multi-arch disabled.
[BZ #21696]
* posix/sched_cpucount.c: Don't include <limits.h>.
(__sched_cpucount): Use __builtin_popcount.
Diffstat (limited to 'posix/sched_cpucount.c')
-rw-r--r-- | posix/sched_cpucount.c | 27 |
1 files changed, 10 insertions, 17 deletions
diff --git a/posix/sched_cpucount.c b/posix/sched_cpucount.c index eaddf61b1b..ab1ff49383 100644 --- a/posix/sched_cpucount.c +++ b/posix/sched_cpucount.c @@ -15,7 +15,6 @@ License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ -#include <limits.h> #include <sched.h> @@ -36,22 +35,16 @@ __sched_cpucount (size_t setsize, const cpu_set_t *setp) 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; + _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 } |