bitmap.h 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. /*
  2. * Bitmap Module
  3. *
  4. * Copyright (C) 2010 Corentin Chary <corentin.chary@gmail.com>
  5. *
  6. * Mostly inspired by (stolen from) linux/bitmap.h and linux/bitops.h
  7. *
  8. * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
  9. * See the COPYING.LIB file in the top-level directory.
  10. */
  11. #ifndef BITMAP_H
  12. #define BITMAP_H
  13. #include "qemu-common.h"
  14. #include "bitops.h"
  15. /*
  16. * The available bitmap operations and their rough meaning in the
  17. * case that the bitmap is a single unsigned long are thus:
  18. *
  19. * Note that nbits should be always a compile time evaluable constant.
  20. * Otherwise many inlines will generate horrible code.
  21. *
  22. * bitmap_zero(dst, nbits) *dst = 0UL
  23. * bitmap_fill(dst, nbits) *dst = ~0UL
  24. * bitmap_copy(dst, src, nbits) *dst = *src
  25. * bitmap_and(dst, src1, src2, nbits) *dst = *src1 & *src2
  26. * bitmap_or(dst, src1, src2, nbits) *dst = *src1 | *src2
  27. * bitmap_xor(dst, src1, src2, nbits) *dst = *src1 ^ *src2
  28. * bitmap_andnot(dst, src1, src2, nbits) *dst = *src1 & ~(*src2)
  29. * bitmap_complement(dst, src, nbits) *dst = ~(*src)
  30. * bitmap_equal(src1, src2, nbits) Are *src1 and *src2 equal?
  31. * bitmap_intersects(src1, src2, nbits) Do *src1 and *src2 overlap?
  32. * bitmap_empty(src, nbits) Are all bits zero in *src?
  33. * bitmap_full(src, nbits) Are all bits set in *src?
  34. * bitmap_set(dst, pos, nbits) Set specified bit area
  35. * bitmap_clear(dst, pos, nbits) Clear specified bit area
  36. * bitmap_find_next_zero_area(buf, len, pos, n, mask) Find bit free area
  37. */
  38. /*
  39. * Also the following operations apply to bitmaps.
  40. *
  41. * set_bit(bit, addr) *addr |= bit
  42. * clear_bit(bit, addr) *addr &= ~bit
  43. * change_bit(bit, addr) *addr ^= bit
  44. * test_bit(bit, addr) Is bit set in *addr?
  45. * test_and_set_bit(bit, addr) Set bit and return old value
  46. * test_and_clear_bit(bit, addr) Clear bit and return old value
  47. * test_and_change_bit(bit, addr) Change bit and return old value
  48. * find_first_zero_bit(addr, nbits) Position first zero bit in *addr
  49. * find_first_bit(addr, nbits) Position first set bit in *addr
  50. * find_next_zero_bit(addr, nbits, bit) Position next zero bit in *addr >= bit
  51. * find_next_bit(addr, nbits, bit) Position next set bit in *addr >= bit
  52. */
  53. #define BITMAP_LAST_WORD_MASK(nbits) \
  54. ( \
  55. ((nbits) % BITS_PER_LONG) ? \
  56. (1UL<<((nbits) % BITS_PER_LONG))-1 : ~0UL \
  57. )
  58. #define DECLARE_BITMAP(name,bits) \
  59. unsigned long name[BITS_TO_LONGS(bits)]
  60. #define small_nbits(nbits) \
  61. ((nbits) <= BITS_PER_LONG)
  62. int slow_bitmap_empty(const unsigned long *bitmap, int bits);
  63. int slow_bitmap_full(const unsigned long *bitmap, int bits);
  64. int slow_bitmap_equal(const unsigned long *bitmap1,
  65. const unsigned long *bitmap2, int bits);
  66. void slow_bitmap_complement(unsigned long *dst, const unsigned long *src,
  67. int bits);
  68. void slow_bitmap_shift_right(unsigned long *dst,
  69. const unsigned long *src, int shift, int bits);
  70. void slow_bitmap_shift_left(unsigned long *dst,
  71. const unsigned long *src, int shift, int bits);
  72. int slow_bitmap_and(unsigned long *dst, const unsigned long *bitmap1,
  73. const unsigned long *bitmap2, int bits);
  74. void slow_bitmap_or(unsigned long *dst, const unsigned long *bitmap1,
  75. const unsigned long *bitmap2, int bits);
  76. void slow_bitmap_xor(unsigned long *dst, const unsigned long *bitmap1,
  77. const unsigned long *bitmap2, int bits);
  78. int slow_bitmap_andnot(unsigned long *dst, const unsigned long *bitmap1,
  79. const unsigned long *bitmap2, int bits);
  80. int slow_bitmap_intersects(const unsigned long *bitmap1,
  81. const unsigned long *bitmap2, int bits);
  82. static inline unsigned long *bitmap_new(int nbits)
  83. {
  84. int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long);
  85. return g_malloc0(len);
  86. }
  87. static inline void bitmap_zero(unsigned long *dst, int nbits)
  88. {
  89. if (small_nbits(nbits)) {
  90. *dst = 0UL;
  91. } else {
  92. int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long);
  93. memset(dst, 0, len);
  94. }
  95. }
  96. static inline void bitmap_fill(unsigned long *dst, int nbits)
  97. {
  98. size_t nlongs = BITS_TO_LONGS(nbits);
  99. if (!small_nbits(nbits)) {
  100. int len = (nlongs - 1) * sizeof(unsigned long);
  101. memset(dst, 0xff, len);
  102. }
  103. dst[nlongs - 1] = BITMAP_LAST_WORD_MASK(nbits);
  104. }
  105. static inline void bitmap_copy(unsigned long *dst, const unsigned long *src,
  106. int nbits)
  107. {
  108. if (small_nbits(nbits)) {
  109. *dst = *src;
  110. } else {
  111. int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long);
  112. memcpy(dst, src, len);
  113. }
  114. }
  115. static inline int bitmap_and(unsigned long *dst, const unsigned long *src1,
  116. const unsigned long *src2, int nbits)
  117. {
  118. if (small_nbits(nbits)) {
  119. return (*dst = *src1 & *src2) != 0;
  120. }
  121. return slow_bitmap_and(dst, src1, src2, nbits);
  122. }
  123. static inline void bitmap_or(unsigned long *dst, const unsigned long *src1,
  124. const unsigned long *src2, int nbits)
  125. {
  126. if (small_nbits(nbits)) {
  127. *dst = *src1 | *src2;
  128. } else {
  129. slow_bitmap_or(dst, src1, src2, nbits);
  130. }
  131. }
  132. static inline void bitmap_xor(unsigned long *dst, const unsigned long *src1,
  133. const unsigned long *src2, int nbits)
  134. {
  135. if (small_nbits(nbits)) {
  136. *dst = *src1 ^ *src2;
  137. } else {
  138. slow_bitmap_xor(dst, src1, src2, nbits);
  139. }
  140. }
  141. static inline int bitmap_andnot(unsigned long *dst, const unsigned long *src1,
  142. const unsigned long *src2, int nbits)
  143. {
  144. if (small_nbits(nbits)) {
  145. return (*dst = *src1 & ~(*src2)) != 0;
  146. }
  147. return slow_bitmap_andnot(dst, src1, src2, nbits);
  148. }
  149. static inline void bitmap_complement(unsigned long *dst, const unsigned long *src,
  150. int nbits)
  151. {
  152. if (small_nbits(nbits)) {
  153. *dst = ~(*src) & BITMAP_LAST_WORD_MASK(nbits);
  154. } else {
  155. slow_bitmap_complement(dst, src, nbits);
  156. }
  157. }
  158. static inline int bitmap_equal(const unsigned long *src1,
  159. const unsigned long *src2, int nbits)
  160. {
  161. if (small_nbits(nbits)) {
  162. return ! ((*src1 ^ *src2) & BITMAP_LAST_WORD_MASK(nbits));
  163. } else {
  164. return slow_bitmap_equal(src1, src2, nbits);
  165. }
  166. }
  167. static inline int bitmap_empty(const unsigned long *src, int nbits)
  168. {
  169. if (small_nbits(nbits)) {
  170. return ! (*src & BITMAP_LAST_WORD_MASK(nbits));
  171. } else {
  172. return slow_bitmap_empty(src, nbits);
  173. }
  174. }
  175. static inline int bitmap_full(const unsigned long *src, int nbits)
  176. {
  177. if (small_nbits(nbits)) {
  178. return ! (~(*src) & BITMAP_LAST_WORD_MASK(nbits));
  179. } else {
  180. return slow_bitmap_full(src, nbits);
  181. }
  182. }
  183. static inline int bitmap_intersects(const unsigned long *src1,
  184. const unsigned long *src2, int nbits)
  185. {
  186. if (small_nbits(nbits)) {
  187. return ((*src1 & *src2) & BITMAP_LAST_WORD_MASK(nbits)) != 0;
  188. } else {
  189. return slow_bitmap_intersects(src1, src2, nbits);
  190. }
  191. }
  192. void bitmap_set(unsigned long *map, int i, int len);
  193. void bitmap_clear(unsigned long *map, int start, int nr);
  194. unsigned long bitmap_find_next_zero_area(unsigned long *map,
  195. unsigned long size,
  196. unsigned long start,
  197. unsigned int nr,
  198. unsigned long align_mask);
  199. #endif /* BITMAP_H */