diff options
author | Yury Norov <yury.norov@gmail.com> | 2022-09-19 14:05:56 -0700 |
---|---|---|
committer | Yury Norov <yury.norov@gmail.com> | 2022-10-01 10:22:57 -0700 |
commit | 6cc18331a987c4a29d66b9c4fd292587fba4d7bd (patch) | |
tree | ec87f04dbf7cdcb81c4094fa9ad5b9943ecd8de2 /include/linux/find.h | |
parent | 33e67710beda78aed38a2fe10be6088d4aeb1c53 (diff) |
lib/find_bit: add find_next{,_and}_bit_wrap
The helper is better optimized for the worst case: in case of empty
cpumask, current code traverses 2 * size:
next = cpumask_next_and(prev, src1p, src2p);
if (next >= nr_cpu_ids)
next = cpumask_first_and(src1p, src2p);
At bitmap level we can stop earlier after checking 'size + offset' bits.
Signed-off-by: Yury Norov <yury.norov@gmail.com>
Diffstat (limited to 'include/linux/find.h')
-rw-r--r-- | include/linux/find.h | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/include/linux/find.h b/include/linux/find.h index 128615a3f93e..77c087b7a451 100644 --- a/include/linux/find.h +++ b/include/linux/find.h @@ -291,6 +291,52 @@ unsigned long find_last_bit(const unsigned long *addr, unsigned long size) #endif /** + * find_next_and_bit_wrap - find the next set bit in both memory regions + * @addr1: The first address to base the search on + * @addr2: The second address to base the search on + * @size: The bitmap size in bits + * @offset: The bitnumber to start searching at + * + * Returns the bit number for the next set bit, or first set bit up to @offset + * If no bits are set, returns @size. + */ +static inline +unsigned long find_next_and_bit_wrap(const unsigned long *addr1, + const unsigned long *addr2, + unsigned long size, unsigned long offset) +{ + unsigned long bit = find_next_and_bit(addr1, addr2, size, offset); + + if (bit < size) + return bit; + + bit = find_first_and_bit(addr1, addr2, offset); + return bit < offset ? bit : size; +} + +/** + * find_next_bit_wrap - find the next set bit in both memory regions + * @addr: The first address to base the search on + * @size: The bitmap size in bits + * @offset: The bitnumber to start searching at + * + * Returns the bit number for the next set bit, or first set bit up to @offset + * If no bits are set, returns @size. + */ +static inline +unsigned long find_next_bit_wrap(const unsigned long *addr, + unsigned long size, unsigned long offset) +{ + unsigned long bit = find_next_bit(addr, size, offset); + + if (bit < size) + return bit; + + bit = find_first_bit(addr, offset); + return bit < offset ? 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 * @addr: address to base the search on |