[Qemu-devel] [RFC 04/29] bitmap: introduce bitmap_invert()

Peter Xu posted 29 patches 8 years, 6 months ago
There is a newer version of this series
[Qemu-devel] [RFC 04/29] bitmap: introduce bitmap_invert()
Posted by Peter Xu 8 years, 6 months ago
It is used to invert the whole bitmap.

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

diff --git a/include/qemu/bitmap.h b/include/qemu/bitmap.h
index c318da1..460d899 100644
--- a/include/qemu/bitmap.h
+++ b/include/qemu/bitmap.h
@@ -82,6 +82,7 @@ int slow_bitmap_andnot(unsigned long *dst, const unsigned long *bitmap1,
                        const unsigned long *bitmap2, long bits);
 int slow_bitmap_intersects(const unsigned long *bitmap1,
                            const unsigned long *bitmap2, long bits);
+void slow_bitmap_invert(unsigned long *bitmap, long nbits);
 
 static inline unsigned long *bitmap_try_new(long nbits)
 {
@@ -216,6 +217,15 @@ static inline int bitmap_intersects(const unsigned long *src1,
     }
 }
 
+static inline void bitmap_invert(unsigned long *bitmap, long nbits)
+{
+    if (small_nbits(nbits)) {
+        *bitmap ^= BITMAP_LAST_WORD_MASK(nbits);
+    } else {
+        slow_bitmap_invert(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 efced9a..9b7408c 100644
--- a/util/bitmap.c
+++ b/util/bitmap.c
@@ -355,3 +355,16 @@ int slow_bitmap_intersects(const unsigned long *bitmap1,
     }
     return 0;
 }
+
+void slow_bitmap_invert(unsigned long *bitmap, long nbits)
+{
+    long k, lim = nbits/BITS_PER_LONG;
+
+    for (k = 0; k < lim; k++) {
+        bitmap[k] ^= ULONG_MAX;
+    }
+
+    if (nbits % BITS_PER_LONG) {
+        bitmap[k] ^= BITMAP_LAST_WORD_MASK(nbits);
+    }
+}
-- 
2.7.4


Re: [Qemu-devel] [RFC 04/29] bitmap: introduce bitmap_invert()
Posted by Dr. David Alan Gilbert 8 years, 6 months ago
* Peter Xu (peterx@redhat.com) wrote:
> It is used to invert the whole bitmap.

Would it be easier to change bitmap_complement to use ^
in it's macro and slow_bitmap_complement, and then you could call it
with src==dst  to do the same thing with just that small change?

Dave

> Signed-off-by: Peter Xu <peterx@redhat.com>
> ---
>  include/qemu/bitmap.h | 10 ++++++++++
>  util/bitmap.c         | 13 +++++++++++++
>  2 files changed, 23 insertions(+)
> 
> diff --git a/include/qemu/bitmap.h b/include/qemu/bitmap.h
> index c318da1..460d899 100644
> --- a/include/qemu/bitmap.h
> +++ b/include/qemu/bitmap.h
> @@ -82,6 +82,7 @@ int slow_bitmap_andnot(unsigned long *dst, const unsigned long *bitmap1,
>                         const unsigned long *bitmap2, long bits);
>  int slow_bitmap_intersects(const unsigned long *bitmap1,
>                             const unsigned long *bitmap2, long bits);
> +void slow_bitmap_invert(unsigned long *bitmap, long nbits);
>  
>  static inline unsigned long *bitmap_try_new(long nbits)
>  {
> @@ -216,6 +217,15 @@ static inline int bitmap_intersects(const unsigned long *src1,
>      }
>  }
>  
> +static inline void bitmap_invert(unsigned long *bitmap, long nbits)
> +{
> +    if (small_nbits(nbits)) {
> +        *bitmap ^= BITMAP_LAST_WORD_MASK(nbits);
> +    } else {
> +        slow_bitmap_invert(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 efced9a..9b7408c 100644
> --- a/util/bitmap.c
> +++ b/util/bitmap.c
> @@ -355,3 +355,16 @@ int slow_bitmap_intersects(const unsigned long *bitmap1,
>      }
>      return 0;
>  }
> +
> +void slow_bitmap_invert(unsigned long *bitmap, long nbits)
> +{
> +    long k, lim = nbits/BITS_PER_LONG;
> +
> +    for (k = 0; k < lim; k++) {
> +        bitmap[k] ^= ULONG_MAX;
> +    }
> +
> +    if (nbits % BITS_PER_LONG) {
> +        bitmap[k] ^= BITMAP_LAST_WORD_MASK(nbits);
> +    }
> +}
> -- 
> 2.7.4
> 
--
Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK

Re: [Qemu-devel] [RFC 04/29] bitmap: introduce bitmap_invert()
Posted by Peter Xu 8 years, 6 months ago
On Mon, Jul 31, 2017 at 06:11:56PM +0100, Dr. David Alan Gilbert wrote:
> * Peter Xu (peterx@redhat.com) wrote:
> > It is used to invert the whole bitmap.
> 
> Would it be easier to change bitmap_complement to use ^
> in it's macro and slow_bitmap_complement, and then you could call it
> with src==dst  to do the same thing with just that small change?

Or, I can directly use that and drop this patch. :-)

(I didn't really notice that one before)

Thanks,

-- 
Peter Xu

Re: [Qemu-devel] [RFC 04/29] bitmap: introduce bitmap_invert()
Posted by Dr. David Alan Gilbert 8 years, 6 months ago
* Peter Xu (peterx@redhat.com) wrote:
> On Mon, Jul 31, 2017 at 06:11:56PM +0100, Dr. David Alan Gilbert wrote:
> > * Peter Xu (peterx@redhat.com) wrote:
> > > It is used to invert the whole bitmap.
> > 
> > Would it be easier to change bitmap_complement to use ^
> > in it's macro and slow_bitmap_complement, and then you could call it
> > with src==dst  to do the same thing with just that small change?
> 
> Or, I can directly use that and drop this patch. :-)

Yes, that's fine - note the only difference I see is what happens to the
bits in the last word after the end of the count; your code leaves them
as is, the complement code will zero them on the destination I think.

Dave

> (I didn't really notice that one before)
> 
> Thanks,
> 
> -- 
> Peter Xu
--
Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK

Re: [Qemu-devel] [RFC 04/29] bitmap: introduce bitmap_invert()
Posted by Peter Xu 8 years, 6 months ago
On Tue, Aug 01, 2017 at 09:40:09AM +0100, Dr. David Alan Gilbert wrote:
> * Peter Xu (peterx@redhat.com) wrote:
> > On Mon, Jul 31, 2017 at 06:11:56PM +0100, Dr. David Alan Gilbert wrote:
> > > * Peter Xu (peterx@redhat.com) wrote:
> > > > It is used to invert the whole bitmap.
> > > 
> > > Would it be easier to change bitmap_complement to use ^
> > > in it's macro and slow_bitmap_complement, and then you could call it
> > > with src==dst  to do the same thing with just that small change?
> > 
> > Or, I can directly use that and drop this patch. :-)
> 
> Yes, that's fine - note the only difference I see is what happens to the
> bits in the last word after the end of the count; your code leaves them
> as is, the complement code will zero them on the destination I think.

I see.  I believe both should work since bitmap users should not
use those bits after all (considering those bits are outside range of
valid bits when declaring the bitmap).  Thanks,

-- 
Peter Xu