diff mbox

[RFC,05/29] bitmap: introduce bitmap_count_one()

Message ID 1501229198-30588-6-git-send-email-peterx@redhat.com
State New
Headers show

Commit Message

Peter Xu July 28, 2017, 8:06 a.m. UTC
Count how many bits set in the bitmap.

Signed-off-by: Peter Xu <peterx@redhat.com>
---
 include/qemu/bitmap.h | 10 ++++++++++
 util/bitmap.c         | 15 +++++++++++++++
 2 files changed, 25 insertions(+)

Comments

Dr. David Alan Gilbert July 31, 2017, 5:58 p.m. UTC | #1
* Peter Xu (peterx@redhat.com) wrote:
> Count how many bits set in the bitmap.
> 
> Signed-off-by: Peter Xu <peterx@redhat.com>
> ---
>  include/qemu/bitmap.h | 10 ++++++++++
>  util/bitmap.c         | 15 +++++++++++++++
>  2 files changed, 25 insertions(+)
> 
> diff --git a/include/qemu/bitmap.h b/include/qemu/bitmap.h
> index 460d899..9c18da0 100644
> --- a/include/qemu/bitmap.h
> +++ b/include/qemu/bitmap.h
> @@ -83,6 +83,7 @@ int slow_bitmap_andnot(unsigned long *dst, const unsigned long *bitmap1,
>  int slow_bitmap_intersects(const unsigned long *bitmap1,
>                             const unsigned long *bitmap2, long bits);
>  void slow_bitmap_invert(unsigned long *bitmap, long nbits);
> +long slow_bitmap_count_one(const unsigned long *bitmap, long nbits);
>  
>  static inline unsigned long *bitmap_try_new(long nbits)
>  {
> @@ -226,6 +227,15 @@ static inline void bitmap_invert(unsigned long *bitmap, long nbits)
>      }
>  }
>  
> +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/util/bitmap.c b/util/bitmap.c
> index 9b7408c..73a1063 100644
> --- a/util/bitmap.c
> +++ b/util/bitmap.c
> @@ -368,3 +368,18 @@ void slow_bitmap_invert(unsigned long *bitmap, long nbits)
>          bitmap[k] ^= BITMAP_LAST_WORD_MASK(nbits);
>      }
>  }
> +
> +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;
> +}

Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>

(I checked what happens with BITMAP_LAST_WORD_MASK(0) interestingly it's
all 1 - so you do need that if)

> -- 
> 2.7.4
> 
--
Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK
diff mbox

Patch

diff --git a/include/qemu/bitmap.h b/include/qemu/bitmap.h
index 460d899..9c18da0 100644
--- a/include/qemu/bitmap.h
+++ b/include/qemu/bitmap.h
@@ -83,6 +83,7 @@  int slow_bitmap_andnot(unsigned long *dst, const unsigned long *bitmap1,
 int slow_bitmap_intersects(const unsigned long *bitmap1,
                            const unsigned long *bitmap2, long bits);
 void slow_bitmap_invert(unsigned long *bitmap, long nbits);
+long slow_bitmap_count_one(const unsigned long *bitmap, long nbits);
 
 static inline unsigned long *bitmap_try_new(long nbits)
 {
@@ -226,6 +227,15 @@  static inline void bitmap_invert(unsigned long *bitmap, long nbits)
     }
 }
 
+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/util/bitmap.c b/util/bitmap.c
index 9b7408c..73a1063 100644
--- a/util/bitmap.c
+++ b/util/bitmap.c
@@ -368,3 +368,18 @@  void slow_bitmap_invert(unsigned long *bitmap, long nbits)
         bitmap[k] ^= BITMAP_LAST_WORD_MASK(nbits);
     }
 }
+
+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;
+}