Commit | Line | Data |
---|---|---|
b2441318 | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
fb72014d ACM |
2 | #ifndef _PERF_BITOPS_H |
3 | #define _PERF_BITOPS_H | |
4 | ||
5 | #include <string.h> | |
6 | #include <linux/bitops.h> | |
98c03296 | 7 | #include <stdlib.h> |
c68a2aab | 8 | #include <linux/kernel.h> |
fb72014d | 9 | |
d944c4ee BP |
10 | #define DECLARE_BITMAP(name,bits) \ |
11 | unsigned long name[BITS_TO_LONGS(bits)] | |
12 | ||
fb72014d | 13 | int __bitmap_weight(const unsigned long *bitmap, int bits); |
850f8127 JO |
14 | void __bitmap_or(unsigned long *dst, const unsigned long *bitmap1, |
15 | const unsigned long *bitmap2, int bits); | |
741c74f5 JO |
16 | int __bitmap_and(unsigned long *dst, const unsigned long *bitmap1, |
17 | const unsigned long *bitmap2, unsigned int bits); | |
fb72014d | 18 | |
64af4e0d ACM |
19 | #define BITMAP_FIRST_WORD_MASK(start) (~0UL << ((start) & (BITS_PER_LONG - 1))) |
20 | ||
fb72014d ACM |
21 | #define BITMAP_LAST_WORD_MASK(nbits) \ |
22 | ( \ | |
23 | ((nbits) % BITS_PER_LONG) ? \ | |
24 | (1UL<<((nbits) % BITS_PER_LONG))-1 : ~0UL \ | |
25 | ) | |
26 | ||
27 | #define small_const_nbits(nbits) \ | |
28 | (__builtin_constant_p(nbits) && (nbits) <= BITS_PER_LONG) | |
29 | ||
30 | static inline void bitmap_zero(unsigned long *dst, int nbits) | |
31 | { | |
32 | if (small_const_nbits(nbits)) | |
33 | *dst = 0UL; | |
34 | else { | |
35 | int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long); | |
36 | memset(dst, 0, len); | |
37 | } | |
38 | } | |
39 | ||
b328daf3 MW |
40 | static inline void bitmap_fill(unsigned long *dst, unsigned int nbits) |
41 | { | |
42 | unsigned int nlongs = BITS_TO_LONGS(nbits); | |
43 | if (!small_const_nbits(nbits)) { | |
44 | unsigned int len = (nlongs - 1) * sizeof(unsigned long); | |
45 | memset(dst, 0xff, len); | |
46 | } | |
47 | dst[nlongs - 1] = BITMAP_LAST_WORD_MASK(nbits); | |
48 | } | |
49 | ||
50 | static inline int bitmap_empty(const unsigned long *src, unsigned nbits) | |
51 | { | |
52 | if (small_const_nbits(nbits)) | |
53 | return ! (*src & BITMAP_LAST_WORD_MASK(nbits)); | |
54 | ||
55 | return find_first_bit(src, nbits) == nbits; | |
56 | } | |
57 | ||
58 | static inline int bitmap_full(const unsigned long *src, unsigned int nbits) | |
59 | { | |
60 | if (small_const_nbits(nbits)) | |
61 | return ! (~(*src) & BITMAP_LAST_WORD_MASK(nbits)); | |
62 | ||
63 | return find_first_zero_bit(src, nbits) == nbits; | |
64 | } | |
65 | ||
fb72014d ACM |
66 | static inline int bitmap_weight(const unsigned long *src, int nbits) |
67 | { | |
68 | if (small_const_nbits(nbits)) | |
69 | return hweight_long(*src & BITMAP_LAST_WORD_MASK(nbits)); | |
70 | return __bitmap_weight(src, nbits); | |
71 | } | |
72 | ||
850f8127 JO |
73 | static inline void bitmap_or(unsigned long *dst, const unsigned long *src1, |
74 | const unsigned long *src2, int nbits) | |
75 | { | |
76 | if (small_const_nbits(nbits)) | |
77 | *dst = *src1 | *src2; | |
78 | else | |
79 | __bitmap_or(dst, src1, src2, nbits); | |
80 | } | |
81 | ||
416c419c JO |
82 | /** |
83 | * test_and_set_bit - Set a bit and return its old value | |
84 | * @nr: Bit to set | |
85 | * @addr: Address to count from | |
86 | */ | |
87 | static inline int test_and_set_bit(int nr, unsigned long *addr) | |
88 | { | |
89 | unsigned long mask = BIT_MASK(nr); | |
90 | unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); | |
91 | unsigned long old; | |
92 | ||
93 | old = *p; | |
94 | *p = old | mask; | |
95 | ||
96 | return (old & mask) != 0; | |
97 | } | |
98 | ||
98c03296 JO |
99 | /** |
100 | * bitmap_alloc - Allocate bitmap | |
101 | * @nr: Bit to set | |
102 | */ | |
103 | static inline unsigned long *bitmap_alloc(int nbits) | |
104 | { | |
105 | return calloc(1, BITS_TO_LONGS(nbits) * sizeof(unsigned long)); | |
106 | } | |
107 | ||
820d12b7 JO |
108 | /* |
109 | * bitmap_scnprintf - print bitmap list into buffer | |
110 | * @bitmap: bitmap | |
111 | * @nbits: size of bitmap | |
112 | * @buf: buffer to store output | |
113 | * @size: size of @buf | |
114 | */ | |
115 | size_t bitmap_scnprintf(unsigned long *bitmap, int nbits, | |
116 | char *buf, size_t size); | |
117 | ||
741c74f5 JO |
118 | /** |
119 | * bitmap_and - Do logical and on bitmaps | |
120 | * @dst: resulting bitmap | |
121 | * @src1: operand 1 | |
122 | * @src2: operand 2 | |
123 | * @nbits: size of bitmap | |
124 | */ | |
125 | static inline int bitmap_and(unsigned long *dst, const unsigned long *src1, | |
126 | const unsigned long *src2, unsigned int nbits) | |
127 | { | |
128 | if (small_const_nbits(nbits)) | |
129 | return (*dst = *src1 & *src2 & BITMAP_LAST_WORD_MASK(nbits)) != 0; | |
130 | return __bitmap_and(dst, src1, src2, nbits); | |
131 | } | |
132 | ||
fb72014d | 133 | #endif /* _PERF_BITOPS_H */ |