Skip to content

Commit 4fe49b3

Browse files
committed
lib/bitmap: introduce for_each_set_bit_wrap() macro
Add for_each_set_bit_wrap() macro and use it in for_each_cpu_wrap(). The new macro is based on __for_each_wrap() iterator, which is simpler and smaller than cpumask_next_wrap(). Signed-off-by: Yury Norov <[email protected]>
1 parent 6cc1833 commit 4fe49b3

File tree

2 files changed

+41
-4
lines changed

2 files changed

+41
-4
lines changed

include/linux/cpumask.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -289,10 +289,8 @@ unsigned int __pure cpumask_next_wrap(int n, const struct cpumask *mask, int sta
289289
*
290290
* After the loop, cpu is >= nr_cpu_ids.
291291
*/
292-
#define for_each_cpu_wrap(cpu, mask, start) \
293-
for ((cpu) = cpumask_next_wrap((start)-1, (mask), (start), false); \
294-
(cpu) < nr_cpumask_bits; \
295-
(cpu) = cpumask_next_wrap((cpu), (mask), (start), true))
292+
#define for_each_cpu_wrap(cpu, mask, start) \
293+
for_each_set_bit_wrap(cpu, cpumask_bits(mask), nr_cpumask_bits, start)
296294

297295
/**
298296
* for_each_cpu_and - iterate over every cpu in both masks

include/linux/find.h

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,32 @@ unsigned long find_next_bit_wrap(const unsigned long *addr,
336336
return bit < offset ? bit : size;
337337
}
338338

339+
/*
340+
* Helper for for_each_set_bit_wrap(). Make sure you're doing right thing
341+
* before using it alone.
342+
*/
343+
static inline
344+
unsigned long __for_each_wrap(const unsigned long *bitmap, unsigned long size,
345+
unsigned long start, unsigned long n)
346+
{
347+
unsigned long bit;
348+
349+
/* If not wrapped around */
350+
if (n > start) {
351+
/* and have a bit, just return it. */
352+
bit = find_next_bit(bitmap, size, n);
353+
if (bit < size)
354+
return bit;
355+
356+
/* Otherwise, wrap around and ... */
357+
n = 0;
358+
}
359+
360+
/* Search the other part. */
361+
bit = find_next_bit(bitmap, start, n);
362+
return bit < start ? bit : size;
363+
}
364+
339365
/**
340366
* find_next_clump8 - find next 8-bit clump with set bits in a memory region
341367
* @clump: location to store copy of found clump
@@ -514,6 +540,19 @@ unsigned long find_next_bit_le(const void *addr, unsigned
514540
(b) = find_next_zero_bit((addr), (size), (e) + 1), \
515541
(e) = find_next_bit((addr), (size), (b) + 1))
516542

543+
/**
544+
* for_each_set_bit_wrap - iterate over all set bits starting from @start, and
545+
* wrapping around the end of bitmap.
546+
* @bit: offset for current iteration
547+
* @addr: bitmap address to base the search on
548+
* @size: bitmap size in number of bits
549+
* @start: Starting bit for bitmap traversing, wrapping around the bitmap end
550+
*/
551+
#define for_each_set_bit_wrap(bit, addr, size, start) \
552+
for ((bit) = find_next_bit_wrap((addr), (size), (start)); \
553+
(bit) < (size); \
554+
(bit) = __for_each_wrap((addr), (size), (start), (bit) + 1))
555+
517556
/**
518557
* for_each_set_clump8 - iterate over bitmap for each 8-bit clump with set bits
519558
* @start: bit offset to start search and to store the current iteration offset

0 commit comments

Comments
 (0)