mirror of
https://github.com/torvalds/linux.git
synced 2026-10-07 05:31:08 -04:00
lib/find: introduce find_nth_and_andnot_bit
In the following patches the function is used to implement in-place bitmaps traversing without storing intermediate result in temporary bitmaps. Signed-off-by: Yury Norov <[email protected]> Acked-by: Tariq Toukan <[email protected]> Reviewed-by: Jacob Keller <[email protected]> Reviewed-by: Peter Lafreniere <[email protected]> Signed-off-by: Jakub Kicinski <[email protected]>
This commit is contained in:
1 parent
383d9f87a0
commit
4324511780
2 files changed
+42
No files matched your search
@@ -22,6 +22,9 @@ unsigned long __find_nth_and_bit(const unsigned long *addr1, const unsigned long
|
||||
unsigned long size, unsigned long n);
|
||||
unsigned long __find_nth_andnot_bit(const unsigned long *addr1, const unsigned long *addr2,
|
||||
unsigned long size, unsigned long n);
|
||||
unsigned long __find_nth_and_andnot_bit(const unsigned long *addr1, const unsigned long *addr2,
|
||||
const unsigned long *addr3, unsigned long size,
|
||||
unsigned long n);
|
||||
extern unsigned long _find_first_and_bit(const unsigned long *addr1,
|
||||
const unsigned long *addr2, unsigned long size);
|
||||
extern unsigned long _find_first_zero_bit(const unsigned long *addr, unsigned long size);
|
||||
@@ -255,6 +258,36 @@ unsigned long find_nth_andnot_bit(const unsigned long *addr1, const unsigned lon
|
||||
return __find_nth_andnot_bit(addr1, addr2, size, n);
|
||||
}
|
||||
|
||||
/**
|
||||
* find_nth_and_andnot_bit - find N'th set bit in 2 memory regions,
|
||||
* excluding those set in 3rd region
|
||||
* @addr1: The 1st address to start the search at
|
||||
* @addr2: The 2nd address to start the search at
|
||||
* @addr3: The 3rd address to start the search at
|
||||
* @size: The maximum number of bits to search
|
||||
* @n: The number of set bit, which position is needed, counting from 0
|
||||
*
|
||||
* Returns the bit number of the N'th set bit.
|
||||
* If no such, returns @size.
|
||||
*/
|
||||
static __always_inline
|
||||
unsigned long find_nth_and_andnot_bit(const unsigned long *addr1,
|
||||
const unsigned long *addr2,
|
||||
const unsigned long *addr3,
|
||||
unsigned long size, unsigned long n)
|
||||
{
|
||||
if (n >= size)
|
||||
return size;
|
||||
|
||||
if (small_const_nbits(size)) {
|
||||
unsigned long val = *addr1 & *addr2 & (~*addr3) & GENMASK(size - 1, 0);
|
||||
|
||||
return val ? fns(val, n) : size;
|
||||
}
|
||||
|
||||
return __find_nth_and_andnot_bit(addr1, addr2, addr3, size, n);
|
||||
}
|
||||
|
||||
#ifndef find_first_and_bit
|
||||
/**
|
||||
* find_first_and_bit - find the first set bit in both memory regions
|
||||
|
||||
@@ -155,6 +155,15 @@ unsigned long __find_nth_andnot_bit(const unsigned long *addr1, const unsigned l
|
||||
}
|
||||
EXPORT_SYMBOL(__find_nth_andnot_bit);
|
||||
|
||||
unsigned long __find_nth_and_andnot_bit(const unsigned long *addr1,
|
||||
const unsigned long *addr2,
|
||||
const unsigned long *addr3,
|
||||
unsigned long size, unsigned long n)
|
||||
{
|
||||
return FIND_NTH_BIT(addr1[idx] & addr2[idx] & ~addr3[idx], size, n);
|
||||
}
|
||||
EXPORT_SYMBOL(__find_nth_and_andnot_bit);
|
||||
|
||||
#ifndef find_next_and_bit
|
||||
unsigned long _find_next_and_bit(const unsigned long *addr1, const unsigned long *addr2,
|
||||
unsigned long nbits, unsigned long start)
|
||||
|
||||
Reference in new issue
Block a user