[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] Tidy up and fix the bit-scanning operations. In particular,
ChangeSet 1.1588, 2005/05/29 11:44:16+01:00, kaf24@xxxxxxxxxxxxxxxxxxxx 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@xxxxxxxxxxxxx> asm-x86/bitops.h | 39 ++++++++++++++++----------------------- xen/cpumask.h | 12 ++++++------ 2 files changed, 22 insertions(+), 29 deletions(-) diff -Nru a/xen/include/asm-x86/bitops.h b/xen/include/asm-x86/bitops.h --- a/xen/include/asm-x86/bitops.h 2005-05-29 07:03:51 -04:00 +++ b/xen/include/asm-x86/bitops.h 2005-05-29 07:03:51 -04:00 @@ -274,7 +274,8 @@ "shl $3,%%"__OP"di\n\t" "add %%"__OP"di,%%"__OP"dx" :"=d" (res), "=&c" (d0), "=&D" (d1), "=&a" (d2) - :"1" ((size + 31) >> 5), "2" (addr), "b" (addr) : "memory"); + :"1" ((size + BITS_PER_LONG - 1) / BITS_PER_LONG), + "2" (addr), "b" (addr) : "memory"); return res; } @@ -310,7 +311,8 @@ "shl $3,%%"__OP"di\n\t" "add %%"__OP"di,%%"__OP"ax" :"=a" (res), "=&c" (d0), "=&D" (d1) - :"1" ((size + 31) >> 5), "2" (addr), "b" (addr) : "memory"); + :"1" ((size + BITS_PER_LONG - 1) / BITS_PER_LONG), + "2" (addr), "b" (addr) : "memory"); return res; } @@ -322,47 +324,38 @@ */ long find_next_bit(const unsigned long *addr, int size, int offset); -/* return index of first bet set in val or max when no bit is set */ -static inline unsigned long __scanbit(unsigned long val, unsigned long max) +/* return index of first bet set in val or BITS_PER_LONG when no bit is set */ +static inline unsigned long __scanbit(unsigned long val) { - asm("bsf %1,%0 ; cmovz %2,%0" : "=&r" (val) : "r" (val), "r" (max)); + asm("bsf %1,%0" : "=&r" (val) : "r" (val), "0" (BITS_PER_LONG)); return val; } #define find_first_bit(addr,size) \ ((__builtin_constant_p(size) && (size) <= BITS_PER_LONG ? \ - (__scanbit(*(unsigned long *)addr,(size))) : \ + (__scanbit(*(unsigned long *)addr)) : \ find_first_bit(addr,size))) #define find_next_bit(addr,size,off) \ -((__builtin_constant_p(size) && (size) <= BITS_PER_LONG ? \ - ((off) + (__scanbit((*(unsigned long *)addr) >> (off),(size)-(off)))) : \ +((__builtin_constant_p(size) && (size) <= BITS_PER_LONG ? \ + ((off) + (__scanbit((*(unsigned long *)addr) >> (off)))) : \ find_next_bit(addr,size,off))) #define find_first_zero_bit(addr,size) \ ((__builtin_constant_p(size) && (size) <= BITS_PER_LONG ? \ - (__scanbit(~*(unsigned long *)addr,(size))) : \ + (__scanbit(~*(unsigned long *)addr)) : \ find_first_zero_bit(addr,size))) - + #define find_next_zero_bit(addr,size,off) \ -((__builtin_constant_p(size) && (size) <= BITS_PER_LONG ? \ - ((off)+(__scanbit(~(((*(unsigned long *)addr)) >> (off)),(size)-(off)))) : \ +((__builtin_constant_p(size) && (size) <= BITS_PER_LONG ? \ + ((off)+(__scanbit(~(((*(unsigned long *)addr)) >> (off))))) : \ find_next_zero_bit(addr,size,off))) /* - * These are the preferred 'find first' functions in Xen. - * Both return the appropriate bit index, with the l.s.b. having index 0. - * If an appropriate bit is not found then the result is undefined. + * Return index of first non-zero bit in @word (counting l.s.b. as 0). + * If no bits are set (@word == 0) then the result is undefined. */ -static __inline__ unsigned long find_first_clear_bit(unsigned long word) -{ - __asm__("bsf %1,%0" - :"=r" (word) - :"r" (~word)); - return word; -} - static __inline__ unsigned long find_first_set_bit(unsigned long word) { __asm__("bsf %1,%0" diff -Nru a/xen/include/xen/cpumask.h b/xen/include/xen/cpumask.h --- a/xen/include/xen/cpumask.h 2005-05-29 07:03:51 -04:00 +++ b/xen/include/xen/cpumask.h 2005-05-29 07:03:51 -04:00 @@ -36,8 +36,8 @@ * void cpus_shift_right(dst, src, n) Shift right * void cpus_shift_left(dst, src, n) Shift left * - * int first_cpu(mask) Number lowest set bit, or NR_CPUS - * int next_cpu(cpu, mask) Next cpu past 'cpu', or NR_CPUS + * int first_cpu(mask) Number lowest set bit, or >= NR_CPUS + * int next_cpu(cpu, mask) Next cpu past 'cpu', or >= NR_CPUS * * cpumask_t cpumask_of_cpu(cpu) Return cpumask with bit 'cpu' set * CPU_MASK_ALL Initializer - all bits set @@ -57,7 +57,7 @@ * int cpu_possible(cpu) Is some cpu possible? * int cpu_present(cpu) Is some cpu present (can schedule)? * - * int any_online_cpu(mask) First online cpu in mask + * int any_online_cpu(mask) First online cpu in mask, or NR_CPUS * * for_each_cpu(cpu) for-loop cpu over cpu_possible_map * for_each_online_cpu(cpu) for-loop cpu over cpu_online_map @@ -207,13 +207,13 @@ #define first_cpu(src) __first_cpu(&(src), NR_CPUS) static inline int __first_cpu(const cpumask_t *srcp, int nbits) { - return min_t(int, nbits, find_first_bit(srcp->bits, nbits)); + return find_first_bit(srcp->bits, nbits); } #define next_cpu(n, src) __next_cpu((n), &(src), NR_CPUS) static inline int __next_cpu(int n, const cpumask_t *srcp, int nbits) { - return min_t(int, nbits, find_next_bit(srcp->bits, nbits, n+1)); + return find_next_bit(srcp->bits, nbits, n+1); } #define cpumask_of_cpu(cpu) \ @@ -368,7 +368,7 @@ for_each_cpu_mask(cpu, (mask)) \ if (cpu_online(cpu)) \ break; \ - cpu; \ + min_t(int, NR_CPUS, cpu); \ }) #define for_each_cpu(cpu) for_each_cpu_mask((cpu), cpu_possible_map) _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |