Skip to content

Commit

Permalink
lib/bitmap: introduce for_each_set_bit_wrap() macro
Browse files Browse the repository at this point in the history
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 <yury.norov@gmail.com>
  • Loading branch information
Yury Norov committed Sep 27, 2022
1 parent 906ffaf commit 9d2c24f
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 4 deletions.
6 changes: 2 additions & 4 deletions include/linux/cpumask.h
Original file line number Diff line number Diff line change
Expand Up @@ -286,10 +286,8 @@ unsigned int __pure cpumask_next_wrap(int n, const struct cpumask *mask, int sta
*
* After the loop, cpu is >= nr_cpu_ids.
*/
#define for_each_cpu_wrap(cpu, mask, start) \
for ((cpu) = cpumask_next_wrap((start)-1, (mask), (start), false); \
(cpu) < nr_cpumask_bits; \
(cpu) = cpumask_next_wrap((cpu), (mask), (start), true))
#define for_each_cpu_wrap(cpu, mask, start) \
for_each_set_bit_wrap(cpu, cpumask_bits(mask), nr_cpumask_bits, start)

/**
* for_each_cpu_and - iterate over every cpu in both masks
Expand Down
39 changes: 39 additions & 0 deletions include/linux/find.h
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,32 @@ unsigned long find_next_bit_wrap(const unsigned long *addr,
return bit < offset ? bit : size;
}

/*
* Helper for for_each_set_bit_wrap(). Make sure you're doing right thing
* before using it alone.
*/
static inline
unsigned long __for_each_wrap(const unsigned long *bitmap, unsigned long size,
unsigned long start, unsigned long n)
{
unsigned long bit;

/* If not wrapped around */
if (n > start) {
/* and have a bit, just return it. */
bit = find_next_bit(bitmap, size, n);
if (bit < size)
return bit;

/* Otherwise, wrap around and ... */
n = 0;
}

/* Search the other part. */
bit = find_next_bit(bitmap, start, n);
return bit < start ? bit : size;
}

/**
* find_next_clump8 - find next 8-bit clump with set bits in a memory region
* @clump: location to store copy of found clump
Expand Down Expand Up @@ -514,6 +540,19 @@ unsigned long find_next_bit_le(const void *addr, unsigned
(b) = find_next_zero_bit((addr), (size), (e) + 1), \
(e) = find_next_bit((addr), (size), (b) + 1))

/**
* for_each_set_bit_wrap - iterate over all set bits starting from @start, and
* wrapping around the end of bitmap.
* @bit: offset for current iteration
* @addr: bitmap address to base the search on
* @size: bitmap size in number of bits
* @start: Starting bit for bitmap traversing, wrapping around the bitmap end
*/
#define for_each_set_bit_wrap(bit, addr, size, start) \
for ((bit) = find_next_bit_wrap((addr), (size), (start)); \
(bit) < (size); \
(bit) = __for_each_wrap((addr), (size), (start), (bit) + 1))

/**
* for_each_set_clump8 - iterate over bitmap for each 8-bit clump with set bits
* @start: bit offset to start search and to store the current iteration offset
Expand Down

0 comments on commit 9d2c24f

Please sign in to comment.