mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
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>
This commit is contained in:
1 parent
e7f2dc7e85
commit
9be9caedcb
2 files changed
+22
-29
No files matched your search
@@ -274,7 +274,8 @@ static inline long find_first_zero_bit(
|
||||
"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 @@ static inline long find_first_bit(
|
||||
"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 @@ static inline long find_first_bit(
|
||||
*/
|
||||
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"
|
||||
|
||||
@@ -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 @@ static inline void __cpus_shift_left(cpumask_t *dstp,
|
||||
#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 @@ extern cpumask_t cpu_present_map;
|
||||
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)
|
||||
|
||||