@@ -211,46 +211,76 @@ bool sbitmap_any_bit_set(const struct sbitmap *sb);
211
211
*/
212
212
bool sbitmap_any_bit_clear (const struct sbitmap * sb );
213
213
214
+ #define SB_NR_TO_INDEX (sb , bitnr ) ((bitnr) >> (sb)->shift)
215
+ #define SB_NR_TO_BIT (sb , bitnr ) ((bitnr) & ((1U << (sb)->shift) - 1U))
216
+
214
217
typedef bool (* sb_for_each_fn )(struct sbitmap * , unsigned int , void * );
215
218
216
219
/**
217
- * sbitmap_for_each_set() - Iterate over each set bit in a &struct sbitmap.
220
+ * __sbitmap_for_each_set() - Iterate over each set bit in a &struct sbitmap.
221
+ * @start: Where to start the iteration.
218
222
* @sb: Bitmap to iterate over.
219
223
* @fn: Callback. Should return true to continue or false to break early.
220
224
* @data: Pointer to pass to callback.
221
225
*
222
226
* This is inline even though it's non-trivial so that the function calls to the
223
227
* callback will hopefully get optimized away.
224
228
*/
225
- static inline void sbitmap_for_each_set (struct sbitmap * sb , sb_for_each_fn fn ,
226
- void * data )
229
+ static inline void __sbitmap_for_each_set (struct sbitmap * sb ,
230
+ unsigned int start ,
231
+ sb_for_each_fn fn , void * data )
227
232
{
228
- unsigned int i ;
233
+ unsigned int index ;
234
+ unsigned int nr ;
235
+ unsigned int scanned = 0 ;
229
236
230
- for (i = 0 ; i < sb -> map_nr ; i ++ ) {
231
- struct sbitmap_word * word = & sb -> map [i ];
232
- unsigned int off , nr ;
237
+ if (start >= sb -> depth )
238
+ start = 0 ;
239
+ index = SB_NR_TO_INDEX (sb , start );
240
+ nr = SB_NR_TO_BIT (sb , start );
233
241
234
- if (!word -> word )
235
- continue ;
242
+ while (scanned < sb -> depth ) {
243
+ struct sbitmap_word * word = & sb -> map [index ];
244
+ unsigned int depth = min_t (unsigned int , word -> depth - nr ,
245
+ sb -> depth - scanned );
236
246
237
- nr = 0 ;
238
- off = i << sb -> shift ;
247
+ scanned += depth ;
248
+ if (!word -> word )
249
+ goto next ;
250
+
251
+ /*
252
+ * On the first iteration of the outer loop, we need to add the
253
+ * bit offset back to the size of the word for find_next_bit().
254
+ * On all other iterations, nr is zero, so this is a noop.
255
+ */
256
+ depth += nr ;
239
257
while (1 ) {
240
- nr = find_next_bit (& word -> word , word -> depth , nr );
241
- if (nr >= word -> depth )
258
+ nr = find_next_bit (& word -> word , depth , nr );
259
+ if (nr >= depth )
242
260
break ;
243
-
244
- if (!fn (sb , off + nr , data ))
261
+ if (!fn (sb , (index << sb -> shift ) + nr , data ))
245
262
return ;
246
263
247
264
nr ++ ;
248
265
}
266
+ next :
267
+ nr = 0 ;
268
+ if (++ index >= sb -> map_nr )
269
+ index = 0 ;
249
270
}
250
271
}
251
272
252
- #define SB_NR_TO_INDEX (sb , bitnr ) ((bitnr) >> (sb)->shift)
253
- #define SB_NR_TO_BIT (sb , bitnr ) ((bitnr) & ((1U << (sb)->shift) - 1U))
273
+ /**
274
+ * sbitmap_for_each_set() - Iterate over each set bit in a &struct sbitmap.
275
+ * @sb: Bitmap to iterate over.
276
+ * @fn: Callback. Should return true to continue or false to break early.
277
+ * @data: Pointer to pass to callback.
278
+ */
279
+ static inline void sbitmap_for_each_set (struct sbitmap * sb , sb_for_each_fn fn ,
280
+ void * data )
281
+ {
282
+ __sbitmap_for_each_set (sb , 0 , fn , data );
283
+ }
254
284
255
285
static inline unsigned long * __sbitmap_word (struct sbitmap * sb ,
256
286
unsigned int bitnr )
0 commit comments