diff options
| -rw-r--r-- | tools/include/asm-generic/bitops.h | 27 | ||||
| -rw-r--r-- | tools/include/asm-generic/bitops/__ffs.h | 43 | ||||
| -rw-r--r-- | tools/include/asm-generic/bitops/__fls.h | 1 | ||||
| -rw-r--r-- | tools/include/asm-generic/bitops/atomic.h | 22 | ||||
| -rw-r--r-- | tools/include/asm-generic/bitops/find.h | 33 | ||||
| -rw-r--r-- | tools/include/asm-generic/bitops/fls.h | 1 | ||||
| -rw-r--r-- | tools/include/asm-generic/bitops/fls64.h | 1 | ||||
| -rw-r--r-- | tools/include/linux/bitops.h | 53 | ||||
| -rw-r--r-- | tools/include/linux/log2.h | 185 | ||||
| -rw-r--r-- | tools/lib/util/find_next_bit.c | 89 | ||||
| -rw-r--r-- | tools/perf/MANIFEST | 16 | ||||
| -rw-r--r-- | tools/perf/Makefile.perf | 14 | ||||
| -rw-r--r-- | tools/perf/builtin-trace.c | 2 | ||||
| -rw-r--r-- | tools/perf/util/evlist.c | 46 | ||||
| -rw-r--r-- | tools/perf/util/include/linux/bitops.h | 162 | ||||
| -rw-r--r-- | tools/perf/util/symbol-minimal.c | 8 | ||||
| -rw-r--r-- | tools/perf/util/util.h | 29 |
17 files changed, 525 insertions, 207 deletions
diff --git a/tools/include/asm-generic/bitops.h b/tools/include/asm-generic/bitops.h new file mode 100644 index 000000000000..6eedba1f7732 --- /dev/null +++ b/tools/include/asm-generic/bitops.h | |||
| @@ -0,0 +1,27 @@ | |||
| 1 | #ifndef __TOOLS_ASM_GENERIC_BITOPS_H | ||
| 2 | #define __TOOLS_ASM_GENERIC_BITOPS_H | ||
| 3 | |||
| 4 | /* | ||
| 5 | * tools/ copied this from include/asm-generic/bitops.h, bit by bit as it needed | ||
| 6 | * some functions. | ||
| 7 | * | ||
| 8 | * For the benefit of those who are trying to port Linux to another | ||
| 9 | * architecture, here are some C-language equivalents. You should | ||
| 10 | * recode these in the native assembly language, if at all possible. | ||
| 11 | * | ||
| 12 | * C language equivalents written by Theodore Ts'o, 9/26/92 | ||
| 13 | */ | ||
| 14 | |||
| 15 | #include <asm-generic/bitops/__ffs.h> | ||
| 16 | #include <asm-generic/bitops/fls.h> | ||
| 17 | #include <asm-generic/bitops/__fls.h> | ||
| 18 | #include <asm-generic/bitops/fls64.h> | ||
| 19 | #include <asm-generic/bitops/find.h> | ||
| 20 | |||
| 21 | #ifndef _TOOLS_LINUX_BITOPS_H_ | ||
| 22 | #error only <linux/bitops.h> can be included directly | ||
| 23 | #endif | ||
| 24 | |||
| 25 | #include <asm-generic/bitops/atomic.h> | ||
| 26 | |||
| 27 | #endif /* __TOOLS_ASM_GENERIC_BITOPS_H */ | ||
diff --git a/tools/include/asm-generic/bitops/__ffs.h b/tools/include/asm-generic/bitops/__ffs.h new file mode 100644 index 000000000000..c94175015a82 --- /dev/null +++ b/tools/include/asm-generic/bitops/__ffs.h | |||
| @@ -0,0 +1,43 @@ | |||
| 1 | #ifndef _TOOLS_LINUX_ASM_GENERIC_BITOPS___FFS_H_ | ||
| 2 | #define _TOOLS_LINUX_ASM_GENERIC_BITOPS___FFS_H_ | ||
| 3 | |||
| 4 | #include <asm/types.h> | ||
| 5 | |||
| 6 | /** | ||
| 7 | * __ffs - find first bit in word. | ||
| 8 | * @word: The word to search | ||
| 9 | * | ||
| 10 | * Undefined if no bit exists, so code should check against 0 first. | ||
| 11 | */ | ||
| 12 | static __always_inline unsigned long __ffs(unsigned long word) | ||
| 13 | { | ||
| 14 | int num = 0; | ||
| 15 | |||
| 16 | #if __BITS_PER_LONG == 64 | ||
| 17 | if ((word & 0xffffffff) == 0) { | ||
| 18 | num += 32; | ||
| 19 | word >>= 32; | ||
| 20 | } | ||
| 21 | #endif | ||
| 22 | if ((word & 0xffff) == 0) { | ||
| 23 | num += 16; | ||
| 24 | word >>= 16; | ||
| 25 | } | ||
| 26 | if ((word & 0xff) == 0) { | ||
| 27 | num += 8; | ||
| 28 | word >>= 8; | ||
| 29 | } | ||
| 30 | if ((word & 0xf) == 0) { | ||
| 31 | num += 4; | ||
| 32 | word >>= 4; | ||
| 33 | } | ||
| 34 | if ((word & 0x3) == 0) { | ||
| 35 | num += 2; | ||
| 36 | word >>= 2; | ||
| 37 | } | ||
| 38 | if ((word & 0x1) == 0) | ||
| 39 | num += 1; | ||
| 40 | return num; | ||
| 41 | } | ||
| 42 | |||
| 43 | #endif /* _TOOLS_LINUX_ASM_GENERIC_BITOPS___FFS_H_ */ | ||
diff --git a/tools/include/asm-generic/bitops/__fls.h b/tools/include/asm-generic/bitops/__fls.h new file mode 100644 index 000000000000..2218b9add4c1 --- /dev/null +++ b/tools/include/asm-generic/bitops/__fls.h | |||
| @@ -0,0 +1 @@ | |||
| #include <../../../../include/asm-generic/bitops/__fls.h> | |||
diff --git a/tools/include/asm-generic/bitops/atomic.h b/tools/include/asm-generic/bitops/atomic.h new file mode 100644 index 000000000000..4bccd7c3d5d6 --- /dev/null +++ b/tools/include/asm-generic/bitops/atomic.h | |||
| @@ -0,0 +1,22 @@ | |||
| 1 | #ifndef _TOOLS_LINUX_ASM_GENERIC_BITOPS_ATOMIC_H_ | ||
| 2 | #define _TOOLS_LINUX_ASM_GENERIC_BITOPS_ATOMIC_H_ | ||
| 3 | |||
| 4 | #include <asm/types.h> | ||
| 5 | |||
| 6 | static inline void set_bit(int nr, unsigned long *addr) | ||
| 7 | { | ||
| 8 | addr[nr / __BITS_PER_LONG] |= 1UL << (nr % __BITS_PER_LONG); | ||
| 9 | } | ||
| 10 | |||
| 11 | static inline void clear_bit(int nr, unsigned long *addr) | ||
| 12 | { | ||
| 13 | addr[nr / __BITS_PER_LONG] &= ~(1UL << (nr % __BITS_PER_LONG)); | ||
| 14 | } | ||
| 15 | |||
| 16 | static __always_inline int test_bit(unsigned int nr, const unsigned long *addr) | ||
| 17 | { | ||
| 18 | return ((1UL << (nr % __BITS_PER_LONG)) & | ||
| 19 | (((unsigned long *)addr)[nr / __BITS_PER_LONG])) != 0; | ||
| 20 | } | ||
| 21 | |||
| 22 | #endif /* _TOOLS_LINUX_ASM_GENERIC_BITOPS_ATOMIC_H_ */ | ||
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/include/asm-generic/bitops/fls.h b/tools/include/asm-generic/bitops/fls.h new file mode 100644 index 000000000000..dbf711a28f71 --- /dev/null +++ b/tools/include/asm-generic/bitops/fls.h | |||
| @@ -0,0 +1 @@ | |||
| #include <../../../../include/asm-generic/bitops/fls.h> | |||
diff --git a/tools/include/asm-generic/bitops/fls64.h b/tools/include/asm-generic/bitops/fls64.h new file mode 100644 index 000000000000..980b1f63c047 --- /dev/null +++ b/tools/include/asm-generic/bitops/fls64.h | |||
| @@ -0,0 +1 @@ | |||
| #include <../../../../include/asm-generic/bitops/fls64.h> | |||
diff --git a/tools/include/linux/bitops.h b/tools/include/linux/bitops.h new file mode 100644 index 000000000000..26005a15e7e2 --- /dev/null +++ b/tools/include/linux/bitops.h | |||
| @@ -0,0 +1,53 @@ | |||
| 1 | #ifndef _TOOLS_LINUX_BITOPS_H_ | ||
| 2 | #define _TOOLS_LINUX_BITOPS_H_ | ||
| 3 | |||
| 4 | #include <linux/kernel.h> | ||
| 5 | #include <linux/compiler.h> | ||
| 6 | #include <asm/hweight.h> | ||
| 7 | |||
| 8 | #ifndef __WORDSIZE | ||
| 9 | #define __WORDSIZE (__SIZEOF_LONG__ * 8) | ||
| 10 | #endif | ||
| 11 | |||
| 12 | #define BITS_PER_LONG __WORDSIZE | ||
| 13 | |||
| 14 | #define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG)) | ||
| 15 | #define BIT_WORD(nr) ((nr) / BITS_PER_LONG) | ||
| 16 | #define BITS_PER_BYTE 8 | ||
| 17 | #define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long)) | ||
| 18 | #define BITS_TO_U64(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(u64)) | ||
| 19 | #define BITS_TO_U32(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(u32)) | ||
| 20 | #define BITS_TO_BYTES(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE) | ||
| 21 | |||
| 22 | /* | ||
| 23 | * Include this here because some architectures need generic_ffs/fls in | ||
| 24 | * scope | ||
| 25 | * | ||
| 26 | * XXX: this needs to be asm/bitops.h, when we get to per arch optimizations | ||
| 27 | */ | ||
| 28 | #include <asm-generic/bitops.h> | ||
| 29 | |||
| 30 | #define for_each_set_bit(bit, addr, size) \ | ||
| 31 | for ((bit) = find_first_bit((addr), (size)); \ | ||
| 32 | (bit) < (size); \ | ||
| 33 | (bit) = find_next_bit((addr), (size), (bit) + 1)) | ||
| 34 | |||
| 35 | /* same as for_each_set_bit() but use bit as value to start with */ | ||
| 36 | #define for_each_set_bit_from(bit, addr, size) \ | ||
| 37 | for ((bit) = find_next_bit((addr), (size), (bit)); \ | ||
| 38 | (bit) < (size); \ | ||
| 39 | (bit) = find_next_bit((addr), (size), (bit) + 1)) | ||
| 40 | |||
| 41 | static inline unsigned long hweight_long(unsigned long w) | ||
| 42 | { | ||
| 43 | return sizeof(w) == 4 ? hweight32(w) : hweight64(w); | ||
| 44 | } | ||
| 45 | |||
| 46 | static inline unsigned fls_long(unsigned long l) | ||
| 47 | { | ||
| 48 | if (sizeof(l) == 4) | ||
| 49 | return fls(l); | ||
| 50 | return fls64(l); | ||
| 51 | } | ||
| 52 | |||
| 53 | #endif | ||
diff --git a/tools/include/linux/log2.h b/tools/include/linux/log2.h new file mode 100644 index 000000000000..41446668ccce --- /dev/null +++ b/tools/include/linux/log2.h | |||
| @@ -0,0 +1,185 @@ | |||
| 1 | /* Integer base 2 logarithm calculation | ||
| 2 | * | ||
| 3 | * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved. | ||
| 4 | * Written by David Howells (dhowells@redhat.com) | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or | ||
| 7 | * modify it under the terms of the GNU General Public License | ||
| 8 | * as published by the Free Software Foundation; either version | ||
| 9 | * 2 of the License, or (at your option) any later version. | ||
| 10 | */ | ||
| 11 | |||
| 12 | #ifndef _TOOLS_LINUX_LOG2_H | ||
| 13 | #define _TOOLS_LINUX_LOG2_H | ||
| 14 | |||
| 15 | /* | ||
| 16 | * deal with unrepresentable constant logarithms | ||
| 17 | */ | ||
| 18 | extern __attribute__((const, noreturn)) | ||
| 19 | int ____ilog2_NaN(void); | ||
| 20 | |||
| 21 | /* | ||
| 22 | * non-constant log of base 2 calculators | ||
| 23 | * - the arch may override these in asm/bitops.h if they can be implemented | ||
| 24 | * more efficiently than using fls() and fls64() | ||
| 25 | * - the arch is not required to handle n==0 if implementing the fallback | ||
| 26 | */ | ||
| 27 | static inline __attribute__((const)) | ||
| 28 | int __ilog2_u32(u32 n) | ||
| 29 | { | ||
| 30 | return fls(n) - 1; | ||
| 31 | } | ||
| 32 | |||
| 33 | static inline __attribute__((const)) | ||
| 34 | int __ilog2_u64(u64 n) | ||
| 35 | { | ||
| 36 | return fls64(n) - 1; | ||
| 37 | } | ||
| 38 | |||
| 39 | /* | ||
| 40 | * Determine whether some value is a power of two, where zero is | ||
| 41 | * *not* considered a power of two. | ||
| 42 | */ | ||
| 43 | |||
| 44 | static inline __attribute__((const)) | ||
| 45 | bool is_power_of_2(unsigned long n) | ||
| 46 | { | ||
| 47 | return (n != 0 && ((n & (n - 1)) == 0)); | ||
| 48 | } | ||
| 49 | |||
| 50 | /* | ||
| 51 | * round up to nearest power of two | ||
| 52 | */ | ||
| 53 | static inline __attribute__((const)) | ||
| 54 | unsigned long __roundup_pow_of_two(unsigned long n) | ||
| 55 | { | ||
| 56 | return 1UL << fls_long(n - 1); | ||
| 57 | } | ||
| 58 | |||
| 59 | /* | ||
| 60 | * round down to nearest power of two | ||
| 61 | */ | ||
| 62 | static inline __attribute__((const)) | ||
| 63 | unsigned long __rounddown_pow_of_two(unsigned long n) | ||
| 64 | { | ||
| 65 | return 1UL << (fls_long(n) - 1); | ||
| 66 | } | ||
| 67 | |||
| 68 | /** | ||
| 69 | * ilog2 - log of base 2 of 32-bit or a 64-bit unsigned value | ||
| 70 | * @n - parameter | ||
| 71 | * | ||
| 72 | * constant-capable log of base 2 calculation | ||
| 73 | * - this can be used to initialise global variables from constant data, hence | ||
| 74 | * the massive ternary operator construction | ||
| 75 | * | ||
| 76 | * selects the appropriately-sized optimised version depending on sizeof(n) | ||
| 77 | */ | ||
| 78 | #define ilog2(n) \ | ||
| 79 | ( \ | ||
| 80 | __builtin_constant_p(n) ? ( \ | ||
| 81 | (n) < 1 ? ____ilog2_NaN() : \ | ||
| 82 | (n) & (1ULL << 63) ? 63 : \ | ||
| 83 | (n) & (1ULL << 62) ? 62 : \ | ||
| 84 | (n) & (1ULL << 61) ? 61 : \ | ||
| 85 | (n) & (1ULL << 60) ? 60 : \ | ||
| 86 | (n) & (1ULL << 59) ? 59 : \ | ||
| 87 | (n) & (1ULL << 58) ? 58 : \ | ||
| 88 | (n) & (1ULL << 57) ? 57 : \ | ||
| 89 | (n) & (1ULL << 56) ? 56 : \ | ||
| 90 | (n) & (1ULL << 55) ? 55 : \ | ||
| 91 | (n) & (1ULL << 54) ? 54 : \ | ||
| 92 | (n) & (1ULL << 53) ? 53 : \ | ||
| 93 | (n) & (1ULL << 52) ? 52 : \ | ||
| 94 | (n) & (1ULL << 51) ? 51 : \ | ||
| 95 | (n) & (1ULL << 50) ? 50 : \ | ||
| 96 | (n) & (1ULL << 49) ? 49 : \ | ||
| 97 | (n) & (1ULL << 48) ? 48 : \ | ||
| 98 | (n) & (1ULL << 47) ? 47 : \ | ||
| 99 | (n) & (1ULL << 46) ? 46 : \ | ||
| 100 | (n) & (1ULL << 45) ? 45 : \ | ||
| 101 | (n) & (1ULL << 44) ? 44 : \ | ||
| 102 | (n) & (1ULL << 43) ? 43 : \ | ||
| 103 | (n) & (1ULL << 42) ? 42 : \ | ||
| 104 | (n) & (1ULL << 41) ? 41 : \ | ||
| 105 | (n) & (1ULL << 40) ? 40 : \ | ||
| 106 | (n) & (1ULL << 39) ? 39 : \ | ||
| 107 | (n) & (1ULL << 38) ? 38 : \ | ||
| 108 | (n) & (1ULL << 37) ? 37 : \ | ||
| 109 | (n) & (1ULL << 36) ? 36 : \ | ||
| 110 | (n) & (1ULL << 35) ? 35 : \ | ||
| 111 | (n) & (1ULL << 34) ? 34 : \ | ||
| 112 | (n) & (1ULL << 33) ? 33 : \ | ||
| 113 | (n) & (1ULL << 32) ? 32 : \ | ||
| 114 | (n) & (1ULL << 31) ? 31 : \ | ||
| 115 | (n) & (1ULL << 30) ? 30 : \ | ||
| 116 | (n) & (1ULL << 29) ? 29 : \ | ||
| 117 | (n) & (1ULL << 28) ? 28 : \ | ||
| 118 | (n) & (1ULL << 27) ? 27 : \ | ||
| 119 | (n) & (1ULL << 26) ? 26 : \ | ||
| 120 | (n) & (1ULL << 25) ? 25 : \ | ||
| 121 | (n) & (1ULL << 24) ? 24 : \ | ||
| 122 | (n) & (1ULL << 23) ? 23 : \ | ||
| 123 | (n) & (1ULL << 22) ? 22 : \ | ||
| 124 | (n) & (1ULL << 21) ? 21 : \ | ||
| 125 | (n) & (1ULL << 20) ? 20 : \ | ||
| 126 | (n) & (1ULL << 19) ? 19 : \ | ||
| 127 | (n) & (1ULL << 18) ? 18 : \ | ||
| 128 | (n) & (1ULL << 17) ? 17 : \ | ||
| 129 | (n) & (1ULL << 16) ? 16 : \ | ||
| 130 | (n) & (1ULL << 15) ? 15 : \ | ||
| 131 | (n) & (1ULL << 14) ? 14 : \ | ||
| 132 | (n) & (1ULL << 13) ? 13 : \ | ||
| 133 | (n) & (1ULL << 12) ? 12 : \ | ||
| 134 | (n) & (1ULL << 11) ? 11 : \ | ||
| 135 | (n) & (1ULL << 10) ? 10 : \ | ||
| 136 | (n) & (1ULL << 9) ? 9 : \ | ||
| 137 | (n) & (1ULL << 8) ? 8 : \ | ||
| 138 | (n) & (1ULL << 7) ? 7 : \ | ||
| 139 | (n) & (1ULL << 6) ? 6 : \ | ||
| 140 | (n) & (1ULL << 5) ? 5 : \ | ||
| 141 | (n) & (1ULL << 4) ? 4 : \ | ||
| 142 | (n) & (1ULL << 3) ? 3 : \ | ||
| 143 | (n) & (1ULL << 2) ? 2 : \ | ||
| 144 | (n) & (1ULL << 1) ? 1 : \ | ||
| 145 | (n) & (1ULL << 0) ? 0 : \ | ||
| 146 | ____ilog2_NaN() \ | ||
| 147 | ) : \ | ||
| 148 | (sizeof(n) <= 4) ? \ | ||
| 149 | __ilog2_u32(n) : \ | ||
| 150 | __ilog2_u64(n) \ | ||
| 151 | ) | ||
| 152 | |||
| 153 | /** | ||
| 154 | * roundup_pow_of_two - round the given value up to nearest power of two | ||
| 155 | * @n - parameter | ||
| 156 | * | ||
| 157 | * round the given value up to the nearest power of two | ||
| 158 | * - the result is undefined when n == 0 | ||
| 159 | * - this can be used to initialise global variables from constant data | ||
| 160 | */ | ||
| 161 | #define roundup_pow_of_two(n) \ | ||
| 162 | ( \ | ||
| 163 | __builtin_constant_p(n) ? ( \ | ||
| 164 | (n == 1) ? 1 : \ | ||
| 165 | (1UL << (ilog2((n) - 1) + 1)) \ | ||
| 166 | ) : \ | ||
| 167 | __roundup_pow_of_two(n) \ | ||
| 168 | ) | ||
| 169 | |||
| 170 | /** | ||
| 171 | * rounddown_pow_of_two - round the given value down to nearest power of two | ||
| 172 | * @n - parameter | ||
| 173 | * | ||
| 174 | * round the given value down to the nearest power of two | ||
| 175 | * - the result is undefined when n == 0 | ||
| 176 | * - this can be used to initialise global variables from constant data | ||
| 177 | */ | ||
| 178 | #define rounddown_pow_of_two(n) \ | ||
| 179 | ( \ | ||
| 180 | __builtin_constant_p(n) ? ( \ | ||
| 181 | (1UL << ilog2(n))) : \ | ||
| 182 | __rounddown_pow_of_two(n) \ | ||
| 183 | ) | ||
| 184 | |||
| 185 | #endif /* _TOOLS_LINUX_LOG2_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 344c4d3d0a4a..83e2887f91a3 100644 --- a/tools/perf/MANIFEST +++ b/tools/perf/MANIFEST | |||
| @@ -4,17 +4,31 @@ 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 |
| 9 | tools/include/asm-generic/bitops/atomic.h | ||
| 10 | tools/include/asm-generic/bitops/__ffs.h | ||
| 11 | tools/include/asm-generic/bitops/__fls.h | ||
| 12 | tools/include/asm-generic/bitops/find.h | ||
| 13 | tools/include/asm-generic/bitops/fls64.h | ||
| 14 | tools/include/asm-generic/bitops/fls.h | ||
| 15 | tools/include/asm-generic/bitops.h | ||
| 16 | tools/include/linux/bitops.h | ||
| 8 | tools/include/linux/compiler.h | 17 | tools/include/linux/compiler.h |
| 9 | tools/include/linux/hash.h | ||
| 10 | tools/include/linux/export.h | 18 | tools/include/linux/export.h |
| 19 | tools/include/linux/hash.h | ||
| 20 | tools/include/linux/log2.h | ||
| 11 | tools/include/linux/types.h | 21 | tools/include/linux/types.h |
| 22 | include/asm-generic/bitops/fls64.h | ||
| 23 | include/asm-generic/bitops/__fls.h | ||
| 24 | include/asm-generic/bitops/fls.h | ||
| 12 | include/linux/const.h | 25 | include/linux/const.h |
| 13 | include/linux/perf_event.h | 26 | include/linux/perf_event.h |
| 14 | include/linux/rbtree.h | 27 | include/linux/rbtree.h |
| 15 | include/linux/list.h | 28 | include/linux/list.h |
| 16 | include/linux/hash.h | 29 | include/linux/hash.h |
| 17 | include/linux/stringify.h | 30 | include/linux/stringify.h |
| 31 | lib/find_next_bit.c | ||
| 18 | lib/rbtree.c | 32 | lib/rbtree.c |
| 19 | include/linux/swab.h | 33 | include/linux/swab.h |
| 20 | arch/*/include/asm/unistd*.h | 34 | arch/*/include/asm/unistd*.h |
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index 763e68fb5767..67a03a825b3c 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf | |||
| @@ -231,8 +231,16 @@ LIB_H += ../../include/uapi/linux/const.h | |||
| 231 | LIB_H += ../include/linux/hash.h | 231 | LIB_H += ../include/linux/hash.h |
| 232 | LIB_H += ../../include/linux/stringify.h | 232 | 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 += ../include/linux/bitops.h |
| 235 | LIB_H += ../include/asm-generic/bitops/atomic.h | ||
| 236 | LIB_H += ../include/asm-generic/bitops/find.h | ||
| 237 | LIB_H += ../include/asm-generic/bitops/fls64.h | ||
| 238 | LIB_H += ../include/asm-generic/bitops/fls.h | ||
| 239 | LIB_H += ../include/asm-generic/bitops/__ffs.h | ||
| 240 | LIB_H += ../include/asm-generic/bitops/__fls.h | ||
| 241 | LIB_H += ../include/asm-generic/bitops.h | ||
| 235 | LIB_H += ../include/linux/compiler.h | 242 | LIB_H += ../include/linux/compiler.h |
| 243 | LIB_H += ../include/linux/log2.h | ||
| 236 | LIB_H += util/include/linux/const.h | 244 | LIB_H += util/include/linux/const.h |
| 237 | LIB_H += util/include/linux/ctype.h | 245 | LIB_H += util/include/linux/ctype.h |
| 238 | LIB_H += util/include/linux/kernel.h | 246 | LIB_H += util/include/linux/kernel.h |
| @@ -335,6 +343,7 @@ LIB_OBJS += $(OUTPUT)util/event.o | |||
| 335 | LIB_OBJS += $(OUTPUT)util/evlist.o | 343 | LIB_OBJS += $(OUTPUT)util/evlist.o |
| 336 | LIB_OBJS += $(OUTPUT)util/evsel.o | 344 | LIB_OBJS += $(OUTPUT)util/evsel.o |
| 337 | LIB_OBJS += $(OUTPUT)util/exec_cmd.o | 345 | LIB_OBJS += $(OUTPUT)util/exec_cmd.o |
| 346 | LIB_OBJS += $(OUTPUT)util/find_next_bit.o | ||
| 338 | LIB_OBJS += $(OUTPUT)util/help.o | 347 | LIB_OBJS += $(OUTPUT)util/help.o |
| 339 | LIB_OBJS += $(OUTPUT)util/kallsyms.o | 348 | LIB_OBJS += $(OUTPUT)util/kallsyms.o |
| 340 | LIB_OBJS += $(OUTPUT)util/levenshtein.o | 349 | LIB_OBJS += $(OUTPUT)util/levenshtein.o |
| @@ -734,6 +743,9 @@ $(OUTPUT)util/kallsyms.o: ../lib/symbol/kallsyms.c $(OUTPUT)PERF-CFLAGS | |||
| 734 | $(OUTPUT)util/rbtree.o: ../../lib/rbtree.c $(OUTPUT)PERF-CFLAGS | 743 | $(OUTPUT)util/rbtree.o: ../../lib/rbtree.c $(OUTPUT)PERF-CFLAGS |
| 735 | $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -Wno-unused-parameter -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $< | 744 | $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -Wno-unused-parameter -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $< |
| 736 | 745 | ||
| 746 | $(OUTPUT)util/find_next_bit.o: ../lib/util/find_next_bit.c $(OUTPUT)PERF-CFLAGS | ||
| 747 | $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -Wno-unused-parameter -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $< | ||
| 748 | |||
| 737 | $(OUTPUT)util/parse-events.o: util/parse-events.c $(OUTPUT)PERF-CFLAGS | 749 | $(OUTPUT)util/parse-events.o: util/parse-events.c $(OUTPUT)PERF-CFLAGS |
| 738 | $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -Wno-redundant-decls $< | 750 | $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -Wno-redundant-decls $< |
| 739 | 751 | ||
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 327541e43c7f..badfabc6a01f 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c | |||
| @@ -2485,7 +2485,7 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused) | |||
| 2485 | .user_freq = UINT_MAX, | 2485 | .user_freq = UINT_MAX, |
| 2486 | .user_interval = ULLONG_MAX, | 2486 | .user_interval = ULLONG_MAX, |
| 2487 | .no_buffering = true, | 2487 | .no_buffering = true, |
| 2488 | .mmap_pages = 1024, | 2488 | .mmap_pages = UINT_MAX, |
| 2489 | }, | 2489 | }, |
| 2490 | .output = stdout, | 2490 | .output = stdout, |
| 2491 | .show_comm = true, | 2491 | .show_comm = true, |
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index bb5dfc5d1e75..cbab1fb77b1d 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c | |||
| @@ -25,6 +25,7 @@ | |||
| 25 | 25 | ||
| 26 | #include <linux/bitops.h> | 26 | #include <linux/bitops.h> |
| 27 | #include <linux/hash.h> | 27 | #include <linux/hash.h> |
| 28 | #include <linux/log2.h> | ||
| 28 | 29 | ||
| 29 | static void perf_evlist__mmap_put(struct perf_evlist *evlist, int idx); | 30 | static void perf_evlist__mmap_put(struct perf_evlist *evlist, int idx); |
| 30 | static void __perf_evlist__munmap(struct perf_evlist *evlist, int idx); | 31 | static void __perf_evlist__munmap(struct perf_evlist *evlist, int idx); |
| @@ -893,10 +894,24 @@ out_unmap: | |||
| 893 | 894 | ||
| 894 | static size_t perf_evlist__mmap_size(unsigned long pages) | 895 | static size_t perf_evlist__mmap_size(unsigned long pages) |
| 895 | { | 896 | { |
| 896 | /* 512 kiB: default amount of unprivileged mlocked memory */ | 897 | if (pages == UINT_MAX) { |
| 897 | if (pages == UINT_MAX) | 898 | int max; |
| 898 | pages = (512 * 1024) / page_size; | 899 | |
| 899 | else if (!is_power_of_2(pages)) | 900 | if (sysctl__read_int("kernel/perf_event_mlock_kb", &max) < 0) { |
| 901 | /* | ||
| 902 | * Pick a once upon a time good value, i.e. things look | ||
| 903 | * strange since we can't read a sysctl value, but lets not | ||
| 904 | * die yet... | ||
| 905 | */ | ||
| 906 | max = 512; | ||
| 907 | } else { | ||
| 908 | max -= (page_size / 1024); | ||
| 909 | } | ||
| 910 | |||
| 911 | pages = (max * 1024) / page_size; | ||
| 912 | if (!is_power_of_2(pages)) | ||
| 913 | pages = rounddown_pow_of_two(pages); | ||
| 914 | } else if (!is_power_of_2(pages)) | ||
| 900 | return 0; | 915 | return 0; |
| 901 | 916 | ||
| 902 | return (pages + 1) * page_size; | 917 | return (pages + 1) * page_size; |
| @@ -933,7 +948,7 @@ static long parse_pages_arg(const char *str, unsigned long min, | |||
| 933 | /* leave number of pages at 0 */ | 948 | /* leave number of pages at 0 */ |
| 934 | } else if (!is_power_of_2(pages)) { | 949 | } else if (!is_power_of_2(pages)) { |
| 935 | /* round pages up to next power of 2 */ | 950 | /* round pages up to next power of 2 */ |
| 936 | pages = next_pow2_l(pages); | 951 | pages = roundup_pow_of_two(pages); |
| 937 | if (!pages) | 952 | if (!pages) |
| 938 | return -EINVAL; | 953 | return -EINVAL; |
| 939 | pr_info("rounding mmap pages size to %lu bytes (%lu pages)\n", | 954 | pr_info("rounding mmap pages size to %lu bytes (%lu pages)\n", |
| @@ -1487,16 +1502,25 @@ int perf_evlist__strerror_open(struct perf_evlist *evlist __maybe_unused, | |||
| 1487 | int perf_evlist__strerror_mmap(struct perf_evlist *evlist, int err, char *buf, size_t size) | 1502 | int perf_evlist__strerror_mmap(struct perf_evlist *evlist, int err, char *buf, size_t size) |
| 1488 | { | 1503 | { |
| 1489 | char sbuf[STRERR_BUFSIZE], *emsg = strerror_r(err, sbuf, sizeof(sbuf)); | 1504 | char sbuf[STRERR_BUFSIZE], *emsg = strerror_r(err, sbuf, sizeof(sbuf)); |
| 1490 | int value; | 1505 | int pages_attempted = evlist->mmap_len / 1024, pages_max_per_user, printed = 0; |
| 1491 | 1506 | ||
| 1492 | switch (err) { | 1507 | switch (err) { |
| 1493 | case EPERM: | 1508 | case EPERM: |
| 1494 | sysctl__read_int("kernel/perf_event_mlock_kb", &value); | 1509 | sysctl__read_int("kernel/perf_event_mlock_kb", &pages_max_per_user); |
| 1495 | scnprintf(buf, size, "Error:\t%s.\n" | 1510 | printed += scnprintf(buf + printed, size - printed, |
| 1511 | "Error:\t%s.\n" | ||
| 1496 | "Hint:\tCheck /proc/sys/kernel/perf_event_mlock_kb (%d kB) setting.\n" | 1512 | "Hint:\tCheck /proc/sys/kernel/perf_event_mlock_kb (%d kB) setting.\n" |
| 1497 | "Hint:\tTried using %zd kB.\n" | 1513 | "Hint:\tTried using %zd kB.\n", |
| 1498 | "Hint:\tTry using a bigger -m/--mmap-pages value.", | 1514 | emsg, pages_max_per_user, pages_attempted); |
| 1499 | emsg, value, evlist->mmap_len / 1024); | 1515 | |
| 1516 | if (pages_attempted >= pages_max_per_user) { | ||
| 1517 | printed += scnprintf(buf + printed, size - printed, | ||
| 1518 | "Hint:\tTry 'sudo sh -c \"echo %d > /proc/sys/kernel/perf_event_mlock_kb\"', or\n", | ||
| 1519 | pages_max_per_user + pages_attempted); | ||
| 1520 | } | ||
| 1521 | |||
| 1522 | printed += scnprintf(buf + printed, size - printed, | ||
| 1523 | "Hint:\tTry using a smaller -m/--mmap-pages value."); | ||
| 1500 | break; | 1524 | break; |
| 1501 | default: | 1525 | default: |
| 1502 | scnprintf(buf, size, "%s", emsg); | 1526 | scnprintf(buf, size, "%s", emsg); |
diff --git a/tools/perf/util/include/linux/bitops.h b/tools/perf/util/include/linux/bitops.h deleted file mode 100644 index c3294163de17..000000000000 --- a/tools/perf/util/include/linux/bitops.h +++ /dev/null | |||
| @@ -1,162 +0,0 @@ | |||
| 1 | #ifndef _PERF_LINUX_BITOPS_H_ | ||
| 2 | #define _PERF_LINUX_BITOPS_H_ | ||
| 3 | |||
| 4 | #include <linux/kernel.h> | ||
| 5 | #include <linux/compiler.h> | ||
| 6 | #include <asm/hweight.h> | ||
| 7 | |||
| 8 | #ifndef __WORDSIZE | ||
| 9 | #define __WORDSIZE (__SIZEOF_LONG__ * 8) | ||
| 10 | #endif | ||
| 11 | |||
| 12 | #define BITS_PER_LONG __WORDSIZE | ||
| 13 | #define BITS_PER_BYTE 8 | ||
| 14 | #define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long)) | ||
| 15 | #define BITS_TO_U64(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(u64)) | ||
| 16 | #define BITS_TO_U32(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(u32)) | ||
| 17 | #define BITS_TO_BYTES(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE) | ||
| 18 | #define BIT_WORD(nr) ((nr) / BITS_PER_LONG) | ||
| 19 | #define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG)) | ||
| 20 | |||
| 21 | #define for_each_set_bit(bit, addr, size) \ | ||
| 22 | for ((bit) = find_first_bit((addr), (size)); \ | ||
| 23 | (bit) < (size); \ | ||
| 24 | (bit) = find_next_bit((addr), (size), (bit) + 1)) | ||
| 25 | |||
| 26 | /* same as for_each_set_bit() but use bit as value to start with */ | ||
| 27 | #define for_each_set_bit_from(bit, addr, size) \ | ||
| 28 | for ((bit) = find_next_bit((addr), (size), (bit)); \ | ||
| 29 | (bit) < (size); \ | ||
| 30 | (bit) = find_next_bit((addr), (size), (bit) + 1)) | ||
| 31 | |||
| 32 | static inline void set_bit(int nr, unsigned long *addr) | ||
| 33 | { | ||
| 34 | addr[nr / BITS_PER_LONG] |= 1UL << (nr % BITS_PER_LONG); | ||
| 35 | } | ||
| 36 | |||
| 37 | static inline void clear_bit(int nr, unsigned long *addr) | ||
| 38 | { | ||
| 39 | addr[nr / BITS_PER_LONG] &= ~(1UL << (nr % BITS_PER_LONG)); | ||
| 40 | } | ||
| 41 | |||
| 42 | static __always_inline int test_bit(unsigned int nr, const unsigned long *addr) | ||
| 43 | { | ||
| 44 | return ((1UL << (nr % BITS_PER_LONG)) & | ||
| 45 | (((unsigned long *)addr)[nr / BITS_PER_LONG])) != 0; | ||
| 46 | } | ||
| 47 | |||
| 48 | static inline unsigned long hweight_long(unsigned long w) | ||
| 49 | { | ||
| 50 | return sizeof(w) == 4 ? hweight32(w) : hweight64(w); | ||
| 51 | } | ||
| 52 | |||
| 53 | #define BITOP_WORD(nr) ((nr) / BITS_PER_LONG) | ||
| 54 | |||
| 55 | /** | ||
| 56 | * __ffs - find first bit in word. | ||
| 57 | * @word: The word to search | ||
| 58 | * | ||
| 59 | * Undefined if no bit exists, so code should check against 0 first. | ||
| 60 | */ | ||
| 61 | static __always_inline unsigned long __ffs(unsigned long word) | ||
| 62 | { | ||
| 63 | int num = 0; | ||
| 64 | |||
| 65 | #if BITS_PER_LONG == 64 | ||
| 66 | if ((word & 0xffffffff) == 0) { | ||
| 67 | num += 32; | ||
| 68 | word >>= 32; | ||
| 69 | } | ||
| 70 | #endif | ||
| 71 | if ((word & 0xffff) == 0) { | ||
| 72 | num += 16; | ||
| 73 | word >>= 16; | ||
| 74 | } | ||
| 75 | if ((word & 0xff) == 0) { | ||
| 76 | num += 8; | ||
| 77 | word >>= 8; | ||
| 78 | } | ||
| 79 | if ((word & 0xf) == 0) { | ||
| 80 | num += 4; | ||
| 81 | word >>= 4; | ||
| 82 | } | ||
| 83 | if ((word & 0x3) == 0) { | ||
| 84 | num += 2; | ||
| 85 | word >>= 2; | ||
| 86 | } | ||
| 87 | if ((word & 0x1) == 0) | ||
| 88 | num += 1; | ||
| 89 | return num; | ||
| 90 | } | ||
| 91 | |||
| 92 | typedef const unsigned long __attribute__((__may_alias__)) long_alias_t; | ||
| 93 | |||
| 94 | /* | ||
| 95 | * Find the first set bit in a memory region. | ||
| 96 | */ | ||
| 97 | static inline unsigned long | ||
| 98 | find_first_bit(const unsigned long *addr, unsigned long size) | ||
| 99 | { | ||
| 100 | long_alias_t *p = (long_alias_t *) addr; | ||
| 101 | unsigned long result = 0; | ||
| 102 | unsigned long tmp; | ||
| 103 | |||
| 104 | while (size & ~(BITS_PER_LONG-1)) { | ||
| 105 | if ((tmp = *(p++))) | ||
| 106 | goto found; | ||
| 107 | result += BITS_PER_LONG; | ||
| 108 | size -= BITS_PER_LONG; | ||
| 109 | } | ||
| 110 | if (!size) | ||
| 111 | return result; | ||
| 112 | |||
| 113 | tmp = (*p) & (~0UL >> (BITS_PER_LONG - size)); | ||
| 114 | if (tmp == 0UL) /* Are any bits set? */ | ||
| 115 | return result + size; /* Nope. */ | ||
| 116 | found: | ||
| 117 | return result + __ffs(tmp); | ||
| 118 | } | ||
| 119 | |||
| 120 | /* | ||
| 121 | * Find the next set bit in a memory region. | ||
| 122 | */ | ||
| 123 | static inline unsigned long | ||
| 124 | find_next_bit(const unsigned long *addr, unsigned long size, unsigned long offset) | ||
| 125 | { | ||
| 126 | const unsigned long *p = addr + BITOP_WORD(offset); | ||
| 127 | unsigned long result = offset & ~(BITS_PER_LONG-1); | ||
| 128 | unsigned long tmp; | ||
| 129 | |||
| 130 | if (offset >= size) | ||
| 131 | return size; | ||
| 132 | size -= result; | ||
| 133 | offset %= BITS_PER_LONG; | ||
| 134 | if (offset) { | ||
| 135 | tmp = *(p++); | ||
| 136 | tmp &= (~0UL << offset); | ||
| 137 | if (size < BITS_PER_LONG) | ||
| 138 | goto found_first; | ||
| 139 | if (tmp) | ||
| 140 | goto found_middle; | ||
| 141 | size -= BITS_PER_LONG; | ||
| 142 | result += BITS_PER_LONG; | ||
| 143 | } | ||
| 144 | while (size & ~(BITS_PER_LONG-1)) { | ||
| 145 | if ((tmp = *(p++))) | ||
| 146 | goto found_middle; | ||
| 147 | result += BITS_PER_LONG; | ||
| 148 | size -= BITS_PER_LONG; | ||
| 149 | } | ||
| 150 | if (!size) | ||
| 151 | return result; | ||
| 152 | tmp = *p; | ||
| 153 | |||
| 154 | found_first: | ||
| 155 | tmp &= (~0UL >> (BITS_PER_LONG - size)); | ||
| 156 | if (tmp == 0UL) /* Are any bits set? */ | ||
| 157 | return result + size; /* Nope. */ | ||
| 158 | found_middle: | ||
| 159 | return result + __ffs(tmp); | ||
| 160 | } | ||
| 161 | |||
| 162 | #endif | ||
diff --git a/tools/perf/util/symbol-minimal.c b/tools/perf/util/symbol-minimal.c index fa585c63f56a..d7efb03b3f9a 100644 --- a/tools/perf/util/symbol-minimal.c +++ b/tools/perf/util/symbol-minimal.c | |||
| @@ -129,6 +129,7 @@ int filename__read_build_id(const char *filename, void *bf, size_t size) | |||
| 129 | 129 | ||
| 130 | for (i = 0, phdr = buf; i < ehdr.e_phnum; i++, phdr++) { | 130 | for (i = 0, phdr = buf; i < ehdr.e_phnum; i++, phdr++) { |
| 131 | void *tmp; | 131 | void *tmp; |
| 132 | long offset; | ||
| 132 | 133 | ||
| 133 | if (need_swap) { | 134 | if (need_swap) { |
| 134 | phdr->p_type = bswap_32(phdr->p_type); | 135 | phdr->p_type = bswap_32(phdr->p_type); |
| @@ -140,12 +141,13 @@ int filename__read_build_id(const char *filename, void *bf, size_t size) | |||
| 140 | continue; | 141 | continue; |
| 141 | 142 | ||
| 142 | buf_size = phdr->p_filesz; | 143 | buf_size = phdr->p_filesz; |
| 144 | offset = phdr->p_offset; | ||
| 143 | tmp = realloc(buf, buf_size); | 145 | tmp = realloc(buf, buf_size); |
| 144 | if (tmp == NULL) | 146 | if (tmp == NULL) |
| 145 | goto out_free; | 147 | goto out_free; |
| 146 | 148 | ||
| 147 | buf = tmp; | 149 | buf = tmp; |
| 148 | fseek(fp, phdr->p_offset, SEEK_SET); | 150 | fseek(fp, offset, SEEK_SET); |
| 149 | if (fread(buf, buf_size, 1, fp) != 1) | 151 | if (fread(buf, buf_size, 1, fp) != 1) |
| 150 | goto out_free; | 152 | goto out_free; |
| 151 | 153 | ||
| @@ -178,6 +180,7 @@ int filename__read_build_id(const char *filename, void *bf, size_t size) | |||
| 178 | 180 | ||
| 179 | for (i = 0, phdr = buf; i < ehdr.e_phnum; i++, phdr++) { | 181 | for (i = 0, phdr = buf; i < ehdr.e_phnum; i++, phdr++) { |
| 180 | void *tmp; | 182 | void *tmp; |
| 183 | long offset; | ||
| 181 | 184 | ||
| 182 | if (need_swap) { | 185 | if (need_swap) { |
| 183 | phdr->p_type = bswap_32(phdr->p_type); | 186 | phdr->p_type = bswap_32(phdr->p_type); |
| @@ -189,12 +192,13 @@ int filename__read_build_id(const char *filename, void *bf, size_t size) | |||
| 189 | continue; | 192 | continue; |
| 190 | 193 | ||
| 191 | buf_size = phdr->p_filesz; | 194 | buf_size = phdr->p_filesz; |
| 195 | offset = phdr->p_offset; | ||
| 192 | tmp = realloc(buf, buf_size); | 196 | tmp = realloc(buf, buf_size); |
| 193 | if (tmp == NULL) | 197 | if (tmp == NULL) |
| 194 | goto out_free; | 198 | goto out_free; |
| 195 | 199 | ||
| 196 | buf = tmp; | 200 | buf = tmp; |
| 197 | fseek(fp, phdr->p_offset, SEEK_SET); | 201 | fseek(fp, offset, SEEK_SET); |
| 198 | if (fread(buf, buf_size, 1, fp) != 1) | 202 | if (fread(buf, buf_size, 1, fp) != 1) |
| 199 | goto out_free; | 203 | goto out_free; |
| 200 | 204 | ||
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h index 008b361b1758..be198ac27031 100644 --- a/tools/perf/util/util.h +++ b/tools/perf/util/util.h | |||
| @@ -269,35 +269,6 @@ void event_attr_init(struct perf_event_attr *attr); | |||
| 269 | #define _STR(x) #x | 269 | #define _STR(x) #x |
| 270 | #define STR(x) _STR(x) | 270 | #define STR(x) _STR(x) |
| 271 | 271 | ||
| 272 | /* | ||
| 273 | * Determine whether some value is a power of two, where zero is | ||
| 274 | * *not* considered a power of two. | ||
| 275 | */ | ||
| 276 | |||
| 277 | static inline __attribute__((const)) | ||
| 278 | bool is_power_of_2(unsigned long n) | ||
| 279 | { | ||
| 280 | return (n != 0 && ((n & (n - 1)) == 0)); | ||
| 281 | } | ||
| 282 | |||
| 283 | static inline unsigned next_pow2(unsigned x) | ||
| 284 | { | ||
| 285 | if (!x) | ||
| 286 | return 1; | ||
| 287 | return 1ULL << (32 - __builtin_clz(x - 1)); | ||
| 288 | } | ||
| 289 | |||
| 290 | static inline unsigned long next_pow2_l(unsigned long x) | ||
| 291 | { | ||
| 292 | #if BITS_PER_LONG == 64 | ||
| 293 | if (x <= (1UL << 31)) | ||
| 294 | return next_pow2(x); | ||
| 295 | return (unsigned long)next_pow2(x >> 32) << 32; | ||
| 296 | #else | ||
| 297 | return next_pow2(x); | ||
| 298 | #endif | ||
| 299 | } | ||
| 300 | |||
| 301 | size_t hex_width(u64 v); | 272 | size_t hex_width(u64 v); |
| 302 | int hex2u64(const char *ptr, u64 *val); | 273 | int hex2u64(const char *ptr, u64 *val); |
| 303 | 274 | ||
