diff options
author | Richard Braun <rbraun@sceen.net> | 2013-03-08 22:05:17 +0100 |
---|---|---|
committer | Richard Braun <rbraun@sceen.net> | 2013-03-08 22:05:17 +0100 |
commit | 4822f9bf6e62c7a9f089d1b876c471d9d962b03d (patch) | |
tree | 72f9ed1fc14b786f85b0578cd75315695b4fd7a1 /kern/bitmap.h | |
parent | 15199538948c1d327fb50ef22f5ac9a2589dfc74 (diff) |
kern/bitmap: new functions
Augment the interface with functions to search and iterate over zero bits.
Diffstat (limited to 'kern/bitmap.h')
-rw-r--r-- | kern/bitmap.h | 59 |
1 files changed, 28 insertions, 31 deletions
diff --git a/kern/bitmap.h b/kern/bitmap.h index 36018bcc..b1c74843 100644 --- a/kern/bitmap.h +++ b/kern/bitmap.h @@ -57,6 +57,15 @@ bitmap_mask(int bit) } /* + * Return the index of the next set bit in the bitmap, starting (and + * including) the given bit index, or -1 if the bitmap is empty. If + * complement is true, bits are toggled before searching so that the + * result is the index of the next zero bit. + */ +int bitmap_find_next_bit(volatile unsigned long *bm, int nr_bits, int bit, + int complement); + +/* * Public interface. */ @@ -123,40 +132,10 @@ bitmap_test(volatile unsigned long *bm, int bit) return ((*bm & bitmap_mask(bit)) != 0); } -/* - * Return the index of the next set bit in the bitmap, starting (and - * including) the given bit index, or -1 if the bitmap is empty. - */ static inline int bitmap_find_next(volatile unsigned long *bm, int nr_bits, int bit) { - volatile unsigned long *start, *end; - unsigned long word; - - start = bm; - end = bm + BITMAP_LONGS(nr_bits); - - if (bit >= LONG_BIT) - bitmap_lookup(&bm, &bit); - - word = *bm; - - if (bit < LONG_BIT) - word &= ~(bitmap_mask(bit) - 1); - - for (;;) { - bit = __builtin_ffsl(word); - - if (bit != 0) - return ((bm - start) * LONG_BIT) + bit - 1; - - bm++; - - if (bm >= end) - return -1; - - word = *bm; - } + return bitmap_find_next_bit(bm, nr_bits, bit, 0); } static inline int @@ -165,10 +144,28 @@ bitmap_find_first(volatile unsigned long *bm, int nr_bits) return bitmap_find_next(bm, nr_bits, 0); } +static inline int +bitmap_find_next_zero(volatile unsigned long *bm, int nr_bits, int bit) +{ + return bitmap_find_next_bit(bm, nr_bits, bit, 1); +} + +static inline int +bitmap_find_first_zero(volatile unsigned long *bm, int nr_bits) +{ + return bitmap_find_next_zero(bm, nr_bits, 0); +} + #define bitmap_for_each(bm, nr_bits, bit) \ for ((bit) = 0; \ ((bit) < nr_bits) \ && (((bit) = bitmap_find_next(bm, nr_bits, bit)) != -1); \ (bit)++) +#define bitmap_for_each_zero(bm, nr_bits, bit) \ +for ((bit) = 0; \ + ((bit) < nr_bits) \ + && (((bit) = bitmap_find_next_zero(bm, nr_bits, bit)) != -1); \ + (bit)++) + #endif /* _KERN_BITMAP_H */ |