Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

tools: sync find_bit() implementation

Sync find_first_bit() and find_next_bit() implementation with the
mother kernel.

Also, drop unused find_last_bit() and find_next_clump8().

Signed-off-by: Yury Norov <yury.norov@gmail.com>

+81 -129
+12 -49
tools/include/linux/find.h
··· 8 8 9 9 #include <linux/bitops.h> 10 10 11 - extern unsigned long _find_next_bit(const unsigned long *addr1, 12 - const unsigned long *addr2, unsigned long nbits, 13 - unsigned long start, unsigned long invert, unsigned long le); 11 + unsigned long _find_next_bit(const unsigned long *addr1, unsigned long nbits, 12 + unsigned long start); 13 + unsigned long _find_next_and_bit(const unsigned long *addr1, const unsigned long *addr2, 14 + unsigned long nbits, unsigned long start); 15 + unsigned long _find_next_zero_bit(const unsigned long *addr, unsigned long nbits, 16 + unsigned long start); 14 17 extern unsigned long _find_first_bit(const unsigned long *addr, unsigned long size); 15 18 extern unsigned long _find_first_and_bit(const unsigned long *addr1, 16 19 const unsigned long *addr2, unsigned long size); 17 20 extern unsigned long _find_first_zero_bit(const unsigned long *addr, unsigned long size); 18 - extern unsigned long _find_last_bit(const unsigned long *addr, unsigned long size); 19 21 20 22 #ifndef find_next_bit 21 23 /** 22 24 * find_next_bit - find the next set bit in a memory region 23 25 * @addr: The address to base the search on 24 - * @offset: The bitnumber to start searching at 25 26 * @size: The bitmap size in bits 27 + * @offset: The bitnumber to start searching at 26 28 * 27 29 * Returns the bit number for the next set bit 28 30 * If no bits are set, returns @size. ··· 43 41 return val ? __ffs(val) : size; 44 42 } 45 43 46 - return _find_next_bit(addr, NULL, size, offset, 0UL, 0); 44 + return _find_next_bit(addr, size, offset); 47 45 } 48 46 #endif 49 47 ··· 52 50 * find_next_and_bit - find the next set bit in both memory regions 53 51 * @addr1: The first address to base the search on 54 52 * @addr2: The second address to base the search on 55 - * @offset: The bitnumber to start searching at 56 53 * @size: The bitmap size in bits 54 + * @offset: The bitnumber to start searching at 57 55 * 58 56 * Returns the bit number for the next set bit 59 57 * If no bits are set, returns @size. ··· 73 71 return val ? __ffs(val) : size; 74 72 } 75 73 76 - return _find_next_bit(addr1, addr2, size, offset, 0UL, 0); 74 + return _find_next_and_bit(addr1, addr2, size, offset); 77 75 } 78 76 #endif 79 77 ··· 81 79 /** 82 80 * find_next_zero_bit - find the next cleared bit in a memory region 83 81 * @addr: The address to base the search on 84 - * @offset: The bitnumber to start searching at 85 82 * @size: The bitmap size in bits 83 + * @offset: The bitnumber to start searching at 86 84 * 87 85 * Returns the bit number of the next zero bit 88 86 * If no bits are zero, returns @size. ··· 101 99 return val == ~0UL ? size : ffz(val); 102 100 } 103 101 104 - return _find_next_bit(addr, NULL, size, offset, ~0UL, 0); 102 + return _find_next_zero_bit(addr, size, offset); 105 103 } 106 104 #endif 107 105 ··· 173 171 return _find_first_zero_bit(addr, size); 174 172 } 175 173 #endif 176 - 177 - #ifndef find_last_bit 178 - /** 179 - * find_last_bit - find the last set bit in a memory region 180 - * @addr: The address to start the search at 181 - * @size: The number of bits to search 182 - * 183 - * Returns the bit number of the last set bit, or size. 184 - */ 185 - static inline 186 - unsigned long find_last_bit(const unsigned long *addr, unsigned long size) 187 - { 188 - if (small_const_nbits(size)) { 189 - unsigned long val = *addr & GENMASK(size - 1, 0); 190 - 191 - return val ? __fls(val) : size; 192 - } 193 - 194 - return _find_last_bit(addr, size); 195 - } 196 - #endif 197 - 198 - /** 199 - * find_next_clump8 - find next 8-bit clump with set bits in a memory region 200 - * @clump: location to store copy of found clump 201 - * @addr: address to base the search on 202 - * @size: bitmap size in number of bits 203 - * @offset: bit offset at which to start searching 204 - * 205 - * Returns the bit offset for the next set clump; the found clump value is 206 - * copied to the location pointed by @clump. If no bits are set, returns @size. 207 - */ 208 - extern unsigned long find_next_clump8(unsigned long *clump, 209 - const unsigned long *addr, 210 - unsigned long size, unsigned long offset); 211 - 212 - #define find_first_clump8(clump, bits, size) \ 213 - find_next_clump8((clump), (bits), (size), 0) 214 - 215 174 216 175 #endif /*__LINUX_FIND_H_ */
+69 -80
tools/lib/find_bit.c
··· 18 18 #include <linux/bitmap.h> 19 19 #include <linux/kernel.h> 20 20 21 - #if !defined(find_next_bit) || !defined(find_next_zero_bit) || \ 22 - !defined(find_next_and_bit) 21 + /* 22 + * Common helper for find_bit() function family 23 + * @FETCH: The expression that fetches and pre-processes each word of bitmap(s) 24 + * @MUNGE: The expression that post-processes a word containing found bit (may be empty) 25 + * @size: The bitmap size in bits 26 + */ 27 + #define FIND_FIRST_BIT(FETCH, MUNGE, size) \ 28 + ({ \ 29 + unsigned long idx, val, sz = (size); \ 30 + \ 31 + for (idx = 0; idx * BITS_PER_LONG < sz; idx++) { \ 32 + val = (FETCH); \ 33 + if (val) { \ 34 + sz = min(idx * BITS_PER_LONG + __ffs(MUNGE(val)), sz); \ 35 + break; \ 36 + } \ 37 + } \ 38 + \ 39 + sz; \ 40 + }) 23 41 24 42 /* 25 - * This is a common helper function for find_next_bit, find_next_zero_bit, and 26 - * find_next_and_bit. The differences are: 27 - * - The "invert" argument, which is XORed with each fetched word before 28 - * searching it for one bits. 29 - * - The optional "addr2", which is anded with "addr1" if present. 43 + * Common helper for find_next_bit() function family 44 + * @FETCH: The expression that fetches and pre-processes each word of bitmap(s) 45 + * @MUNGE: The expression that post-processes a word containing found bit (may be empty) 46 + * @size: The bitmap size in bits 47 + * @start: The bitnumber to start searching at 30 48 */ 31 - unsigned long _find_next_bit(const unsigned long *addr1, 32 - const unsigned long *addr2, unsigned long nbits, 33 - unsigned long start, unsigned long invert, unsigned long le) 34 - { 35 - unsigned long tmp, mask; 36 - (void) le; 37 - 38 - if (unlikely(start >= nbits)) 39 - return nbits; 40 - 41 - tmp = addr1[start / BITS_PER_LONG]; 42 - if (addr2) 43 - tmp &= addr2[start / BITS_PER_LONG]; 44 - tmp ^= invert; 45 - 46 - /* Handle 1st word. */ 47 - mask = BITMAP_FIRST_WORD_MASK(start); 48 - 49 - /* 50 - * Due to the lack of swab() in tools, and the fact that it doesn't 51 - * need little-endian support, just comment it out 52 - */ 53 - #if (0) 54 - if (le) 55 - mask = swab(mask); 56 - #endif 57 - 58 - tmp &= mask; 59 - 60 - start = round_down(start, BITS_PER_LONG); 61 - 62 - while (!tmp) { 63 - start += BITS_PER_LONG; 64 - if (start >= nbits) 65 - return nbits; 66 - 67 - tmp = addr1[start / BITS_PER_LONG]; 68 - if (addr2) 69 - tmp &= addr2[start / BITS_PER_LONG]; 70 - tmp ^= invert; 71 - } 72 - 73 - #if (0) 74 - if (le) 75 - tmp = swab(tmp); 76 - #endif 77 - 78 - return min(start + __ffs(tmp), nbits); 79 - } 80 - #endif 49 + #define FIND_NEXT_BIT(FETCH, MUNGE, size, start) \ 50 + ({ \ 51 + unsigned long mask, idx, tmp, sz = (size), __start = (start); \ 52 + \ 53 + if (unlikely(__start >= sz)) \ 54 + goto out; \ 55 + \ 56 + mask = MUNGE(BITMAP_FIRST_WORD_MASK(__start)); \ 57 + idx = __start / BITS_PER_LONG; \ 58 + \ 59 + for (tmp = (FETCH) & mask; !tmp; tmp = (FETCH)) { \ 60 + if ((idx + 1) * BITS_PER_LONG >= sz) \ 61 + goto out; \ 62 + idx++; \ 63 + } \ 64 + \ 65 + sz = min(idx * BITS_PER_LONG + __ffs(MUNGE(tmp)), sz); \ 66 + out: \ 67 + sz; \ 68 + }) 81 69 82 70 #ifndef find_first_bit 83 71 /* ··· 73 85 */ 74 86 unsigned long _find_first_bit(const unsigned long *addr, unsigned long size) 75 87 { 76 - unsigned long idx; 77 - 78 - for (idx = 0; idx * BITS_PER_LONG < size; idx++) { 79 - if (addr[idx]) 80 - return min(idx * BITS_PER_LONG + __ffs(addr[idx]), size); 81 - } 82 - 83 - return size; 88 + return FIND_FIRST_BIT(addr[idx], /* nop */, size); 84 89 } 85 90 #endif 86 91 ··· 85 104 const unsigned long *addr2, 86 105 unsigned long size) 87 106 { 88 - unsigned long idx, val; 89 - 90 - for (idx = 0; idx * BITS_PER_LONG < size; idx++) { 91 - val = addr1[idx] & addr2[idx]; 92 - if (val) 93 - return min(idx * BITS_PER_LONG + __ffs(val), size); 94 - } 95 - 96 - return size; 107 + return FIND_FIRST_BIT(addr1[idx] & addr2[idx], /* nop */, size); 97 108 } 98 109 #endif 99 110 ··· 95 122 */ 96 123 unsigned long _find_first_zero_bit(const unsigned long *addr, unsigned long size) 97 124 { 98 - unsigned long idx; 125 + return FIND_FIRST_BIT(~addr[idx], /* nop */, size); 126 + } 127 + #endif 99 128 100 - for (idx = 0; idx * BITS_PER_LONG < size; idx++) { 101 - if (addr[idx] != ~0UL) 102 - return min(idx * BITS_PER_LONG + ffz(addr[idx]), size); 103 - } 129 + #ifndef find_next_bit 130 + unsigned long _find_next_bit(const unsigned long *addr, unsigned long nbits, unsigned long start) 131 + { 132 + return FIND_NEXT_BIT(addr[idx], /* nop */, nbits, start); 133 + } 134 + #endif 104 135 105 - return size; 136 + #ifndef find_next_and_bit 137 + unsigned long _find_next_and_bit(const unsigned long *addr1, const unsigned long *addr2, 138 + unsigned long nbits, unsigned long start) 139 + { 140 + return FIND_NEXT_BIT(addr1[idx] & addr2[idx], /* nop */, nbits, start); 141 + } 142 + #endif 143 + 144 + #ifndef find_next_zero_bit 145 + unsigned long _find_next_zero_bit(const unsigned long *addr, unsigned long nbits, 146 + unsigned long start) 147 + { 148 + return FIND_NEXT_BIT(~addr[idx], /* nop */, nbits, start); 106 149 } 107 150 #endif