diff options
-rw-r--r-- | tools/include/asm-generic/bitops/find.h | 33 | ||||
-rw-r--r-- | tools/lib/util/find_next_bit.c | 89 | ||||
-rw-r--r-- | tools/perf/MANIFEST | 3 | ||||
-rw-r--r-- | tools/perf/Makefile.perf | 5 | ||||
-rw-r--r-- | tools/perf/util/include/linux/bitops.h | 73 |
5 files changed, 131 insertions, 72 deletions
diff --git a/tools/include/asm-generic/bitops/find.h b/tools/include/asm-generic/bitops/find.h new file mode 100644 index 000000000000..31f51547fcd4 --- /dev/null +++ b/tools/include/asm-generic/bitops/find.h | |||
@@ -0,0 +1,33 @@ | |||
1 | #ifndef _TOOLS_LINUX_ASM_GENERIC_BITOPS_FIND_H_ | ||
2 | #define _TOOLS_LINUX_ASM_GENERIC_BITOPS_FIND_H_ | ||
3 | |||
4 | #ifndef find_next_bit | ||
5 | /** | ||
6 | * find_next_bit - find the next set bit in a memory region | ||
7 | * @addr: The address to base the search on | ||
8 | * @offset: The bitnumber to start searching at | ||
9 | * @size: The bitmap size in bits | ||
10 | * | ||
11 | * Returns the bit number for the next set bit | ||
12 | * If no bits are set, returns @size. | ||
13 | */ | ||
14 | extern unsigned long find_next_bit(const unsigned long *addr, unsigned long | ||
15 | size, unsigned long offset); | ||
16 | #endif | ||
17 | |||
18 | #ifndef find_first_bit | ||
19 | |||
20 | /** | ||
21 | * find_first_bit - find the first set bit in a memory region | ||
22 | * @addr: The address to start the search at | ||
23 | * @size: The maximum number of bits to search | ||
24 | * | ||
25 | * Returns the bit number of the first set bit. | ||
26 | * If no bits are set, returns @size. | ||
27 | */ | ||
28 | extern unsigned long find_first_bit(const unsigned long *addr, | ||
29 | unsigned long size); | ||
30 | |||
31 | #endif /* find_first_bit */ | ||
32 | |||
33 | #endif /*_TOOLS_LINUX_ASM_GENERIC_BITOPS_FIND_H_ */ | ||
diff --git a/tools/lib/util/find_next_bit.c b/tools/lib/util/find_next_bit.c new file mode 100644 index 000000000000..41b44f65a79e --- /dev/null +++ b/tools/lib/util/find_next_bit.c | |||
@@ -0,0 +1,89 @@ | |||
1 | /* find_next_bit.c: fallback find next bit implementation | ||
2 | * | ||
3 | * Copied from lib/find_next_bit.c to tools/lib/next_bit.c | ||
4 | * | ||
5 | * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. | ||
6 | * Written by David Howells (dhowells@redhat.com) | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public License | ||
10 | * as published by the Free Software Foundation; either version | ||
11 | * 2 of the License, or (at your option) any later version. | ||
12 | */ | ||
13 | |||
14 | #include <linux/bitops.h> | ||
15 | #include <asm/types.h> | ||
16 | #include <asm/byteorder.h> | ||
17 | |||
18 | #define BITOP_WORD(nr) ((nr) / BITS_PER_LONG) | ||
19 | |||
20 | #ifndef find_next_bit | ||
21 | /* | ||
22 | * Find the next set bit in a memory region. | ||
23 | */ | ||
24 | unsigned long find_next_bit(const unsigned long *addr, unsigned long size, | ||
25 | unsigned long offset) | ||
26 | { | ||
27 | const unsigned long *p = addr + BITOP_WORD(offset); | ||
28 | unsigned long result = offset & ~(BITS_PER_LONG-1); | ||
29 | unsigned long tmp; | ||
30 | |||
31 | if (offset >= size) | ||
32 | return size; | ||
33 | size -= result; | ||
34 | offset %= BITS_PER_LONG; | ||
35 | if (offset) { | ||
36 | tmp = *(p++); | ||
37 | tmp &= (~0UL << offset); | ||
38 | if (size < BITS_PER_LONG) | ||
39 | goto found_first; | ||
40 | if (tmp) | ||
41 | goto found_middle; | ||
42 | size -= BITS_PER_LONG; | ||
43 | result += BITS_PER_LONG; | ||
44 | } | ||
45 | while (size & ~(BITS_PER_LONG-1)) { | ||
46 | if ((tmp = *(p++))) | ||
47 | goto found_middle; | ||
48 | result += BITS_PER_LONG; | ||
49 | size -= BITS_PER_LONG; | ||
50 | } | ||
51 | if (!size) | ||
52 | return result; | ||
53 | tmp = *p; | ||
54 | |||
55 | found_first: | ||
56 | tmp &= (~0UL >> (BITS_PER_LONG - size)); | ||
57 | if (tmp == 0UL) /* Are any bits set? */ | ||
58 | return result + size; /* Nope. */ | ||
59 | found_middle: | ||
60 | return result + __ffs(tmp); | ||
61 | } | ||
62 | #endif | ||
63 | |||
64 | #ifndef find_first_bit | ||
65 | /* | ||
66 | * Find the first set bit in a memory region. | ||
67 | */ | ||
68 | unsigned long find_first_bit(const unsigned long *addr, unsigned long size) | ||
69 | { | ||
70 | const unsigned long *p = addr; | ||
71 | unsigned long result = 0; | ||
72 | unsigned long tmp; | ||
73 | |||
74 | while (size & ~(BITS_PER_LONG-1)) { | ||
75 | if ((tmp = *(p++))) | ||
76 | goto found; | ||
77 | result += BITS_PER_LONG; | ||
78 | size -= BITS_PER_LONG; | ||
79 | } | ||
80 | if (!size) | ||
81 | return result; | ||
82 | |||
83 | tmp = (*p) & (~0UL >> (BITS_PER_LONG - size)); | ||
84 | if (tmp == 0UL) /* Are any bits set? */ | ||
85 | return result + size; /* Nope. */ | ||
86 | found: | ||
87 | return result + __ffs(tmp); | ||
88 | } | ||
89 | #endif | ||
diff --git a/tools/perf/MANIFEST b/tools/perf/MANIFEST index 67d48e20f7e1..bfd7e22bafad 100644 --- a/tools/perf/MANIFEST +++ b/tools/perf/MANIFEST | |||
@@ -4,8 +4,10 @@ tools/lib/traceevent | |||
4 | tools/lib/api | 4 | tools/lib/api |
5 | tools/lib/symbol/kallsyms.c | 5 | tools/lib/symbol/kallsyms.c |
6 | tools/lib/symbol/kallsyms.h | 6 | tools/lib/symbol/kallsyms.h |
7 | tools/lib/util/find_next_bit.c | ||
7 | tools/include/asm/bug.h | 8 | tools/include/asm/bug.h |
8 | tools/include/asm-generic/bitops/atomic.h | 9 | tools/include/asm-generic/bitops/atomic.h |
10 | tools/include/asm-generic/bitops/find.h | ||
9 | tools/include/asm-generic/bitops/__ffs.h | 11 | tools/include/asm-generic/bitops/__ffs.h |
10 | tools/include/linux/compiler.h | 12 | tools/include/linux/compiler.h |
11 | tools/include/linux/export.h | 13 | tools/include/linux/export.h |
@@ -18,6 +20,7 @@ include/linux/rbtree.h | |||
18 | include/linux/list.h | 20 | include/linux/list.h |
19 | include/linux/hash.h | 21 | include/linux/hash.h |
20 | include/linux/stringify.h | 22 | include/linux/stringify.h |
23 | lib/find_next_bit.c | ||
21 | lib/rbtree.c | 24 | lib/rbtree.c |
22 | include/linux/swab.h | 25 | include/linux/swab.h |
23 | arch/*/include/asm/unistd*.h | 26 | arch/*/include/asm/unistd*.h |
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index 604349dcafef..1aef4176ca19 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf | |||
@@ -233,6 +233,7 @@ LIB_H += ../../include/linux/stringify.h | |||
233 | LIB_H += util/include/linux/bitmap.h | 233 | LIB_H += util/include/linux/bitmap.h |
234 | LIB_H += util/include/linux/bitops.h | 234 | LIB_H += util/include/linux/bitops.h |
235 | LIB_H += ../include/asm-generic/bitops/atomic.h | 235 | LIB_H += ../include/asm-generic/bitops/atomic.h |
236 | LIB_H += ../include/asm-generic/bitops/find.h | ||
236 | LIB_H += ../include/asm-generic/bitops/__ffs.h | 237 | LIB_H += ../include/asm-generic/bitops/__ffs.h |
237 | LIB_H += ../include/linux/compiler.h | 238 | LIB_H += ../include/linux/compiler.h |
238 | LIB_H += ../include/linux/log2.h | 239 | LIB_H += ../include/linux/log2.h |
@@ -338,6 +339,7 @@ LIB_OBJS += $(OUTPUT)util/event.o | |||
338 | LIB_OBJS += $(OUTPUT)util/evlist.o | 339 | LIB_OBJS += $(OUTPUT)util/evlist.o |
339 | LIB_OBJS += $(OUTPUT)util/evsel.o | 340 | LIB_OBJS += $(OUTPUT)util/evsel.o |
340 | LIB_OBJS += $(OUTPUT)util/exec_cmd.o | 341 | LIB_OBJS += $(OUTPUT)util/exec_cmd.o |
342 | LIB_OBJS += $(OUTPUT)util/find_next_bit.o | ||
341 | LIB_OBJS += $(OUTPUT)util/help.o | 343 | LIB_OBJS += $(OUTPUT)util/help.o |
342 | LIB_OBJS += $(OUTPUT)util/kallsyms.o | 344 | LIB_OBJS += $(OUTPUT)util/kallsyms.o |
343 | LIB_OBJS += $(OUTPUT)util/levenshtein.o | 345 | LIB_OBJS += $(OUTPUT)util/levenshtein.o |
@@ -737,6 +739,9 @@ $(OUTPUT)util/kallsyms.o: ../lib/symbol/kallsyms.c $(OUTPUT)PERF-CFLAGS | |||
737 | $(OUTPUT)util/rbtree.o: ../../lib/rbtree.c $(OUTPUT)PERF-CFLAGS | 739 | $(OUTPUT)util/rbtree.o: ../../lib/rbtree.c $(OUTPUT)PERF-CFLAGS |
738 | $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -Wno-unused-parameter -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $< | 740 | $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -Wno-unused-parameter -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $< |
739 | 741 | ||
742 | $(OUTPUT)util/find_next_bit.o: ../lib/util/find_next_bit.c $(OUTPUT)PERF-CFLAGS | ||
743 | $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -Wno-unused-parameter -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $< | ||
744 | |||
740 | $(OUTPUT)util/parse-events.o: util/parse-events.c $(OUTPUT)PERF-CFLAGS | 745 | $(OUTPUT)util/parse-events.o: util/parse-events.c $(OUTPUT)PERF-CFLAGS |
741 | $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -Wno-redundant-decls $< | 746 | $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -Wno-redundant-decls $< |
742 | 747 | ||
diff --git a/tools/perf/util/include/linux/bitops.h b/tools/perf/util/include/linux/bitops.h index 58c4a2520ac2..292aadeb66c5 100644 --- a/tools/perf/util/include/linux/bitops.h +++ b/tools/perf/util/include/linux/bitops.h | |||
@@ -37,78 +37,7 @@ static inline unsigned long hweight_long(unsigned long w) | |||
37 | return sizeof(w) == 4 ? hweight32(w) : hweight64(w); | 37 | return sizeof(w) == 4 ? hweight32(w) : hweight64(w); |
38 | } | 38 | } |
39 | 39 | ||
40 | #define BITOP_WORD(nr) ((nr) / BITS_PER_LONG) | ||
41 | |||
42 | #include <asm-generic/bitops/__ffs.h> | 40 | #include <asm-generic/bitops/__ffs.h> |
43 | 41 | #include <asm-generic/bitops/find.h> | |
44 | typedef const unsigned long __attribute__((__may_alias__)) long_alias_t; | ||
45 | |||
46 | /* | ||
47 | * Find the first set bit in a memory region. | ||
48 | */ | ||
49 | static inline unsigned long | ||
50 | find_first_bit(const unsigned long *addr, unsigned long size) | ||
51 | { | ||
52 | long_alias_t *p = (long_alias_t *) addr; | ||
53 | unsigned long result = 0; | ||
54 | unsigned long tmp; | ||
55 | |||
56 | while (size & ~(BITS_PER_LONG-1)) { | ||
57 | if ((tmp = *(p++))) | ||
58 | goto found; | ||
59 | result += BITS_PER_LONG; | ||
60 | size -= BITS_PER_LONG; | ||
61 | } | ||
62 | if (!size) | ||
63 | return result; | ||
64 | |||
65 | tmp = (*p) & (~0UL >> (BITS_PER_LONG - size)); | ||
66 | if (tmp == 0UL) /* Are any bits set? */ | ||
67 | return result + size; /* Nope. */ | ||
68 | found: | ||
69 | return result + __ffs(tmp); | ||
70 | } | ||
71 | |||
72 | /* | ||
73 | * Find the next set bit in a memory region. | ||
74 | */ | ||
75 | static inline unsigned long | ||
76 | find_next_bit(const unsigned long *addr, unsigned long size, unsigned long offset) | ||
77 | { | ||
78 | const unsigned long *p = addr + BITOP_WORD(offset); | ||
79 | unsigned long result = offset & ~(BITS_PER_LONG-1); | ||
80 | unsigned long tmp; | ||
81 | |||
82 | if (offset >= size) | ||
83 | return size; | ||
84 | size -= result; | ||
85 | offset %= BITS_PER_LONG; | ||
86 | if (offset) { | ||
87 | tmp = *(p++); | ||
88 | tmp &= (~0UL << offset); | ||
89 | if (size < BITS_PER_LONG) | ||
90 | goto found_first; | ||
91 | if (tmp) | ||
92 | goto found_middle; | ||
93 | size -= BITS_PER_LONG; | ||
94 | result += BITS_PER_LONG; | ||
95 | } | ||
96 | while (size & ~(BITS_PER_LONG-1)) { | ||
97 | if ((tmp = *(p++))) | ||
98 | goto found_middle; | ||
99 | result += BITS_PER_LONG; | ||
100 | size -= BITS_PER_LONG; | ||
101 | } | ||
102 | if (!size) | ||
103 | return result; | ||
104 | tmp = *p; | ||
105 | |||
106 | found_first: | ||
107 | tmp &= (~0UL >> (BITS_PER_LONG - size)); | ||
108 | if (tmp == 0UL) /* Are any bits set? */ | ||
109 | return result + size; /* Nope. */ | ||
110 | found_middle: | ||
111 | return result + __ffs(tmp); | ||
112 | } | ||
113 | 42 | ||
114 | #endif | 43 | #endif |