Messages in this thread Patch in this message | | | From | Julien Desfossez <> | Subject | [RFC PATCH v7 06/23] bitops: Introduce find_next_or_bit | Date | Fri, 28 Aug 2020 15:51:07 -0400 |
| |
From: Vineeth Pillai <viremana@linux.microsoft.com>
Hotplug fixes to core-scheduling require a new bitops API.
Introduce a new API find_next_or_bit() which returns the bit number of the next set bit in OR-ed bit masks of the given bit masks.
Signed-off-by: Vineeth Pillai <viremana@linux.microsoft.com> Signed-off-by: Joel Fernandes (Google) <joel@joelfernandes.org> --- include/asm-generic/bitops/find.h | 16 +++++++++ lib/find_bit.c | 58 +++++++++++++++++++++++++------ 2 files changed, 63 insertions(+), 11 deletions(-)
diff --git a/include/asm-generic/bitops/find.h b/include/asm-generic/bitops/find.h index 9fdf21302fdf..0b476ca0d665 100644 --- a/include/asm-generic/bitops/find.h +++ b/include/asm-generic/bitops/find.h @@ -32,6 +32,22 @@ extern unsigned long find_next_and_bit(const unsigned long *addr1, unsigned long offset); #endif +#ifndef find_next_or_bit +/** + * find_next_or_bit - find the next set bit in any memory regions + * @addr1: The first address to base the search on + * @addr2: The second address to base the search on + * @offset: The bitnumber to start searching at + * @size: The bitmap size in bits + * + * Returns the bit number for the next set bit + * If no bits are set, returns @size. + */ +extern unsigned long find_next_or_bit(const unsigned long *addr1, + const unsigned long *addr2, unsigned long size, + unsigned long offset); +#endif + #ifndef find_next_zero_bit /** * find_next_zero_bit - find the next cleared bit in a memory region diff --git a/lib/find_bit.c b/lib/find_bit.c index 49f875f1baf7..e36257bb0701 100644 --- a/lib/find_bit.c +++ b/lib/find_bit.c @@ -19,7 +19,16 @@ #if !defined(find_next_bit) || !defined(find_next_zero_bit) || \ !defined(find_next_bit_le) || !defined(find_next_zero_bit_le) || \ - !defined(find_next_and_bit) + !defined(find_next_and_bit) || !defined(find_next_or_bit) + +/* + * find_next_bit bitwise operation types + */ +enum fnb_bwops_type { + FNB_AND = 0, + FNB_OR = 1 +}; + /* * This is a common helper function for find_next_bit, find_next_zero_bit, and * find_next_and_bit. The differences are: @@ -29,7 +38,8 @@ */ static unsigned long _find_next_bit(const unsigned long *addr1, const unsigned long *addr2, unsigned long nbits, - unsigned long start, unsigned long invert, unsigned long le) + unsigned long start, unsigned long invert, + enum fnb_bwops_type type, unsigned long le) { unsigned long tmp, mask; @@ -37,8 +47,16 @@ static unsigned long _find_next_bit(const unsigned long *addr1, return nbits; tmp = addr1[start / BITS_PER_LONG]; - if (addr2) - tmp &= addr2[start / BITS_PER_LONG]; + if (addr2) { + switch (type) { + case FNB_AND: + tmp &= addr2[start / BITS_PER_LONG]; + break; + case FNB_OR: + tmp |= addr2[start / BITS_PER_LONG]; + break; + } + } tmp ^= invert; /* Handle 1st word. */ @@ -56,8 +74,16 @@ static unsigned long _find_next_bit(const unsigned long *addr1, return nbits; tmp = addr1[start / BITS_PER_LONG]; - if (addr2) - tmp &= addr2[start / BITS_PER_LONG]; + if (addr2) { + switch (type) { + case FNB_AND: + tmp &= addr2[start / BITS_PER_LONG]; + break; + case FNB_OR: + tmp |= addr2[start / BITS_PER_LONG]; + break; + } + } tmp ^= invert; } @@ -75,7 +101,7 @@ static unsigned long _find_next_bit(const unsigned long *addr1, unsigned long find_next_bit(const unsigned long *addr, unsigned long size, unsigned long offset) { - return _find_next_bit(addr, NULL, size, offset, 0UL, 0); + return _find_next_bit(addr, NULL, size, offset, 0UL, FNB_AND, 0); } EXPORT_SYMBOL(find_next_bit); #endif @@ -84,7 +110,7 @@ EXPORT_SYMBOL(find_next_bit); unsigned long find_next_zero_bit(const unsigned long *addr, unsigned long size, unsigned long offset) { - return _find_next_bit(addr, NULL, size, offset, ~0UL, 0); + return _find_next_bit(addr, NULL, size, offset, ~0UL, FNB_AND, 0); } EXPORT_SYMBOL(find_next_zero_bit); #endif @@ -94,11 +120,21 @@ unsigned long find_next_and_bit(const unsigned long *addr1, const unsigned long *addr2, unsigned long size, unsigned long offset) { - return _find_next_bit(addr1, addr2, size, offset, 0UL, 0); + return _find_next_bit(addr1, addr2, size, offset, 0UL, FNB_AND, 0); } EXPORT_SYMBOL(find_next_and_bit); #endif +#if !defined(find_next_or_bit) +unsigned long find_next_or_bit(const unsigned long *addr1, + const unsigned long *addr2, unsigned long size, + unsigned long offset) +{ + return _find_next_bit(addr1, addr2, size, offset, 0UL, FNB_OR, 0); +} +EXPORT_SYMBOL(find_next_or_bit); +#endif + #ifndef find_first_bit /* * Find the first set bit in a memory region. @@ -161,7 +197,7 @@ EXPORT_SYMBOL(find_last_bit); unsigned long find_next_zero_bit_le(const void *addr, unsigned long size, unsigned long offset) { - return _find_next_bit(addr, NULL, size, offset, ~0UL, 1); + return _find_next_bit(addr, NULL, size, offset, ~0UL, FNB_AND, 1); } EXPORT_SYMBOL(find_next_zero_bit_le); #endif @@ -170,7 +206,7 @@ EXPORT_SYMBOL(find_next_zero_bit_le); unsigned long find_next_bit_le(const void *addr, unsigned long size, unsigned long offset) { - return _find_next_bit(addr, NULL, size, offset, 0UL, 1); + return _find_next_bit(addr, NULL, size, offset, 0UL, FNB_AND, 1); } EXPORT_SYMBOL(find_next_bit_le); #endif -- 2.17.1
| |