bitmap: Fix some bugs on 32-bit platforms
authorDavid Gibson <david@gibson.dropbear.id.au>
Thu, 11 Jul 2019 02:07:33 +0000 (12:07 +1000)
committerDavid Gibson <david@gibson.dropbear.id.au>
Thu, 11 Jul 2019 02:07:33 +0000 (12:07 +1000)
The bitmap_word type is an unsigned long.  However in some places we assign
it using -1ULL, a 64-bit value on many platforms.  We sometimes get away
with this because it masks correctly, but in other cases it breaks things.

To clean this up define a new BITMAP_WORD_1 constant, indicating a
bitmap_word with all bits set, and use that instead of explicit UL or ULL
qualifiers.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
ccan/bitmap/bitmap.c
ccan/bitmap/bitmap.h

index d812af6a2344f47283f2dd89f358a398cf1cea17..d254b20e561ea804f456f777034c892d957e8cfd 100644 (file)
@@ -13,8 +13,8 @@ void bitmap_zero_range(bitmap *bitmap, unsigned long n, unsigned long m)
 {
        unsigned long an = BIT_ALIGN_UP(n);
        unsigned long am = BIT_ALIGN_DOWN(m);
-       bitmap_word headmask = -1ULL >> (n % BITMAP_WORD_BITS);
-       bitmap_word tailmask = ~(-1ULL >> (m % BITMAP_WORD_BITS));
+       bitmap_word headmask = BITMAP_WORD_1 >> (n % BITMAP_WORD_BITS);
+       bitmap_word tailmask = ~(BITMAP_WORD_1 >> (m % BITMAP_WORD_BITS));
 
        assert(m >= n);
 
@@ -38,8 +38,8 @@ void bitmap_fill_range(bitmap *bitmap, unsigned long n, unsigned long m)
 {
        unsigned long an = BIT_ALIGN_UP(n);
        unsigned long am = BIT_ALIGN_DOWN(m);
-       bitmap_word headmask = -1ULL >> (n % BITMAP_WORD_BITS);
-       bitmap_word tailmask = ~(-1ULL >> (m % BITMAP_WORD_BITS));
+       bitmap_word headmask = BITMAP_WORD_1 >> (n % BITMAP_WORD_BITS);
+       bitmap_word tailmask = ~(BITMAP_WORD_1 >> (m % BITMAP_WORD_BITS));
 
        assert(m >= n);
 
@@ -65,7 +65,7 @@ static int bitmap_clz(bitmap_word w)
        return __builtin_clzl(w);
 #else
        int lz = 0;
-       bitmap_word mask = 1UL << (BITMAP_WORD_BITS - 1);
+       bitmap_word mask = (bitmap_word)1 << (BITMAP_WORD_BITS - 1);
 
        while (!(w & mask)) {
                lz++;
@@ -81,8 +81,8 @@ unsigned long bitmap_ffs(const bitmap *bitmap,
 {
        unsigned long an = BIT_ALIGN_UP(n);
        unsigned long am = BIT_ALIGN_DOWN(m);
-       bitmap_word headmask = -1ULL >> (n % BITMAP_WORD_BITS);
-       bitmap_word tailmask = ~(-1ULL >> (m % BITMAP_WORD_BITS));
+       bitmap_word headmask = BITMAP_WORD_1 >> (n % BITMAP_WORD_BITS);
+       bitmap_word tailmask = ~(BITMAP_WORD_1 >> (m % BITMAP_WORD_BITS));
 
        assert(m >= n);
 
index 9e6c2bbc51912d797eec56000963756598d48592..beeb1e953cab473aaa0bcd70cb6755842629a988 100644 (file)
@@ -15,6 +15,9 @@ typedef unsigned long bitmap_word;
 #define BITMAP_NWORDS(_n)      \
        (((_n) + BITMAP_WORD_BITS - 1) / BITMAP_WORD_BITS)
 
+#define BITMAP_WORD_0          (0)
+#define BITMAP_WORD_1          ((bitmap_word)-1UL)
+
 /*
  * We wrap each word in a structure for type checking.
  */