bitmaps.h 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. /* bitmaps and bitmap operations */
  2. #ifndef _BITMAPS_H_
  3. #define _BITMAPS_H_
  4. /*
  5. * Bitmaps are arrays of unsigned ints, filled with bits in most-
  6. * significant-first order. So bitmap[0] shall contain the bits from
  7. * 0 to 31 on a 32bit architecture, bitmap[1] - 32-63, and so forth.
  8. *
  9. * The callers are responsible to do all the bounds-checking.
  10. */
  11. enum { BITS_PER_BITMAP_ELEM = 8 * sizeof(unsigned) };
  12. typedef unsigned bitmap_elem_t;
  13. /* returned is the unshifted bit state. IOW: NOT 0 or 1, but something
  14. * like 0x00001000 or 0x40000000 */
  15. static inline
  16. bitmap_elem_t bitmap_test_bit(const bitmap_elem_t* bits, unsigned bit)
  17. {
  18. if ( sizeof(*bits) == 4 )
  19. return bits[bit >> 5] & (0x80000000 >> (bit & 0x1f));
  20. else if ( sizeof(*bits) == 8 )
  21. return bits[bit >> 6] & (0x8000000000000000ull >> (bit & 0x3f));
  22. else
  23. {
  24. return bits[bit / BITS_PER_BITMAP_ELEM] &
  25. 1 << ((BITS_PER_BITMAP_ELEM - bit % BITS_PER_BITMAP_ELEM) - 1);
  26. }
  27. }
  28. static inline
  29. bitmap_elem_t bitmap_set_bit(bitmap_elem_t* bits, unsigned bit)
  30. {
  31. if ( sizeof(*bits) == 4 )
  32. return bits[bit >> 5] |= (0x80000000 >> (bit & 0x1f));
  33. else if ( sizeof(*bits) == 8 )
  34. return bits[bit >> 6] |= (0x8000000000000000ull >> (bit & 0x3f));
  35. else
  36. {
  37. return bits[bit / BITS_PER_BITMAP_ELEM] |=
  38. 1 << ((BITS_PER_BITMAP_ELEM - bit % BITS_PER_BITMAP_ELEM) - 1);
  39. }
  40. }
  41. /* pos must position the bits inside of a bitmap element, otherwise
  42. * the index shift puts the bits in the wrong word (for simplicity).
  43. * Only low 8 bits of b8 shall be used */
  44. static inline
  45. void bitmap_set_8bits_fast(bitmap_elem_t* bits, unsigned pos, unsigned b8)
  46. {
  47. if ( sizeof(*bits) == 4 )
  48. bits[pos >> 5] |= b8 << (24 - (pos & 0x1f));
  49. else if ( sizeof(*bits) == 8 )
  50. bits[pos >> 6] |= b8 << (56 - (pos & 0x3f));
  51. else
  52. {
  53. bits[pos / BITS_PER_BITMAP_ELEM] |=
  54. b8 << (BITS_PER_BITMAP_ELEM - 8 - pos % BITS_PER_BITMAP_ELEM);
  55. }
  56. }
  57. static inline
  58. bitmap_elem_t bitmap_clear_bit(bitmap_elem_t* bits, unsigned bit)
  59. {
  60. if ( sizeof(*bits) == 4 )
  61. return bits[bit >> 5] &= ~(0x80000000 >> (bit & 0x1f));
  62. else if ( sizeof(*bits) == 8 )
  63. return bits[bit >> 6] &= ~(0x8000000000000000ull >> (bit & 0x3f));
  64. else
  65. {
  66. return bits[bit / BITS_PER_BITMAP_ELEM] &=
  67. ~(1 << ((BITS_PER_BITMAP_ELEM - bit % BITS_PER_BITMAP_ELEM) - 1));
  68. }
  69. }
  70. #endif /* _BITMAPS_H_ */