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
|