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: Jiri 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.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:

committed by
Arnaldo Carvalho de Melo

parent
fe316723a8
commit
02bc11de56
@@ -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>
|
||||||
|
12
tools/include/asm-generic/bitops/__ffz.h
Normal file
12
tools/include/asm-generic/bitops/__ffz.h
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
#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
|
|||||||
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,
|
|||||||
|
|
||||||
#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);
|
|||||||
(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)
|
|||||||
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
|
|||||||
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
|
||||||
|
Reference in New Issue
Block a user