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:
kaf24@firebug.cl.cam.ac.uk committed 2005-05-29 10:44:16 +00:00
1 parent e7f2dc7e85
commit 9be9caedcb
2 files changed
+22 -29

No files matched your search

+16 -23
View File
@@ -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"
+6 -6
View File
@@ -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)
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.