bitmap.h 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. #ifndef _TOOLS_LINUX_BITMAP_H
  3. #define _TOOLS_LINUX_BITMAP_H
  4. #include <string.h>
  5. #include <asm-generic/bitsperlong.h>
  6. #include <linux/align.h>
  7. #include <linux/bitops.h>
  8. #include <linux/find.h>
  9. #include <stdlib.h>
  10. #include <linux/kernel.h>
  11. #define DECLARE_BITMAP(name,bits) \
  12. unsigned long name[BITS_TO_LONGS(bits)]
  13. unsigned int __bitmap_weight(const unsigned long *bitmap, int bits);
  14. void __bitmap_or(unsigned long *dst, const unsigned long *bitmap1,
  15. const unsigned long *bitmap2, int bits);
  16. bool __bitmap_and(unsigned long *dst, const unsigned long *bitmap1,
  17. const unsigned long *bitmap2, unsigned int bits);
  18. bool __bitmap_equal(const unsigned long *bitmap1,
  19. const unsigned long *bitmap2, unsigned int bits);
  20. void __bitmap_set(unsigned long *map, unsigned int start, int len);
  21. void __bitmap_clear(unsigned long *map, unsigned int start, int len);
  22. bool __bitmap_intersects(const unsigned long *bitmap1,
  23. const unsigned long *bitmap2, unsigned int bits);
  24. bool __bitmap_subset(const unsigned long *bitmap1,
  25. const unsigned long *bitmap2, unsigned int nbits);
  26. bool __bitmap_andnot(unsigned long *dst, const unsigned long *bitmap1,
  27. const unsigned long *bitmap2, unsigned int nbits);
  28. #define BITMAP_FIRST_WORD_MASK(start) (~0UL << ((start) & (BITS_PER_LONG - 1)))
  29. #define BITMAP_LAST_WORD_MASK(nbits) (~0UL >> (-(nbits) & (BITS_PER_LONG - 1)))
  30. #define bitmap_size(nbits) (ALIGN(nbits, BITS_PER_LONG) / BITS_PER_BYTE)
  31. static inline void bitmap_zero(unsigned long *dst, unsigned int nbits)
  32. {
  33. if (small_const_nbits(nbits))
  34. *dst = 0UL;
  35. else {
  36. memset(dst, 0, bitmap_size(nbits));
  37. }
  38. }
  39. static inline void bitmap_fill(unsigned long *dst, unsigned int nbits)
  40. {
  41. unsigned int nlongs = BITS_TO_LONGS(nbits);
  42. if (!small_const_nbits(nbits)) {
  43. unsigned int len = (nlongs - 1) * sizeof(unsigned long);
  44. memset(dst, 0xff, len);
  45. }
  46. dst[nlongs - 1] = BITMAP_LAST_WORD_MASK(nbits);
  47. }
  48. static inline bool bitmap_empty(const unsigned long *src, unsigned int nbits)
  49. {
  50. if (small_const_nbits(nbits))
  51. return ! (*src & BITMAP_LAST_WORD_MASK(nbits));
  52. return find_first_bit(src, nbits) == nbits;
  53. }
  54. static inline bool bitmap_full(const unsigned long *src, unsigned int nbits)
  55. {
  56. if (small_const_nbits(nbits))
  57. return ! (~(*src) & BITMAP_LAST_WORD_MASK(nbits));
  58. return find_first_zero_bit(src, nbits) == nbits;
  59. }
  60. static inline unsigned int bitmap_weight(const unsigned long *src, unsigned int nbits)
  61. {
  62. if (small_const_nbits(nbits))
  63. return hweight_long(*src & BITMAP_LAST_WORD_MASK(nbits));
  64. return __bitmap_weight(src, nbits);
  65. }
  66. static inline void bitmap_or(unsigned long *dst, const unsigned long *src1,
  67. const unsigned long *src2, unsigned int nbits)
  68. {
  69. if (small_const_nbits(nbits))
  70. *dst = *src1 | *src2;
  71. else
  72. __bitmap_or(dst, src1, src2, nbits);
  73. }
  74. static __always_inline
  75. bool bitmap_andnot(unsigned long *dst, const unsigned long *src1,
  76. const unsigned long *src2, unsigned int nbits)
  77. {
  78. if (small_const_nbits(nbits))
  79. return (*dst = *src1 & ~(*src2) & BITMAP_LAST_WORD_MASK(nbits)) != 0;
  80. return __bitmap_andnot(dst, src1, src2, nbits);
  81. }
  82. static inline unsigned long *bitmap_alloc(unsigned int nbits, gfp_t flags __maybe_unused)
  83. {
  84. return malloc(bitmap_size(nbits));
  85. }
  86. /**
  87. * bitmap_zalloc - Allocate bitmap
  88. * @nbits: Number of bits
  89. */
  90. static inline unsigned long *bitmap_zalloc(int nbits)
  91. {
  92. return calloc(1, bitmap_size(nbits));
  93. }
  94. /*
  95. * bitmap_free - Free bitmap
  96. * @bitmap: pointer to bitmap
  97. */
  98. static inline void bitmap_free(unsigned long *bitmap)
  99. {
  100. free(bitmap);
  101. }
  102. /*
  103. * bitmap_scnprintf - print bitmap list into buffer
  104. * @bitmap: bitmap
  105. * @nbits: size of bitmap
  106. * @buf: buffer to store output
  107. * @size: size of @buf
  108. */
  109. size_t bitmap_scnprintf(unsigned long *bitmap, unsigned int nbits,
  110. char *buf, size_t size);
  111. /**
  112. * bitmap_and - Do logical and on bitmaps
  113. * @dst: resulting bitmap
  114. * @src1: operand 1
  115. * @src2: operand 2
  116. * @nbits: size of bitmap
  117. */
  118. static inline bool bitmap_and(unsigned long *dst, const unsigned long *src1,
  119. const unsigned long *src2, unsigned int nbits)
  120. {
  121. if (small_const_nbits(nbits))
  122. return (*dst = *src1 & *src2 & BITMAP_LAST_WORD_MASK(nbits)) != 0;
  123. return __bitmap_and(dst, src1, src2, nbits);
  124. }
  125. #ifdef __LITTLE_ENDIAN
  126. #define BITMAP_MEM_ALIGNMENT 8
  127. #else
  128. #define BITMAP_MEM_ALIGNMENT (8 * sizeof(unsigned long))
  129. #endif
  130. #define BITMAP_MEM_MASK (BITMAP_MEM_ALIGNMENT - 1)
  131. static inline bool bitmap_equal(const unsigned long *src1,
  132. const unsigned long *src2, unsigned int nbits)
  133. {
  134. if (small_const_nbits(nbits))
  135. return !((*src1 ^ *src2) & BITMAP_LAST_WORD_MASK(nbits));
  136. if (__builtin_constant_p(nbits & BITMAP_MEM_MASK) &&
  137. IS_ALIGNED(nbits, BITMAP_MEM_ALIGNMENT))
  138. return !memcmp(src1, src2, nbits / 8);
  139. return __bitmap_equal(src1, src2, nbits);
  140. }
  141. static inline bool bitmap_intersects(const unsigned long *src1,
  142. const unsigned long *src2,
  143. unsigned int nbits)
  144. {
  145. if (small_const_nbits(nbits))
  146. return ((*src1 & *src2) & BITMAP_LAST_WORD_MASK(nbits)) != 0;
  147. else
  148. return __bitmap_intersects(src1, src2, nbits);
  149. }
  150. static __always_inline
  151. bool bitmap_subset(const unsigned long *src1, const unsigned long *src2, unsigned int nbits)
  152. {
  153. if (small_const_nbits(nbits))
  154. return ! ((*src1 & ~(*src2)) & BITMAP_LAST_WORD_MASK(nbits));
  155. else
  156. return __bitmap_subset(src1, src2, nbits);
  157. }
  158. static inline void bitmap_set(unsigned long *map, unsigned int start, unsigned int nbits)
  159. {
  160. if (__builtin_constant_p(nbits) && nbits == 1)
  161. __set_bit(start, map);
  162. else if (small_const_nbits(start + nbits))
  163. *map |= GENMASK(start + nbits - 1, start);
  164. else if (__builtin_constant_p(start & BITMAP_MEM_MASK) &&
  165. IS_ALIGNED(start, BITMAP_MEM_ALIGNMENT) &&
  166. __builtin_constant_p(nbits & BITMAP_MEM_MASK) &&
  167. IS_ALIGNED(nbits, BITMAP_MEM_ALIGNMENT))
  168. memset((char *)map + start / 8, 0xff, nbits / 8);
  169. else
  170. __bitmap_set(map, start, nbits);
  171. }
  172. static inline void bitmap_clear(unsigned long *map, unsigned int start,
  173. unsigned int nbits)
  174. {
  175. if (__builtin_constant_p(nbits) && nbits == 1)
  176. __clear_bit(start, map);
  177. else if (small_const_nbits(start + nbits))
  178. *map &= ~GENMASK(start + nbits - 1, start);
  179. else if (__builtin_constant_p(start & BITMAP_MEM_MASK) &&
  180. IS_ALIGNED(start, BITMAP_MEM_ALIGNMENT) &&
  181. __builtin_constant_p(nbits & BITMAP_MEM_MASK) &&
  182. IS_ALIGNED(nbits, BITMAP_MEM_ALIGNMENT))
  183. memset((char *)map + start / 8, 0, nbits / 8);
  184. else
  185. __bitmap_clear(map, start, nbits);
  186. }
  187. #endif /* _TOOLS_LINUX_BITMAP_H */