Commit 02bc11de authored by Jiri Olsa's avatar Jiri Olsa Committed by Arnaldo Carvalho de Melo

tools lib: Add for_each_clear_bit macro

Adding for_each_clear_bit macro plus all its the necessary backbone
functions. Taken from related kernel code. It will be used in following
patch.
Signed-off-by: default avatarJiri Olsa <jolsa@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/n/tip-cayv2zbqi0nlmg5sjjxs1775@git.kernel.orgSigned-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent fe316723
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
*/ */
#include <asm-generic/bitops/__ffs.h> #include <asm-generic/bitops/__ffs.h>
#include <asm-generic/bitops/__ffz.h>
#include <asm-generic/bitops/fls.h> #include <asm-generic/bitops/fls.h>
#include <asm-generic/bitops/__fls.h> #include <asm-generic/bitops/__fls.h>
#include <asm-generic/bitops/fls64.h> #include <asm-generic/bitops/fls64.h>
......
#ifndef _ASM_GENERIC_BITOPS_FFZ_H_
#define _ASM_GENERIC_BITOPS_FFZ_H_
/*
* ffz - find first zero in word.
* @word: The word to search
*
* Undefined if no zero exists, so code should check against ~0UL first.
*/
#define ffz(x) __ffs(~(x))
#endif /* _ASM_GENERIC_BITOPS_FFZ_H_ */
...@@ -15,6 +15,21 @@ extern unsigned long find_next_bit(const unsigned long *addr, unsigned long ...@@ -15,6 +15,21 @@ extern unsigned long find_next_bit(const unsigned long *addr, unsigned long
size, unsigned long offset); size, unsigned long offset);
#endif #endif
#ifndef find_next_zero_bit
/**
* find_next_zero_bit - find the next cleared bit in a memory region
* @addr: The address to base the search on
* @offset: The bitnumber to start searching at
* @size: The bitmap size in bits
*
* Returns the bit number of the next zero bit
* If no bits are zero, returns @size.
*/
unsigned long find_next_zero_bit(const unsigned long *addr, unsigned long size,
unsigned long offset);
#endif
#ifndef find_first_bit #ifndef find_first_bit
/** /**
...@@ -30,4 +45,17 @@ extern unsigned long find_first_bit(const unsigned long *addr, ...@@ -30,4 +45,17 @@ extern unsigned long find_first_bit(const unsigned long *addr,
#endif /* find_first_bit */ #endif /* find_first_bit */
#ifndef find_first_zero_bit
/**
* find_first_zero_bit - find the first cleared bit in a memory region
* @addr: The address to start the search at
* @size: The maximum number of bits to search
*
* Returns the bit number of the first cleared bit.
* If no bits are zero, returns @size.
*/
unsigned long find_first_zero_bit(const unsigned long *addr, unsigned long size);
#endif
#endif /*_TOOLS_LINUX_ASM_GENERIC_BITOPS_FIND_H_ */ #endif /*_TOOLS_LINUX_ASM_GENERIC_BITOPS_FIND_H_ */
...@@ -39,6 +39,11 @@ extern unsigned long __sw_hweight64(__u64 w); ...@@ -39,6 +39,11 @@ extern unsigned long __sw_hweight64(__u64 w);
(bit) < (size); \ (bit) < (size); \
(bit) = find_next_bit((addr), (size), (bit) + 1)) (bit) = find_next_bit((addr), (size), (bit) + 1))
#define for_each_clear_bit(bit, addr, size) \
for ((bit) = find_first_zero_bit((addr), (size)); \
(bit) < (size); \
(bit) = find_next_zero_bit((addr), (size), (bit) + 1))
/* same as for_each_set_bit() but use bit as value to start with */ /* same as for_each_set_bit() but use bit as value to start with */
#define for_each_set_bit_from(bit, addr, size) \ #define for_each_set_bit_from(bit, addr, size) \
for ((bit) = find_next_bit((addr), (size), (bit)); \ for ((bit) = find_next_bit((addr), (size), (bit)); \
......
...@@ -82,3 +82,28 @@ unsigned long find_first_bit(const unsigned long *addr, unsigned long size) ...@@ -82,3 +82,28 @@ unsigned long find_first_bit(const unsigned long *addr, unsigned long size)
return size; return size;
} }
#endif #endif
#ifndef find_first_zero_bit
/*
* Find the first cleared bit in a memory region.
*/
unsigned long find_first_zero_bit(const unsigned long *addr, unsigned long size)
{
unsigned long idx;
for (idx = 0; idx * BITS_PER_LONG < size; idx++) {
if (addr[idx] != ~0UL)
return min(idx * BITS_PER_LONG + ffz(addr[idx]), size);
}
return size;
}
#endif
#ifndef find_next_zero_bit
unsigned long find_next_zero_bit(const unsigned long *addr, unsigned long size,
unsigned long offset)
{
return _find_next_bit(addr, size, offset, ~0UL);
}
#endif
...@@ -51,6 +51,7 @@ tools/include/asm-generic/bitops/arch_hweight.h ...@@ -51,6 +51,7 @@ tools/include/asm-generic/bitops/arch_hweight.h
tools/include/asm-generic/bitops/atomic.h tools/include/asm-generic/bitops/atomic.h
tools/include/asm-generic/bitops/const_hweight.h tools/include/asm-generic/bitops/const_hweight.h
tools/include/asm-generic/bitops/__ffs.h tools/include/asm-generic/bitops/__ffs.h
tools/include/asm-generic/bitops/__ffz.h
tools/include/asm-generic/bitops/__fls.h tools/include/asm-generic/bitops/__fls.h
tools/include/asm-generic/bitops/find.h tools/include/asm-generic/bitops/find.h
tools/include/asm-generic/bitops/fls64.h tools/include/asm-generic/bitops/fls64.h
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment