bitmap: introduce bitmap_count_one()

Count how many bits set in the bitmap.

Backports commit fc7deeea26af3d08f45bad85b8bd3fc3d790a090 from qemu
This commit is contained in:
Peter Xu 2018-03-05 01:08:26 -05:00 committed by Lioncash
parent 296c30aaca
commit 3d5fa79305
No known key found for this signature in database
GPG key ID: 4E3C3CC1031BA9C7
2 changed files with 26 additions and 0 deletions

View file

@ -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);

View file

@ -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;
}