xfs_bit.c 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. /*
  2. * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved.
  3. *
  4. * This program is free software; you can redistribute it and/or modify it
  5. * under the terms of version 2 of the GNU General Public License as
  6. * published by the Free Software Foundation.
  7. *
  8. * This program is distributed in the hope that it would be useful, but
  9. * WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. *
  12. * Further, this software is distributed without any warranty that it is
  13. * free of the rightful claim of any third person regarding infringement
  14. * or the like. Any license provided herein, whether implied or
  15. * otherwise, applies only to this software file. Patent licenses, if
  16. * any, provided herein do not apply to combinations of this program with
  17. * other software, or any other product whatsoever.
  18. *
  19. * You should have received a copy of the GNU General Public License along
  20. * with this program; if not, write the Free Software Foundation, Inc., 59
  21. * Temple Place - Suite 330, Boston MA 02111-1307, USA.
  22. *
  23. * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
  24. * Mountain View, CA 94043, or:
  25. *
  26. * http://www.sgi.com
  27. *
  28. * For further information regarding this notice, see:
  29. *
  30. * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
  31. */
  32. /*
  33. * XFS bit manipulation routines, used in non-realtime code.
  34. */
  35. #include "xfs.h"
  36. #include "xfs_bit.h"
  37. #include "xfs_log.h"
  38. #include "xfs_trans.h"
  39. #include "xfs_buf_item.h"
  40. #ifndef HAVE_ARCH_HIGHBIT
  41. /*
  42. * Index of high bit number in byte, -1 for none set, 0..7 otherwise.
  43. */
  44. STATIC const char xfs_highbit[256] = {
  45. -1, 0, 1, 1, 2, 2, 2, 2, /* 00 .. 07 */
  46. 3, 3, 3, 3, 3, 3, 3, 3, /* 08 .. 0f */
  47. 4, 4, 4, 4, 4, 4, 4, 4, /* 10 .. 17 */
  48. 4, 4, 4, 4, 4, 4, 4, 4, /* 18 .. 1f */
  49. 5, 5, 5, 5, 5, 5, 5, 5, /* 20 .. 27 */
  50. 5, 5, 5, 5, 5, 5, 5, 5, /* 28 .. 2f */
  51. 5, 5, 5, 5, 5, 5, 5, 5, /* 30 .. 37 */
  52. 5, 5, 5, 5, 5, 5, 5, 5, /* 38 .. 3f */
  53. 6, 6, 6, 6, 6, 6, 6, 6, /* 40 .. 47 */
  54. 6, 6, 6, 6, 6, 6, 6, 6, /* 48 .. 4f */
  55. 6, 6, 6, 6, 6, 6, 6, 6, /* 50 .. 57 */
  56. 6, 6, 6, 6, 6, 6, 6, 6, /* 58 .. 5f */
  57. 6, 6, 6, 6, 6, 6, 6, 6, /* 60 .. 67 */
  58. 6, 6, 6, 6, 6, 6, 6, 6, /* 68 .. 6f */
  59. 6, 6, 6, 6, 6, 6, 6, 6, /* 70 .. 77 */
  60. 6, 6, 6, 6, 6, 6, 6, 6, /* 78 .. 7f */
  61. 7, 7, 7, 7, 7, 7, 7, 7, /* 80 .. 87 */
  62. 7, 7, 7, 7, 7, 7, 7, 7, /* 88 .. 8f */
  63. 7, 7, 7, 7, 7, 7, 7, 7, /* 90 .. 97 */
  64. 7, 7, 7, 7, 7, 7, 7, 7, /* 98 .. 9f */
  65. 7, 7, 7, 7, 7, 7, 7, 7, /* a0 .. a7 */
  66. 7, 7, 7, 7, 7, 7, 7, 7, /* a8 .. af */
  67. 7, 7, 7, 7, 7, 7, 7, 7, /* b0 .. b7 */
  68. 7, 7, 7, 7, 7, 7, 7, 7, /* b8 .. bf */
  69. 7, 7, 7, 7, 7, 7, 7, 7, /* c0 .. c7 */
  70. 7, 7, 7, 7, 7, 7, 7, 7, /* c8 .. cf */
  71. 7, 7, 7, 7, 7, 7, 7, 7, /* d0 .. d7 */
  72. 7, 7, 7, 7, 7, 7, 7, 7, /* d8 .. df */
  73. 7, 7, 7, 7, 7, 7, 7, 7, /* e0 .. e7 */
  74. 7, 7, 7, 7, 7, 7, 7, 7, /* e8 .. ef */
  75. 7, 7, 7, 7, 7, 7, 7, 7, /* f0 .. f7 */
  76. 7, 7, 7, 7, 7, 7, 7, 7, /* f8 .. ff */
  77. };
  78. #endif
  79. /*
  80. * Count of bits set in byte, 0..8.
  81. */
  82. static const char xfs_countbit[256] = {
  83. 0, 1, 1, 2, 1, 2, 2, 3, /* 00 .. 07 */
  84. 1, 2, 2, 3, 2, 3, 3, 4, /* 08 .. 0f */
  85. 1, 2, 2, 3, 2, 3, 3, 4, /* 10 .. 17 */
  86. 2, 3, 3, 4, 3, 4, 4, 5, /* 18 .. 1f */
  87. 1, 2, 2, 3, 2, 3, 3, 4, /* 20 .. 27 */
  88. 2, 3, 3, 4, 3, 4, 4, 5, /* 28 .. 2f */
  89. 2, 3, 3, 4, 3, 4, 4, 5, /* 30 .. 37 */
  90. 3, 4, 4, 5, 4, 5, 5, 6, /* 38 .. 3f */
  91. 1, 2, 2, 3, 2, 3, 3, 4, /* 40 .. 47 */
  92. 2, 3, 3, 4, 3, 4, 4, 5, /* 48 .. 4f */
  93. 2, 3, 3, 4, 3, 4, 4, 5, /* 50 .. 57 */
  94. 3, 4, 4, 5, 4, 5, 5, 6, /* 58 .. 5f */
  95. 2, 3, 3, 4, 3, 4, 4, 5, /* 60 .. 67 */
  96. 3, 4, 4, 5, 4, 5, 5, 6, /* 68 .. 6f */
  97. 3, 4, 4, 5, 4, 5, 5, 6, /* 70 .. 77 */
  98. 4, 5, 5, 6, 5, 6, 6, 7, /* 78 .. 7f */
  99. 1, 2, 2, 3, 2, 3, 3, 4, /* 80 .. 87 */
  100. 2, 3, 3, 4, 3, 4, 4, 5, /* 88 .. 8f */
  101. 2, 3, 3, 4, 3, 4, 4, 5, /* 90 .. 97 */
  102. 3, 4, 4, 5, 4, 5, 5, 6, /* 98 .. 9f */
  103. 2, 3, 3, 4, 3, 4, 4, 5, /* a0 .. a7 */
  104. 3, 4, 4, 5, 4, 5, 5, 6, /* a8 .. af */
  105. 3, 4, 4, 5, 4, 5, 5, 6, /* b0 .. b7 */
  106. 4, 5, 5, 6, 5, 6, 6, 7, /* b8 .. bf */
  107. 2, 3, 3, 4, 3, 4, 4, 5, /* c0 .. c7 */
  108. 3, 4, 4, 5, 4, 5, 5, 6, /* c8 .. cf */
  109. 3, 4, 4, 5, 4, 5, 5, 6, /* d0 .. d7 */
  110. 4, 5, 5, 6, 5, 6, 6, 7, /* d8 .. df */
  111. 3, 4, 4, 5, 4, 5, 5, 6, /* e0 .. e7 */
  112. 4, 5, 5, 6, 5, 6, 6, 7, /* e8 .. ef */
  113. 4, 5, 5, 6, 5, 6, 6, 7, /* f0 .. f7 */
  114. 5, 6, 6, 7, 6, 7, 7, 8, /* f8 .. ff */
  115. };
  116. /*
  117. * xfs_highbit32: get high bit set out of 32-bit argument, -1 if none set.
  118. */
  119. inline int
  120. xfs_highbit32(
  121. __uint32_t v)
  122. {
  123. #ifdef HAVE_ARCH_HIGHBIT
  124. return highbit32(v);
  125. #else
  126. int i;
  127. if (v & 0xffff0000)
  128. if (v & 0xff000000)
  129. i = 24;
  130. else
  131. i = 16;
  132. else if (v & 0x0000ffff)
  133. if (v & 0x0000ff00)
  134. i = 8;
  135. else
  136. i = 0;
  137. else
  138. return -1;
  139. return i + xfs_highbit[(v >> i) & 0xff];
  140. #endif
  141. }
  142. /*
  143. * xfs_lowbit64: get low bit set out of 64-bit argument, -1 if none set.
  144. */
  145. int
  146. xfs_lowbit64(
  147. __uint64_t v)
  148. {
  149. __uint32_t w = (__uint32_t)v;
  150. int n = 0;
  151. if (w) { /* lower bits */
  152. n = ffs(w);
  153. } else { /* upper bits */
  154. w = (__uint32_t)(v >> 32);
  155. if (w && (n = ffs(w)))
  156. n += 32;
  157. }
  158. return n - 1;
  159. }
  160. /*
  161. * xfs_highbit64: get high bit set out of 64-bit argument, -1 if none set.
  162. */
  163. int
  164. xfs_highbit64(
  165. __uint64_t v)
  166. {
  167. __uint32_t h = (__uint32_t)(v >> 32);
  168. if (h)
  169. return xfs_highbit32(h) + 32;
  170. return xfs_highbit32((__uint32_t)v);
  171. }
  172. /*
  173. * Count the number of bits set in the bitmap starting with bit
  174. * start_bit. Size is the size of the bitmap in words.
  175. *
  176. * Do the counting by mapping a byte value to the number of set
  177. * bits for that value using the xfs_countbit array, i.e.
  178. * xfs_countbit[0] == 0, xfs_countbit[1] == 1, xfs_countbit[2] == 1,
  179. * xfs_countbit[3] == 2, etc.
  180. */
  181. int
  182. xfs_count_bits(uint *map, uint size, uint start_bit)
  183. {
  184. register int bits;
  185. register unsigned char *bytep;
  186. register unsigned char *end_map;
  187. int byte_bit;
  188. bits = 0;
  189. end_map = (char*)(map + size);
  190. bytep = (char*)(map + (start_bit & ~0x7));
  191. byte_bit = start_bit & 0x7;
  192. /*
  193. * If the caller fell off the end of the map, return 0.
  194. */
  195. if (bytep >= end_map) {
  196. return (0);
  197. }
  198. /*
  199. * If start_bit is not byte aligned, then process the
  200. * first byte separately.
  201. */
  202. if (byte_bit != 0) {
  203. /*
  204. * Shift off the bits we don't want to look at,
  205. * before indexing into xfs_countbit.
  206. */
  207. bits += xfs_countbit[(*bytep >> byte_bit)];
  208. bytep++;
  209. }
  210. /*
  211. * Count the bits in each byte until the end of the bitmap.
  212. */
  213. while (bytep < end_map) {
  214. bits += xfs_countbit[*bytep];
  215. bytep++;
  216. }
  217. return (bits);
  218. }
  219. /*
  220. * Count the number of contiguous bits set in the bitmap starting with bit
  221. * start_bit. Size is the size of the bitmap in words.
  222. */
  223. int
  224. xfs_contig_bits(uint *map, uint size, uint start_bit)
  225. {
  226. uint * p = ((unsigned int *) map) + (start_bit >> BIT_TO_WORD_SHIFT);
  227. uint result = 0;
  228. uint tmp;
  229. size <<= BIT_TO_WORD_SHIFT;
  230. ASSERT(start_bit < size);
  231. size -= start_bit & ~(NBWORD - 1);
  232. start_bit &= (NBWORD - 1);
  233. if (start_bit) {
  234. tmp = *p++;
  235. /* set to one first offset bits prior to start */
  236. tmp |= (~0U >> (NBWORD-start_bit));
  237. if (tmp != ~0U)
  238. goto found;
  239. result += NBWORD;
  240. size -= NBWORD;
  241. }
  242. while (size) {
  243. if ((tmp = *p++) != ~0U)
  244. goto found;
  245. result += NBWORD;
  246. size -= NBWORD;
  247. }
  248. return result - start_bit;
  249. found:
  250. return result + ffz(tmp) - start_bit;
  251. }
  252. /*
  253. * This takes the bit number to start looking from and
  254. * returns the next set bit from there. It returns -1
  255. * if there are no more bits set or the start bit is
  256. * beyond the end of the bitmap.
  257. *
  258. * Size is the number of words, not bytes, in the bitmap.
  259. */
  260. int xfs_next_bit(uint *map, uint size, uint start_bit)
  261. {
  262. uint * p = ((unsigned int *) map) + (start_bit >> BIT_TO_WORD_SHIFT);
  263. uint result = start_bit & ~(NBWORD - 1);
  264. uint tmp;
  265. size <<= BIT_TO_WORD_SHIFT;
  266. if (start_bit >= size)
  267. return -1;
  268. size -= result;
  269. start_bit &= (NBWORD - 1);
  270. if (start_bit) {
  271. tmp = *p++;
  272. /* set to zero first offset bits prior to start */
  273. tmp &= (~0U << start_bit);
  274. if (tmp != 0U)
  275. goto found;
  276. result += NBWORD;
  277. size -= NBWORD;
  278. }
  279. while (size) {
  280. if ((tmp = *p++) != 0U)
  281. goto found;
  282. result += NBWORD;
  283. size -= NBWORD;
  284. }
  285. return -1;
  286. found:
  287. return result + ffs(tmp) - 1;
  288. }