| /* GPLv2 or OpenIB.org BSD (MIT) See COPYING file */ |
| |
| #ifndef UTIL_BITMAP_H |
| #define UTIL_BITMAP_H |
| |
| #include <stdlib.h> |
| #include <stdbool.h> |
| #include <limits.h> |
| #include <string.h> |
| #include <assert.h> |
| |
| #include "util.h" |
| |
| #define BMP_DECLARE(name, nbits) \ |
| unsigned long (name)[BITS_TO_LONGS((nbits))] |
| |
| unsigned long bitmap_find_first_bit(const unsigned long *bmp, |
| unsigned long start, unsigned long end); |
| |
| void bitmap_zero_region(unsigned long *bmp, unsigned long start, |
| unsigned long end); |
| |
| void bitmap_fill_region(unsigned long *bmp, unsigned long start, |
| unsigned long end); |
| |
| unsigned long bitmap_find_free_region(unsigned long *bmp, |
| unsigned long nbits, |
| unsigned long region_size); |
| |
| static inline void bitmap_fill(unsigned long *bmp, unsigned long nbits) |
| { |
| unsigned long size = BITS_TO_LONGS(nbits) * sizeof(unsigned long); |
| |
| memset(bmp, 0xff, size); |
| } |
| |
| static inline void bitmap_zero(unsigned long *bmp, unsigned long nbits) |
| { |
| unsigned long size = BITS_TO_LONGS(nbits) * sizeof(unsigned long); |
| |
| memset(bmp, 0, size); |
| } |
| |
| static inline bool bitmap_empty(const unsigned long *bmp, unsigned long nbits) |
| { |
| unsigned long i; |
| unsigned long mask = ULONG_MAX; |
| |
| assert(nbits); |
| |
| for (i = 0; i < BITS_TO_LONGS(nbits) - 1; i++) { |
| if (bmp[i] != 0) |
| return false; |
| } |
| |
| if (nbits % BITS_PER_LONG) |
| mask = (1UL << (nbits % BITS_PER_LONG)) - 1; |
| |
| return (bmp[i] & mask) ? false : true; |
| } |
| |
| static inline bool bitmap_full(const unsigned long *bmp, unsigned long nbits) |
| { |
| unsigned long i; |
| unsigned long mask = ULONG_MAX; |
| |
| assert(nbits); |
| |
| for (i = 0; i < BITS_TO_LONGS(nbits) - 1; i++) { |
| if (bmp[i] != -1UL) |
| return false; |
| } |
| |
| if (nbits % BITS_PER_LONG) |
| mask = (1UL << (nbits % BITS_PER_LONG)) - 1; |
| |
| return ((bmp[i] & mask) ^ (mask)) ? false : true; |
| } |
| |
| static inline void bitmap_set_bit(unsigned long *bmp, unsigned long idx) |
| { |
| bmp[(idx / BITS_PER_LONG)] |= (1UL << (idx % BITS_PER_LONG)); |
| } |
| |
| static inline void bitmap_clear_bit(unsigned long *bmp, unsigned long idx) |
| { |
| bmp[(idx / BITS_PER_LONG)] &= ~(1UL << (idx % BITS_PER_LONG)); |
| } |
| |
| static inline bool bitmap_test_bit(const unsigned long *bmp, unsigned long idx) |
| { |
| return !!(bmp[(idx / BITS_PER_LONG)] & |
| (1UL << (idx % BITS_PER_LONG))); |
| } |
| |
| static inline unsigned long *bitmap_alloc0(unsigned long size) |
| { |
| unsigned long *bmp; |
| |
| bmp = calloc(BITS_TO_LONGS(size), sizeof(long)); |
| if (!bmp) |
| return NULL; |
| |
| return bmp; |
| } |
| |
| static inline unsigned long *bitmap_alloc1(unsigned long size) |
| { |
| unsigned long *bmp; |
| |
| bmp = bitmap_alloc0(size); |
| if (!bmp) |
| return NULL; |
| |
| bitmap_fill(bmp, size); |
| |
| return bmp; |
| } |
| |
| #endif |