From 3f6685ef3cc0932453a431664b839e25cbe895eb Mon Sep 17 00:00:00 2001 From: Robert Elliott Date: Mon, 13 Nov 2017 20:22:09 -0600 Subject: [PATCH] os-windows: fix cpumask operations Fix cpumask manipulation on (64-bit) Windows systems. cpus_allowed=nn values greater than 32 does not work, due to * the compiler not promoting expressions like "1 << cpu" to 64 bits * the clear function clearing the wrong bit (using "cpu - 1"), * the clear function using XOR to clear (which only works if the bit was previously set) * the check function returning a 64-bit value through a 32-bit return value Example problems (from extra debug prints): * setting CPU 32 really sets bit 0 (CPU 0) Set mask of 0000000000000000 to add 0000000000000001 (32) * setting CPU 63 really sets bit 31 (CPU 31) Set mask of 0000000000000000 to add 0000000080000000 (63) * clearing CPU 0 really clears bit 63 (CPU 63) Clear mask of 0000000055555555 to remove 8000000000000000 (0) * clearing CPU 2 really clears bit 2 (CPU 2) Clear mask of 0000000055555555 to remove 0000000000000002 (2) * checking claims CPU 32 is not in a mask of CPUs {32,34,36,38} for 0000005500000000 check if bit 32 is set ==> FALSE Tested with x86_64-w64-mingw32-gcc 6.4.0 from cygwin on a system with 64 CPU cores (all fitting in one Windows processor group). Signed-off-by: Jens Axboe --- os/os-windows.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/os/os-windows.h b/os/os-windows.h index 520da19a..1b87771d 100644 --- a/os/os-windows.h +++ b/os/os-windows.h @@ -209,17 +209,17 @@ static inline int fio_getaffinity(int pid, os_cpu_mask_t *mask) static inline void fio_cpu_clear(os_cpu_mask_t *mask, int cpu) { - *mask ^= 1 << (cpu-1); + *mask &= ~(1ULL << cpu); } static inline void fio_cpu_set(os_cpu_mask_t *mask, int cpu) { - *mask |= 1 << cpu; + *mask |= 1ULL << cpu; } static inline int fio_cpu_isset(os_cpu_mask_t *mask, int cpu) { - return (*mask & (1U << cpu)); + return (*mask & (1ULL << cpu)) > 0; } static inline int fio_cpu_count(os_cpu_mask_t *mask) -- 2.25.1