diff --git a/qemu/include/qemu/bitmap.h b/qemu/include/qemu/bitmap.h index 80297364..1bae171d 100644 --- a/qemu/include/qemu/bitmap.h +++ b/qemu/include/qemu/bitmap.h @@ -48,6 +48,8 @@ #define DECLARE_BITMAP(name,bits) \ unsigned long name[BITS_TO_LONGS(bits)] +long slow_bitmap_count_one(const unsigned long *bitmap, long nbits); + static inline unsigned long *bitmap_try_new(long nbits) { long len = BITS_TO_LONGS(nbits) * sizeof(unsigned long); @@ -63,6 +65,15 @@ static inline unsigned long *bitmap_new(long nbits) return ptr; } +static inline long bitmap_count_one(const unsigned long *bitmap, long nbits) +{ + if (small_nbits(nbits)) { + return ctpopl(*bitmap & BITMAP_LAST_WORD_MASK(nbits)); + } else { + return slow_bitmap_count_one(bitmap, nbits); + } +} + void bitmap_set(unsigned long *map, long i, long len); void bitmap_set_atomic(unsigned long *map, long i, long len); void bitmap_clear(unsigned long *map, long start, long nr); diff --git a/qemu/util/bitmap.c b/qemu/util/bitmap.c index 037eb0f0..d605244a 100644 --- a/qemu/util/bitmap.c +++ b/qemu/util/bitmap.c @@ -148,3 +148,18 @@ void bitmap_copy_and_clear_atomic(unsigned long *dst, unsigned long *src, nr -= BITS_PER_LONG; } } + +long slow_bitmap_count_one(const unsigned long *bitmap, long nbits) +{ + long k, lim = nbits / BITS_PER_LONG, result = 0; + + for (k = 0; k < lim; k++) { + result += ctpopl(bitmap[k]); + } + + if (nbits % BITS_PER_LONG) { + result += ctpopl(bitmap[k] & BITMAP_LAST_WORD_MASK(nbits)); + } + + return result; +}