Messages in this thread Patch in this message | | | From | chenggang <> | Subject | [PATCH 1/5] perf tools: Add some functions to bitops.h to support more bitmap operations. | Date | Thu, 20 Dec 2012 17:05:15 +0800 |
| |
Add bitmap_copy() & find_first_zero_bit() to the 'util/include/linux/bitops.h'. These functions could be need if we want to change the thread_map or any other mechanism with bitmap.
Cc: David Ahern <dsahern@gmail.com> Cc: Arjan van de Ven <arjan@linux.intel.com> Cc: Namhyung Kim <namhyung@gmail.com> Cc: Yanmin Zhang <yanmin.zhang@intel.com> Cc: Wu Fengguang <fengguang.wu@intel.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Ingo Molnar <mingo@redhat.com> Cc: Arnaldo Carvalho de Melo <acme@ghostprotocols.net> Cc: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Chenggang Qin <chenggang.qcg@taobao.com> --- tools/perf/util/include/linux/bitops.h | 85 ++++++++++++++++++++++++++------ 1 file changed, 69 insertions(+), 16 deletions(-)
diff --git a/tools/perf/util/include/linux/bitops.h b/tools/perf/util/include/linux/bitops.h index a55d8cf..644504a 100644 --- a/tools/perf/util/include/linux/bitops.h +++ b/tools/perf/util/include/linux/bitops.h @@ -4,6 +4,12 @@ #include <linux/kernel.h> #include <linux/compiler.h> #include <asm/hweight.h> +#include <string.h> + +typedef unsigned long BITMAP; + +#define PID_MAX_DEFAULT 0x8000 +#define CPU_MAX_DEFAULT 0x40 #ifndef __WORDSIZE #define __WORDSIZE (__SIZEOF_LONG__ * 8) @@ -26,36 +32,57 @@ (bit) < (size); \ (bit) = find_next_bit((addr), (size), (bit) + 1)) -static inline void set_bit(int nr, unsigned long *addr) +static inline void set_bit(int nr, BITMAP *addr) { addr[nr / BITS_PER_LONG] |= 1UL << (nr % BITS_PER_LONG); } -static inline void clear_bit(int nr, unsigned long *addr) +static inline void clear_bit(int nr, BITMAP *addr) { addr[nr / BITS_PER_LONG] &= ~(1UL << (nr % BITS_PER_LONG)); } -static __always_inline int test_bit(unsigned int nr, const unsigned long *addr) +static __always_inline int test_bit(unsigned int nr, const BITMAP *addr) { return ((1UL << (nr % BITS_PER_LONG)) & - (((unsigned long *)addr)[nr / BITS_PER_LONG])) != 0; + (((BITMAP *)addr)[nr / BITS_PER_LONG])) != 0; } -static inline unsigned long hweight_long(unsigned long w) +static inline BITMAP hweight_long(BITMAP w) { return sizeof(w) == 4 ? hweight32(w) : hweight64(w); } +static inline void bitmap_copy(BITMAP *dst, const BITMAP *src, + int nbits) +{ + int len = BITS_TO_LONGS(nbits) * sizeof(BITMAP); + memcpy(dst, src, len); +} + #define BITOP_WORD(nr) ((nr) / BITS_PER_LONG) +/* + * ffz - find first zero bit in word + * @word: The word to search + * + * Undefined if no zero exists, so code should check against ~0UL first. + */ +static __always_inline BITMAP ffz(BITMAP word) +{ + asm("rep; bsf %1,%0" + : "=r" (word) + : "r" (~word)); + return word; +} + /** * __ffs - find first bit in word. * @word: The word to search * * Undefined if no bit exists, so code should check against 0 first. */ -static __always_inline unsigned long __ffs(unsigned long word) +static __always_inline BITMAP __ffs(BITMAP word) { int num = 0; @@ -87,14 +114,40 @@ static __always_inline unsigned long __ffs(unsigned long word) } /* + * Find the first cleared bit in a memory region. + */ +static inline BITMAP +find_first_zero_bit(const BITMAP *addr, BITMAP size) +{ + const BITMAP *p = addr; + BITMAP result = 0; + BITMAP tmp; + + while (size & ~(BITS_PER_LONG-1)) { + if (~(tmp = *(p++))) + goto found; + result += BITS_PER_LONG; + size -= BITS_PER_LONG; + } + if (!size) + return result; + + tmp = (*p) | (~0UL << size); + if (tmp == ~0UL) /* Are any bits zero? */ + return result + size; /* Nope. */ +found: + return result + __ffs(~tmp); +} + +/* * Find the first set bit in a memory region. */ -static inline unsigned long -find_first_bit(const unsigned long *addr, unsigned long size) +static inline BITMAP +find_first_bit(const BITMAP *addr, BITMAP size) { - const unsigned long *p = addr; - unsigned long result = 0; - unsigned long tmp; + const BITMAP *p = addr; + BITMAP result = 0; + BITMAP tmp; while (size & ~(BITS_PER_LONG-1)) { if ((tmp = *(p++))) @@ -115,12 +168,12 @@ found: /* * Find the next set bit in a memory region. */ -static inline unsigned long -find_next_bit(const unsigned long *addr, unsigned long size, unsigned long offset) +static inline BITMAP +find_next_bit(const BITMAP *addr, BITMAP size, BITMAP offset) { - const unsigned long *p = addr + BITOP_WORD(offset); - unsigned long result = offset & ~(BITS_PER_LONG-1); - unsigned long tmp; + const BITMAP *p = addr + BITOP_WORD(offset); + BITMAP result = offset & ~(BITS_PER_LONG-1); + BITMAP tmp; if (offset >= size) return size; -- 1.7.9.5
| |