bitmap.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. #include <limits.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #include <starpu.h>
  5. #include <starpu_sched_node.h>
  6. #ifndef LONG_BIT
  7. #define LONG_BIT (sizeof(unsigned long) * 8)
  8. #endif
  9. struct starpu_bitmap
  10. {
  11. unsigned long * bits;
  12. int size; /* the size of bits array in number of unsigned long */
  13. int cardinal;
  14. };
  15. #ifndef STARPU_NO_ASSERT
  16. static int check_bitmap(struct starpu_bitmap *b);
  17. #endif
  18. static int _count_bit(unsigned long e)
  19. {
  20. int c = 0;
  21. while(e)
  22. {
  23. c += e&1;
  24. e >>= 1;
  25. }
  26. return c;
  27. }
  28. struct starpu_bitmap * starpu_bitmap_create(void)
  29. {
  30. struct starpu_bitmap * b = malloc(sizeof(*b));
  31. memset(b,0,sizeof(*b));
  32. return b;
  33. }
  34. void starpu_bitmap_destroy(struct starpu_bitmap * b)
  35. {
  36. if(b)
  37. {
  38. free(b->bits);
  39. free(b);
  40. }
  41. }
  42. void starpu_bitmap_set(struct starpu_bitmap * b, int e)
  43. {
  44. if(!starpu_bitmap_get(b, e))
  45. b->cardinal++;
  46. else
  47. return;
  48. if((e/LONG_BIT) + 1 > b->size)
  49. {
  50. b->bits = realloc(b->bits, sizeof(unsigned long) * ((e/LONG_BIT) + 1));
  51. memset(b->bits + b->size, 0, sizeof(unsigned long) * ((e/LONG_BIT + 1) - b->size));
  52. b->size = (e/LONG_BIT) + 1;
  53. }
  54. b->bits[e/LONG_BIT] |= (1ul << (e%LONG_BIT));
  55. STARPU_ASSERT(check_bitmap(b));
  56. }
  57. void starpu_bitmap_unset(struct starpu_bitmap *b, int e)
  58. {
  59. if(starpu_bitmap_get(b, e))
  60. b->cardinal--;
  61. else
  62. return;
  63. if(e / LONG_BIT > b->size)
  64. return;
  65. b->bits[e/LONG_BIT] &= ~(1ul << (e%LONG_BIT));
  66. STARPU_ASSERT(check_bitmap(b));
  67. }
  68. void starpu_bitmap_unset_all(struct starpu_bitmap * b)
  69. {
  70. free(b->bits);
  71. b->bits = NULL;
  72. b->size = 0;
  73. }
  74. void starpu_bitmap_unset_and(struct starpu_bitmap * a, struct starpu_bitmap * b, struct starpu_bitmap * c)
  75. {
  76. int n = STARPU_MIN(b->size, c->size);
  77. a->bits = realloc(a->bits, sizeof(unsigned long) * n);
  78. a->size = n;
  79. a->cardinal = 0;
  80. int i;
  81. for(i = 0; i < n; i++)
  82. {
  83. a->bits[i] = b->bits[i] & c->bits[i];
  84. a->cardinal += _count_bit(a->bits[i]);
  85. }
  86. }
  87. int starpu_bitmap_get(struct starpu_bitmap * b, int e)
  88. {
  89. if(e / LONG_BIT >= b->size)
  90. return 0;
  91. return (b->bits[e/LONG_BIT] & (1ul << (e%LONG_BIT))) ?
  92. 1:
  93. 0;
  94. }
  95. void starpu_bitmap_or(struct starpu_bitmap * a, struct starpu_bitmap * b)
  96. {
  97. if(a->size < b->size)
  98. {
  99. a->bits = realloc(a->bits, b->size * sizeof(unsigned long));
  100. memset(a->bits + a->size, 0, (b->size - a->size) * sizeof(unsigned long));
  101. a->size = b->size;
  102. }
  103. int i;
  104. for(i = 0; i < b->size; i++)
  105. {
  106. a->bits[i] |= b->bits[i];
  107. }
  108. a->cardinal = 0;
  109. for(i = 0; i < a->size; i++)
  110. a->cardinal += _count_bit(a->bits[i]);
  111. }
  112. int starpu_bitmap_and_get(struct starpu_bitmap * b1, struct starpu_bitmap * b2, int e)
  113. {
  114. return starpu_bitmap_get(b1,e) && starpu_bitmap_get(b2,e);
  115. }
  116. int starpu_bitmap_cardinal(struct starpu_bitmap * b)
  117. {
  118. return b->cardinal;
  119. }
  120. static inline int get_first_bit_rank(unsigned long ms)
  121. {
  122. STARPU_ASSERT(ms != 0);
  123. unsigned long m = 1ul;
  124. int i = 0;
  125. while(!(m&ms))
  126. i++,m<<=1;
  127. return i;
  128. }
  129. int starpu_bitmap_first(struct starpu_bitmap * b)
  130. {
  131. int i = 0;
  132. while(i < b->size && !b->bits[i])
  133. i++;
  134. if( i == b->size)
  135. return -1;
  136. int nb_long = i;
  137. unsigned long ms = b->bits[i];
  138. return (nb_long * LONG_BIT) + get_first_bit_rank(ms);
  139. }
  140. int starpu_bitmap_has_next(struct starpu_bitmap * b, int e)
  141. {
  142. int nb_long = e / LONG_BIT;
  143. int nb_bit = e % LONG_BIT;
  144. unsigned long mask = (~0ul) << (nb_bit + 1);
  145. if(b->bits[nb_long] & mask)
  146. return 1;
  147. for(nb_long++; nb_long < b->size; nb_long++)
  148. if(b->bits[nb_long])
  149. return 1;
  150. return 0;
  151. }
  152. int starpu_bitmap_last(struct starpu_bitmap * b)
  153. {
  154. if(b->cardinal == 0)
  155. return -1;
  156. int ilong;
  157. for(ilong = b->size - 1; ilong >= 0; ilong--)
  158. {
  159. if(b->bits[ilong])
  160. break;
  161. }
  162. STARPU_ASSERT(ilong >= 0);
  163. unsigned long l = b->bits[ilong];
  164. int ibit = LONG_BIT - 1;
  165. while((!(1ul << ibit)) & l)
  166. ibit--;
  167. STARPU_ASSERT(ibit >= 0);
  168. return ilong * LONG_BIT + ibit;
  169. }
  170. int starpu_bitmap_next(struct starpu_bitmap *b, int e)
  171. {
  172. int nb_long = e / LONG_BIT;
  173. int nb_bit = e % LONG_BIT;
  174. unsigned long rest = nb_bit == LONG_BIT - 1 ? 0 : (~0ul << (nb_bit + 1)) & b->bits[nb_long];
  175. if(nb_bit != (LONG_BIT - 1) && rest)
  176. {
  177. int i = get_first_bit_rank(rest);
  178. STARPU_ASSERT(i >= 0 && i < LONG_BIT);
  179. return (nb_long * LONG_BIT) + i;
  180. }
  181. for(nb_long++;nb_long < b->size; nb_long++)
  182. if(b->bits[nb_long])
  183. return nb_long * LONG_BIT + get_first_bit_rank(b->bits[nb_long]);
  184. return -1;
  185. }
  186. #ifndef STARPU_NO_ASSERT
  187. static int check_bitmap(struct starpu_bitmap *b)
  188. {
  189. int card = b->cardinal;
  190. int i = starpu_bitmap_first(b);
  191. int j;
  192. for(j = 0; j < card; j++)
  193. {
  194. if(i == -1)
  195. return 0;
  196. int tmp = starpu_bitmap_next(b,i);
  197. if(tmp == i)
  198. return 0;
  199. i = tmp;
  200. }
  201. if(i != -1)
  202. return 0;
  203. return 1;
  204. }
  205. #endif