find_bit.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /* bit search implementation
  3. *
  4. * Copied from lib/find_bit.c to tools/lib/find_bit.c
  5. *
  6. * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
  7. * Written by David Howells ([email protected])
  8. *
  9. * Copyright (C) 2008 IBM Corporation
  10. * 'find_last_bit' is written by Rusty Russell <[email protected]>
  11. * (Inspired by David Howell's find_next_bit implementation)
  12. *
  13. * Rewritten by Yury Norov <[email protected]> to decrease
  14. * size and improve performance, 2015.
  15. */
  16. #include <linux/bitops.h>
  17. #include <linux/bitmap.h>
  18. #include <linux/kernel.h>
  19. /*
  20. * Common helper for find_bit() function family
  21. * @FETCH: The expression that fetches and pre-processes each word of bitmap(s)
  22. * @MUNGE: The expression that post-processes a word containing found bit (may be empty)
  23. * @size: The bitmap size in bits
  24. */
  25. #define FIND_FIRST_BIT(FETCH, MUNGE, size) \
  26. ({ \
  27. unsigned long idx, val, sz = (size); \
  28. \
  29. for (idx = 0; idx * BITS_PER_LONG < sz; idx++) { \
  30. val = (FETCH); \
  31. if (val) { \
  32. sz = min(idx * BITS_PER_LONG + __ffs(MUNGE(val)), sz); \
  33. break; \
  34. } \
  35. } \
  36. \
  37. sz; \
  38. })
  39. /*
  40. * Common helper for find_next_bit() function family
  41. * @FETCH: The expression that fetches and pre-processes each word of bitmap(s)
  42. * @MUNGE: The expression that post-processes a word containing found bit (may be empty)
  43. * @size: The bitmap size in bits
  44. * @start: The bitnumber to start searching at
  45. */
  46. #define FIND_NEXT_BIT(FETCH, MUNGE, size, start) \
  47. ({ \
  48. unsigned long mask, idx, tmp, sz = (size), __start = (start); \
  49. \
  50. if (unlikely(__start >= sz)) \
  51. goto out; \
  52. \
  53. mask = MUNGE(BITMAP_FIRST_WORD_MASK(__start)); \
  54. idx = __start / BITS_PER_LONG; \
  55. \
  56. for (tmp = (FETCH) & mask; !tmp; tmp = (FETCH)) { \
  57. if ((idx + 1) * BITS_PER_LONG >= sz) \
  58. goto out; \
  59. idx++; \
  60. } \
  61. \
  62. sz = min(idx * BITS_PER_LONG + __ffs(MUNGE(tmp)), sz); \
  63. out: \
  64. sz; \
  65. })
  66. #ifndef find_first_bit
  67. /*
  68. * Find the first set bit in a memory region.
  69. */
  70. unsigned long _find_first_bit(const unsigned long *addr, unsigned long size)
  71. {
  72. return FIND_FIRST_BIT(addr[idx], /* nop */, size);
  73. }
  74. #endif
  75. #ifndef find_first_and_bit
  76. /*
  77. * Find the first set bit in two memory regions.
  78. */
  79. unsigned long _find_first_and_bit(const unsigned long *addr1,
  80. const unsigned long *addr2,
  81. unsigned long size)
  82. {
  83. return FIND_FIRST_BIT(addr1[idx] & addr2[idx], /* nop */, size);
  84. }
  85. #endif
  86. #ifndef find_first_zero_bit
  87. /*
  88. * Find the first cleared bit in a memory region.
  89. */
  90. unsigned long _find_first_zero_bit(const unsigned long *addr, unsigned long size)
  91. {
  92. return FIND_FIRST_BIT(~addr[idx], /* nop */, size);
  93. }
  94. #endif
  95. #ifndef find_next_bit
  96. unsigned long _find_next_bit(const unsigned long *addr, unsigned long nbits, unsigned long start)
  97. {
  98. return FIND_NEXT_BIT(addr[idx], /* nop */, nbits, start);
  99. }
  100. #endif
  101. #ifndef find_next_and_bit
  102. unsigned long _find_next_and_bit(const unsigned long *addr1, const unsigned long *addr2,
  103. unsigned long nbits, unsigned long start)
  104. {
  105. return FIND_NEXT_BIT(addr1[idx] & addr2[idx], /* nop */, nbits, start);
  106. }
  107. #endif
  108. #ifndef find_next_zero_bit
  109. unsigned long _find_next_zero_bit(const unsigned long *addr, unsigned long nbits,
  110. unsigned long start)
  111. {
  112. return FIND_NEXT_BIT(~addr[idx], /* nop */, nbits, start);
  113. }
  114. #endif