1 #ifndef _PERF_BITOPS_H 2 #define _PERF_BITOPS_H 3 4 #include <string.h> 5 #include <linux/bitops.h> 6 #include <stdlib.h> 7 8 #define DECLARE_BITMAP(name,bits) \ 9 unsigned long name[BITS_TO_LONGS(bits)] 10 11 int __bitmap_weight(const unsigned long *bitmap, int bits); 12 void __bitmap_or(unsigned long *dst, const unsigned long *bitmap1, 13 const unsigned long *bitmap2, int bits); 14 int __bitmap_and(unsigned long *dst, const unsigned long *bitmap1, 15 const unsigned long *bitmap2, unsigned int bits); 16 17 #define BITMAP_FIRST_WORD_MASK(start) (~0UL << ((start) & (BITS_PER_LONG - 1))) 18 19 #define BITMAP_LAST_WORD_MASK(nbits) \ 20 ( \ 21 ((nbits) % BITS_PER_LONG) ? \ 22 (1UL<<((nbits) % BITS_PER_LONG))-1 : ~0UL \ 23 ) 24 25 #define small_const_nbits(nbits) \ 26 (__builtin_constant_p(nbits) && (nbits) <= BITS_PER_LONG) 27 28 static inline void bitmap_zero(unsigned long *dst, int nbits) 29 { 30 if (small_const_nbits(nbits)) 31 *dst = 0UL; 32 else { 33 int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long); 34 memset(dst, 0, len); 35 } 36 } 37 38 static inline void bitmap_fill(unsigned long *dst, unsigned int nbits) 39 { 40 unsigned int nlongs = BITS_TO_LONGS(nbits); 41 if (!small_const_nbits(nbits)) { 42 unsigned int len = (nlongs - 1) * sizeof(unsigned long); 43 memset(dst, 0xff, len); 44 } 45 dst[nlongs - 1] = BITMAP_LAST_WORD_MASK(nbits); 46 } 47 48 static inline int bitmap_empty(const unsigned long *src, unsigned nbits) 49 { 50 if (small_const_nbits(nbits)) 51 return ! (*src & BITMAP_LAST_WORD_MASK(nbits)); 52 53 return find_first_bit(src, nbits) == nbits; 54 } 55 56 static inline int bitmap_full(const unsigned long *src, unsigned int nbits) 57 { 58 if (small_const_nbits(nbits)) 59 return ! (~(*src) & BITMAP_LAST_WORD_MASK(nbits)); 60 61 return find_first_zero_bit(src, nbits) == nbits; 62 } 63 64 static inline int bitmap_weight(const unsigned long *src, int nbits) 65 { 66 if (small_const_nbits(nbits)) 67 return hweight_long(*src & BITMAP_LAST_WORD_MASK(nbits)); 68 return __bitmap_weight(src, nbits); 69 } 70 71 static inline void bitmap_or(unsigned long *dst, const unsigned long *src1, 72 const unsigned long *src2, int nbits) 73 { 74 if (small_const_nbits(nbits)) 75 *dst = *src1 | *src2; 76 else 77 __bitmap_or(dst, src1, src2, nbits); 78 } 79 80 /** 81 * test_and_set_bit - Set a bit and return its old value 82 * @nr: Bit to set 83 * @addr: Address to count from 84 */ 85 static inline int test_and_set_bit(int nr, unsigned long *addr) 86 { 87 unsigned long mask = BIT_MASK(nr); 88 unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); 89 unsigned long old; 90 91 old = *p; 92 *p = old | mask; 93 94 return (old & mask) != 0; 95 } 96 97 /** 98 * bitmap_alloc - Allocate bitmap 99 * @nr: Bit to set 100 */ 101 static inline unsigned long *bitmap_alloc(int nbits) 102 { 103 return calloc(1, BITS_TO_LONGS(nbits) * sizeof(unsigned long)); 104 } 105 106 /* 107 * bitmap_scnprintf - print bitmap list into buffer 108 * @bitmap: bitmap 109 * @nbits: size of bitmap 110 * @buf: buffer to store output 111 * @size: size of @buf 112 */ 113 size_t bitmap_scnprintf(unsigned long *bitmap, int nbits, 114 char *buf, size_t size); 115 116 /** 117 * bitmap_and - Do logical and on bitmaps 118 * @dst: resulting bitmap 119 * @src1: operand 1 120 * @src2: operand 2 121 * @nbits: size of bitmap 122 */ 123 static inline int bitmap_and(unsigned long *dst, const unsigned long *src1, 124 const unsigned long *src2, unsigned int nbits) 125 { 126 if (small_const_nbits(nbits)) 127 return (*dst = *src1 & *src2 & BITMAP_LAST_WORD_MASK(nbits)) != 0; 128 return __bitmap_and(dst, src1, src2, nbits); 129 } 130 131 #endif /* _PERF_BITOPS_H */ 132