Line data Source code
1 : // SPDX-License-Identifier: GPL-2.0-or-later
2 : /* bit search implementation
3 : *
4 : * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
5 : * Written by David Howells (dhowells@redhat.com)
6 : *
7 : * Copyright (C) 2008 IBM Corporation
8 : * 'find_last_bit' is written by Rusty Russell <rusty@rustcorp.com.au>
9 : * (Inspired by David Howell's find_next_bit implementation)
10 : *
11 : * Rewritten by Yury Norov <yury.norov@gmail.com> to decrease
12 : * size and improve performance, 2015.
13 : */
14 :
15 : #include <linux/bitops.h>
16 : #include <linux/bitmap.h>
17 : #include <linux/export.h>
18 : #include <linux/math.h>
19 : #include <linux/minmax.h>
20 : #include <linux/swab.h>
21 :
22 : /*
23 : * Common helper for find_bit() function family
24 : * @FETCH: The expression that fetches and pre-processes each word of bitmap(s)
25 : * @MUNGE: The expression that post-processes a word containing found bit (may be empty)
26 : * @size: The bitmap size in bits
27 : */
28 : #define FIND_FIRST_BIT(FETCH, MUNGE, size) \
29 : ({ \
30 : unsigned long idx, val, sz = (size); \
31 : \
32 : for (idx = 0; idx * BITS_PER_LONG < sz; idx++) { \
33 : val = (FETCH); \
34 : if (val) { \
35 : sz = min(idx * BITS_PER_LONG + __ffs(MUNGE(val)), sz); \
36 : break; \
37 : } \
38 : } \
39 : \
40 : sz; \
41 : })
42 :
43 : /*
44 : * Common helper for find_next_bit() function family
45 : * @FETCH: The expression that fetches and pre-processes each word of bitmap(s)
46 : * @MUNGE: The expression that post-processes a word containing found bit (may be empty)
47 : * @size: The bitmap size in bits
48 : * @start: The bitnumber to start searching at
49 : */
50 : #define FIND_NEXT_BIT(FETCH, MUNGE, size, start) \
51 : ({ \
52 : unsigned long mask, idx, tmp, sz = (size), __start = (start); \
53 : \
54 : if (unlikely(__start >= sz)) \
55 : goto out; \
56 : \
57 : mask = MUNGE(BITMAP_FIRST_WORD_MASK(__start)); \
58 : idx = __start / BITS_PER_LONG; \
59 : \
60 : for (tmp = (FETCH) & mask; !tmp; tmp = (FETCH)) { \
61 : if ((idx + 1) * BITS_PER_LONG >= sz) \
62 : goto out; \
63 : idx++; \
64 : } \
65 : \
66 : sz = min(idx * BITS_PER_LONG + __ffs(MUNGE(tmp)), sz); \
67 : out: \
68 : sz; \
69 : })
70 :
71 : #define FIND_NTH_BIT(FETCH, size, num) \
72 : ({ \
73 : unsigned long sz = (size), nr = (num), idx, w, tmp; \
74 : \
75 : for (idx = 0; (idx + 1) * BITS_PER_LONG <= sz; idx++) { \
76 : if (idx * BITS_PER_LONG + nr >= sz) \
77 : goto out; \
78 : \
79 : tmp = (FETCH); \
80 : w = hweight_long(tmp); \
81 : if (w > nr) \
82 : goto found; \
83 : \
84 : nr -= w; \
85 : } \
86 : \
87 : if (sz % BITS_PER_LONG) \
88 : tmp = (FETCH) & BITMAP_LAST_WORD_MASK(sz); \
89 : found: \
90 : sz = min(idx * BITS_PER_LONG + fns(tmp, nr), sz); \
91 : out: \
92 : sz; \
93 : })
94 :
95 : #ifndef find_first_bit
96 : /*
97 : * Find the first set bit in a memory region.
98 : */
99 0 : unsigned long _find_first_bit(const unsigned long *addr, unsigned long size)
100 : {
101 0 : return FIND_FIRST_BIT(addr[idx], /* nop */, size);
102 : }
103 : EXPORT_SYMBOL(_find_first_bit);
104 : #endif
105 :
106 : #ifndef find_first_and_bit
107 : /*
108 : * Find the first set bit in two memory regions.
109 : */
110 0 : unsigned long _find_first_and_bit(const unsigned long *addr1,
111 : const unsigned long *addr2,
112 : unsigned long size)
113 : {
114 0 : return FIND_FIRST_BIT(addr1[idx] & addr2[idx], /* nop */, size);
115 : }
116 : EXPORT_SYMBOL(_find_first_and_bit);
117 : #endif
118 :
119 : #ifndef find_first_zero_bit
120 : /*
121 : * Find the first cleared bit in a memory region.
122 : */
123 120 : unsigned long _find_first_zero_bit(const unsigned long *addr, unsigned long size)
124 : {
125 240 : return FIND_FIRST_BIT(~addr[idx], /* nop */, size);
126 : }
127 : EXPORT_SYMBOL(_find_first_zero_bit);
128 : #endif
129 :
130 : #ifndef find_next_bit
131 911 : unsigned long _find_next_bit(const unsigned long *addr, unsigned long nbits, unsigned long start)
132 : {
133 966 : return FIND_NEXT_BIT(addr[idx], /* nop */, nbits, start);
134 : }
135 : EXPORT_SYMBOL(_find_next_bit);
136 : #endif
137 :
138 0 : unsigned long __find_nth_bit(const unsigned long *addr, unsigned long size, unsigned long n)
139 : {
140 0 : return FIND_NTH_BIT(addr[idx], size, n);
141 : }
142 : EXPORT_SYMBOL(__find_nth_bit);
143 :
144 0 : unsigned long __find_nth_and_bit(const unsigned long *addr1, const unsigned long *addr2,
145 : unsigned long size, unsigned long n)
146 : {
147 0 : return FIND_NTH_BIT(addr1[idx] & addr2[idx], size, n);
148 : }
149 : EXPORT_SYMBOL(__find_nth_and_bit);
150 :
151 0 : unsigned long __find_nth_andnot_bit(const unsigned long *addr1, const unsigned long *addr2,
152 : unsigned long size, unsigned long n)
153 : {
154 0 : return FIND_NTH_BIT(addr1[idx] & ~addr2[idx], size, n);
155 : }
156 : EXPORT_SYMBOL(__find_nth_andnot_bit);
157 :
158 0 : unsigned long __find_nth_and_andnot_bit(const unsigned long *addr1,
159 : const unsigned long *addr2,
160 : const unsigned long *addr3,
161 : unsigned long size, unsigned long n)
162 : {
163 0 : return FIND_NTH_BIT(addr1[idx] & addr2[idx] & ~addr3[idx], size, n);
164 : }
165 : EXPORT_SYMBOL(__find_nth_and_andnot_bit);
166 :
167 : #ifndef find_next_and_bit
168 0 : unsigned long _find_next_and_bit(const unsigned long *addr1, const unsigned long *addr2,
169 : unsigned long nbits, unsigned long start)
170 : {
171 0 : return FIND_NEXT_BIT(addr1[idx] & addr2[idx], /* nop */, nbits, start);
172 : }
173 : EXPORT_SYMBOL(_find_next_and_bit);
174 : #endif
175 :
176 : #ifndef find_next_andnot_bit
177 0 : unsigned long _find_next_andnot_bit(const unsigned long *addr1, const unsigned long *addr2,
178 : unsigned long nbits, unsigned long start)
179 : {
180 0 : return FIND_NEXT_BIT(addr1[idx] & ~addr2[idx], /* nop */, nbits, start);
181 : }
182 : EXPORT_SYMBOL(_find_next_andnot_bit);
183 : #endif
184 :
185 : #ifndef find_next_or_bit
186 0 : unsigned long _find_next_or_bit(const unsigned long *addr1, const unsigned long *addr2,
187 : unsigned long nbits, unsigned long start)
188 : {
189 0 : return FIND_NEXT_BIT(addr1[idx] | addr2[idx], /* nop */, nbits, start);
190 : }
191 : EXPORT_SYMBOL(_find_next_or_bit);
192 : #endif
193 :
194 : #ifndef find_next_zero_bit
195 1402 : unsigned long _find_next_zero_bit(const unsigned long *addr, unsigned long nbits,
196 : unsigned long start)
197 : {
198 2375 : return FIND_NEXT_BIT(~addr[idx], /* nop */, nbits, start);
199 : }
200 : EXPORT_SYMBOL(_find_next_zero_bit);
201 : #endif
202 :
203 : #ifndef find_last_bit
204 16 : unsigned long _find_last_bit(const unsigned long *addr, unsigned long size)
205 : {
206 16 : if (size) {
207 16 : unsigned long val = BITMAP_LAST_WORD_MASK(size);
208 16 : unsigned long idx = (size-1) / BITS_PER_LONG;
209 :
210 : do {
211 16 : val &= addr[idx];
212 16 : if (val)
213 32 : return idx * BITS_PER_LONG + __fls(val);
214 :
215 0 : val = ~0ul;
216 0 : } while (idx--);
217 : }
218 : return size;
219 : }
220 : EXPORT_SYMBOL(_find_last_bit);
221 : #endif
222 :
223 0 : unsigned long find_next_clump8(unsigned long *clump, const unsigned long *addr,
224 : unsigned long size, unsigned long offset)
225 : {
226 0 : offset = find_next_bit(addr, size, offset);
227 0 : if (offset == size)
228 : return size;
229 :
230 0 : offset = round_down(offset, 8);
231 0 : *clump = bitmap_get_value8(addr, offset);
232 :
233 0 : return offset;
234 : }
235 : EXPORT_SYMBOL(find_next_clump8);
236 :
237 : #ifdef __BIG_ENDIAN
238 :
239 : #ifndef find_first_zero_bit_le
240 : /*
241 : * Find the first cleared bit in an LE memory region.
242 : */
243 : unsigned long _find_first_zero_bit_le(const unsigned long *addr, unsigned long size)
244 : {
245 : return FIND_FIRST_BIT(~addr[idx], swab, size);
246 : }
247 : EXPORT_SYMBOL(_find_first_zero_bit_le);
248 :
249 : #endif
250 :
251 : #ifndef find_next_zero_bit_le
252 : unsigned long _find_next_zero_bit_le(const unsigned long *addr,
253 : unsigned long size, unsigned long offset)
254 : {
255 : return FIND_NEXT_BIT(~addr[idx], swab, size, offset);
256 : }
257 : EXPORT_SYMBOL(_find_next_zero_bit_le);
258 : #endif
259 :
260 : #ifndef find_next_bit_le
261 : unsigned long _find_next_bit_le(const unsigned long *addr,
262 : unsigned long size, unsigned long offset)
263 : {
264 : return FIND_NEXT_BIT(addr[idx], swab, size, offset);
265 : }
266 : EXPORT_SYMBOL(_find_next_bit_le);
267 :
268 : #endif
269 :
270 : #endif /* __BIG_ENDIAN */
|