[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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.