find_bit.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. #include <linux/bitops.h>
  2. /**
  3. * find_next_bit - find the next set bit in a memory region
  4. * @addr: The address to base the search on
  5. * @offset: The bitnumber to start searching at
  6. * @size: The maximum size to search
  7. */
  8. unsigned long find_next_bit(const unsigned long *addr, unsigned long size,
  9. unsigned long offset)
  10. {
  11. const unsigned long *p = addr + (offset >> 6);
  12. unsigned long result = offset & ~63UL;
  13. unsigned long tmp;
  14. if (offset >= size)
  15. return size;
  16. size -= result;
  17. offset &= 63UL;
  18. if (offset) {
  19. tmp = *(p++);
  20. tmp &= (~0UL << offset);
  21. if (size < 64)
  22. goto found_first;
  23. if (tmp)
  24. goto found_middle;
  25. size -= 64;
  26. result += 64;
  27. }
  28. while (size & ~63UL) {
  29. if ((tmp = *(p++)))
  30. goto found_middle;
  31. result += 64;
  32. size -= 64;
  33. }
  34. if (!size)
  35. return result;
  36. tmp = *p;
  37. found_first:
  38. tmp &= (~0UL >> (64 - size));
  39. if (tmp == 0UL) /* Are any bits set? */
  40. return result + size; /* Nope. */
  41. found_middle:
  42. return result + __ffs(tmp);
  43. }
  44. /* find_next_zero_bit() finds the first zero bit in a bit string of length
  45. * 'size' bits, starting the search at bit 'offset'. This is largely based
  46. * on Linus's ALPHA routines, which are pretty portable BTW.
  47. */
  48. unsigned long find_next_zero_bit(const unsigned long *addr,
  49. unsigned long size, unsigned long offset)
  50. {
  51. const unsigned long *p = addr + (offset >> 6);
  52. unsigned long result = offset & ~63UL;
  53. unsigned long tmp;
  54. if (offset >= size)
  55. return size;
  56. size -= result;
  57. offset &= 63UL;
  58. if (offset) {
  59. tmp = *(p++);
  60. tmp |= ~0UL >> (64-offset);
  61. if (size < 64)
  62. goto found_first;
  63. if (~tmp)
  64. goto found_middle;
  65. size -= 64;
  66. result += 64;
  67. }
  68. while (size & ~63UL) {
  69. if (~(tmp = *(p++)))
  70. goto found_middle;
  71. result += 64;
  72. size -= 64;
  73. }
  74. if (!size)
  75. return result;
  76. tmp = *p;
  77. found_first:
  78. tmp |= ~0UL << size;
  79. if (tmp == ~0UL) /* Are any bits zero? */
  80. return result + size; /* Nope. */
  81. found_middle:
  82. return result + ffz(tmp);
  83. }
  84. unsigned long find_next_zero_le_bit(unsigned long *addr, unsigned long size, unsigned long offset)
  85. {
  86. unsigned long *p = addr + (offset >> 6);
  87. unsigned long result = offset & ~63UL;
  88. unsigned long tmp;
  89. if (offset >= size)
  90. return size;
  91. size -= result;
  92. offset &= 63UL;
  93. if(offset) {
  94. tmp = __swab64p(p++);
  95. tmp |= (~0UL >> (64-offset));
  96. if(size < 64)
  97. goto found_first;
  98. if(~tmp)
  99. goto found_middle;
  100. size -= 64;
  101. result += 64;
  102. }
  103. while(size & ~63) {
  104. if(~(tmp = __swab64p(p++)))
  105. goto found_middle;
  106. result += 64;
  107. size -= 64;
  108. }
  109. if(!size)
  110. return result;
  111. tmp = __swab64p(p);
  112. found_first:
  113. tmp |= (~0UL << size);
  114. if (tmp == ~0UL) /* Are any bits zero? */
  115. return result + size; /* Nope. */
  116. found_middle:
  117. return result + ffz(tmp);
  118. }