ia64/xen-unstable
changeset 5197:7c8e84ee36b2
bitkeeper revision 1.1588 (42999d00gxHg_hThncByjrGk7labNA)
Tidy up and fix the bit-scanning operations. In particular,
find_{first,next}_[zero_]bit(addr, max) may return any value >= max
if no suitable bit is found. This is now also the case for first_cpu()
and next_cpu() (unlike Linux!). I don't believe that any callers
care -- they always check for >= NR_CPUS, and I fixed any_online_cpu()
separately. This reduces code size and will improve performance.
Signed-off-by: Keir Fraser <keir@xensource.com>
Tidy up and fix the bit-scanning operations. In particular,
find_{first,next}_[zero_]bit(addr, max) may return any value >= max
if no suitable bit is found. This is now also the case for first_cpu()
and next_cpu() (unlike Linux!). I don't believe that any callers
care -- they always check for >= NR_CPUS, and I fixed any_online_cpu()
separately. This reduces code size and will improve performance.
Signed-off-by: Keir Fraser <keir@xensource.com>
author | kaf24@firebug.cl.cam.ac.uk |
---|---|
date | Sun May 29 10:44:16 2005 +0000 (2005-05-29) |
parents | df3e1d0fd811 |
children | 4155e76f7528 |
files | xen/include/asm-x86/bitops.h xen/include/xen/cpumask.h |
line diff
1.1 --- a/xen/include/asm-x86/bitops.h Sun May 29 01:03:56 2005 +0000 1.2 +++ b/xen/include/asm-x86/bitops.h Sun May 29 10:44:16 2005 +0000 1.3 @@ -274,7 +274,8 @@ static inline long find_first_zero_bit( 1.4 "shl $3,%%"__OP"di\n\t" 1.5 "add %%"__OP"di,%%"__OP"dx" 1.6 :"=d" (res), "=&c" (d0), "=&D" (d1), "=&a" (d2) 1.7 - :"1" ((size + 31) >> 5), "2" (addr), "b" (addr) : "memory"); 1.8 + :"1" ((size + BITS_PER_LONG - 1) / BITS_PER_LONG), 1.9 + "2" (addr), "b" (addr) : "memory"); 1.10 return res; 1.11 } 1.12 1.13 @@ -310,7 +311,8 @@ static inline long find_first_bit( 1.14 "shl $3,%%"__OP"di\n\t" 1.15 "add %%"__OP"di,%%"__OP"ax" 1.16 :"=a" (res), "=&c" (d0), "=&D" (d1) 1.17 - :"1" ((size + 31) >> 5), "2" (addr), "b" (addr) : "memory"); 1.18 + :"1" ((size + BITS_PER_LONG - 1) / BITS_PER_LONG), 1.19 + "2" (addr), "b" (addr) : "memory"); 1.20 return res; 1.21 } 1.22 1.23 @@ -322,47 +324,38 @@ static inline long find_first_bit( 1.24 */ 1.25 long find_next_bit(const unsigned long *addr, int size, int offset); 1.26 1.27 -/* return index of first bet set in val or max when no bit is set */ 1.28 -static inline unsigned long __scanbit(unsigned long val, unsigned long max) 1.29 +/* return index of first bet set in val or BITS_PER_LONG when no bit is set */ 1.30 +static inline unsigned long __scanbit(unsigned long val) 1.31 { 1.32 - asm("bsf %1,%0 ; cmovz %2,%0" : "=&r" (val) : "r" (val), "r" (max)); 1.33 + asm("bsf %1,%0" : "=&r" (val) : "r" (val), "0" (BITS_PER_LONG)); 1.34 return val; 1.35 } 1.36 1.37 #define find_first_bit(addr,size) \ 1.38 ((__builtin_constant_p(size) && (size) <= BITS_PER_LONG ? \ 1.39 - (__scanbit(*(unsigned long *)addr,(size))) : \ 1.40 + (__scanbit(*(unsigned long *)addr)) : \ 1.41 find_first_bit(addr,size))) 1.42 1.43 #define find_next_bit(addr,size,off) \ 1.44 -((__builtin_constant_p(size) && (size) <= BITS_PER_LONG ? \ 1.45 - ((off) + (__scanbit((*(unsigned long *)addr) >> (off),(size)-(off)))) : \ 1.46 +((__builtin_constant_p(size) && (size) <= BITS_PER_LONG ? \ 1.47 + ((off) + (__scanbit((*(unsigned long *)addr) >> (off)))) : \ 1.48 find_next_bit(addr,size,off))) 1.49 1.50 #define find_first_zero_bit(addr,size) \ 1.51 ((__builtin_constant_p(size) && (size) <= BITS_PER_LONG ? \ 1.52 - (__scanbit(~*(unsigned long *)addr,(size))) : \ 1.53 + (__scanbit(~*(unsigned long *)addr)) : \ 1.54 find_first_zero_bit(addr,size))) 1.55 - 1.56 + 1.57 #define find_next_zero_bit(addr,size,off) \ 1.58 -((__builtin_constant_p(size) && (size) <= BITS_PER_LONG ? \ 1.59 - ((off)+(__scanbit(~(((*(unsigned long *)addr)) >> (off)),(size)-(off)))) : \ 1.60 +((__builtin_constant_p(size) && (size) <= BITS_PER_LONG ? \ 1.61 + ((off)+(__scanbit(~(((*(unsigned long *)addr)) >> (off))))) : \ 1.62 find_next_zero_bit(addr,size,off))) 1.63 1.64 1.65 /* 1.66 - * These are the preferred 'find first' functions in Xen. 1.67 - * Both return the appropriate bit index, with the l.s.b. having index 0. 1.68 - * If an appropriate bit is not found then the result is undefined. 1.69 + * Return index of first non-zero bit in @word (counting l.s.b. as 0). 1.70 + * If no bits are set (@word == 0) then the result is undefined. 1.71 */ 1.72 -static __inline__ unsigned long find_first_clear_bit(unsigned long word) 1.73 -{ 1.74 - __asm__("bsf %1,%0" 1.75 - :"=r" (word) 1.76 - :"r" (~word)); 1.77 - return word; 1.78 -} 1.79 - 1.80 static __inline__ unsigned long find_first_set_bit(unsigned long word) 1.81 { 1.82 __asm__("bsf %1,%0"
2.1 --- a/xen/include/xen/cpumask.h Sun May 29 01:03:56 2005 +0000 2.2 +++ b/xen/include/xen/cpumask.h Sun May 29 10:44:16 2005 +0000 2.3 @@ -36,8 +36,8 @@ 2.4 * void cpus_shift_right(dst, src, n) Shift right 2.5 * void cpus_shift_left(dst, src, n) Shift left 2.6 * 2.7 - * int first_cpu(mask) Number lowest set bit, or NR_CPUS 2.8 - * int next_cpu(cpu, mask) Next cpu past 'cpu', or NR_CPUS 2.9 + * int first_cpu(mask) Number lowest set bit, or >= NR_CPUS 2.10 + * int next_cpu(cpu, mask) Next cpu past 'cpu', or >= NR_CPUS 2.11 * 2.12 * cpumask_t cpumask_of_cpu(cpu) Return cpumask with bit 'cpu' set 2.13 * CPU_MASK_ALL Initializer - all bits set 2.14 @@ -57,7 +57,7 @@ 2.15 * int cpu_possible(cpu) Is some cpu possible? 2.16 * int cpu_present(cpu) Is some cpu present (can schedule)? 2.17 * 2.18 - * int any_online_cpu(mask) First online cpu in mask 2.19 + * int any_online_cpu(mask) First online cpu in mask, or NR_CPUS 2.20 * 2.21 * for_each_cpu(cpu) for-loop cpu over cpu_possible_map 2.22 * for_each_online_cpu(cpu) for-loop cpu over cpu_online_map 2.23 @@ -207,13 +207,13 @@ static inline void __cpus_shift_left(cpu 2.24 #define first_cpu(src) __first_cpu(&(src), NR_CPUS) 2.25 static inline int __first_cpu(const cpumask_t *srcp, int nbits) 2.26 { 2.27 - return min_t(int, nbits, find_first_bit(srcp->bits, nbits)); 2.28 + return find_first_bit(srcp->bits, nbits); 2.29 } 2.30 2.31 #define next_cpu(n, src) __next_cpu((n), &(src), NR_CPUS) 2.32 static inline int __next_cpu(int n, const cpumask_t *srcp, int nbits) 2.33 { 2.34 - return min_t(int, nbits, find_next_bit(srcp->bits, nbits, n+1)); 2.35 + return find_next_bit(srcp->bits, nbits, n+1); 2.36 } 2.37 2.38 #define cpumask_of_cpu(cpu) \ 2.39 @@ -368,7 +368,7 @@ extern cpumask_t cpu_present_map; 2.40 for_each_cpu_mask(cpu, (mask)) \ 2.41 if (cpu_online(cpu)) \ 2.42 break; \ 2.43 - cpu; \ 2.44 + min_t(int, NR_CPUS, cpu); \ 2.45 }) 2.46 2.47 #define for_each_cpu(cpu) for_each_cpu_mask((cpu), cpu_possible_map)