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>
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)