aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/bitops.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux/bitops.h')
-rw-r--r--include/linux/bitops.h117
1 files changed, 13 insertions, 104 deletions
diff --git a/include/linux/bitops.h b/include/linux/bitops.h
index 48bde600a2db..024f2b027244 100644
--- a/include/linux/bitops.h
+++ b/include/linux/bitops.h
@@ -6,8 +6,8 @@
6#define BIT(nr) (1UL << (nr)) 6#define BIT(nr) (1UL << (nr))
7#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG)) 7#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG))
8#define BIT_WORD(nr) ((nr) / BITS_PER_LONG) 8#define BIT_WORD(nr) ((nr) / BITS_PER_LONG)
9#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_LONG)
10#define BITS_PER_BYTE 8 9#define BITS_PER_BYTE 8
10#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long))
11#endif 11#endif
12 12
13/* 13/*
@@ -114,8 +114,6 @@ static inline unsigned fls_long(unsigned long l)
114 114
115#ifdef __KERNEL__ 115#ifdef __KERNEL__
116#ifdef CONFIG_GENERIC_FIND_FIRST_BIT 116#ifdef CONFIG_GENERIC_FIND_FIRST_BIT
117extern unsigned long __find_first_bit(const unsigned long *addr,
118 unsigned long size);
119 117
120/** 118/**
121 * find_first_bit - find the first set bit in a memory region 119 * find_first_bit - find the first set bit in a memory region
@@ -124,28 +122,8 @@ extern unsigned long __find_first_bit(const unsigned long *addr,
124 * 122 *
125 * Returns the bit number of the first set bit. 123 * Returns the bit number of the first set bit.
126 */ 124 */
127static __always_inline unsigned long 125extern unsigned long find_first_bit(const unsigned long *addr,
128find_first_bit(const unsigned long *addr, unsigned long size) 126 unsigned long size);
129{
130 /* Avoid a function call if the bitmap size is a constant */
131 /* and not bigger than BITS_PER_LONG. */
132
133 /* insert a sentinel so that __ffs returns size if there */
134 /* are no set bits in the bitmap */
135 if (__builtin_constant_p(size) && (size < BITS_PER_LONG))
136 return __ffs((*addr) | (1ul << size));
137
138 /* the result of __ffs(0) is undefined, so it needs to be */
139 /* handled separately */
140 if (__builtin_constant_p(size) && (size == BITS_PER_LONG))
141 return ((*addr) == 0) ? BITS_PER_LONG : __ffs(*addr);
142
143 /* size is not constant or too big */
144 return __find_first_bit(addr, size);
145}
146
147extern unsigned long __find_first_zero_bit(const unsigned long *addr,
148 unsigned long size);
149 127
150/** 128/**
151 * find_first_zero_bit - find the first cleared bit in a memory region 129 * find_first_zero_bit - find the first cleared bit in a memory region
@@ -154,31 +132,12 @@ extern unsigned long __find_first_zero_bit(const unsigned long *addr,
154 * 132 *
155 * Returns the bit number of the first cleared bit. 133 * Returns the bit number of the first cleared bit.
156 */ 134 */
157static __always_inline unsigned long 135extern unsigned long find_first_zero_bit(const unsigned long *addr,
158find_first_zero_bit(const unsigned long *addr, unsigned long size) 136 unsigned long size);
159{ 137
160 /* Avoid a function call if the bitmap size is a constant */
161 /* and not bigger than BITS_PER_LONG. */
162
163 /* insert a sentinel so that __ffs returns size if there */
164 /* are no set bits in the bitmap */
165 if (__builtin_constant_p(size) && (size < BITS_PER_LONG)) {
166 return __ffs(~(*addr) | (1ul << size));
167 }
168
169 /* the result of __ffs(0) is undefined, so it needs to be */
170 /* handled separately */
171 if (__builtin_constant_p(size) && (size == BITS_PER_LONG))
172 return (~(*addr) == 0) ? BITS_PER_LONG : __ffs(~(*addr));
173
174 /* size is not constant or too big */
175 return __find_first_zero_bit(addr, size);
176}
177#endif /* CONFIG_GENERIC_FIND_FIRST_BIT */ 138#endif /* CONFIG_GENERIC_FIND_FIRST_BIT */
178 139
179#ifdef CONFIG_GENERIC_FIND_NEXT_BIT 140#ifdef CONFIG_GENERIC_FIND_NEXT_BIT
180extern unsigned long __find_next_bit(const unsigned long *addr,
181 unsigned long size, unsigned long offset);
182 141
183/** 142/**
184 * find_next_bit - find the next set bit in a memory region 143 * find_next_bit - find the next set bit in a memory region
@@ -186,36 +145,8 @@ extern unsigned long __find_next_bit(const unsigned long *addr,
186 * @offset: The bitnumber to start searching at 145 * @offset: The bitnumber to start searching at
187 * @size: The bitmap size in bits 146 * @size: The bitmap size in bits
188 */ 147 */
189static __always_inline unsigned long 148extern unsigned long find_next_bit(const unsigned long *addr,
190find_next_bit(const unsigned long *addr, unsigned long size, 149 unsigned long size, unsigned long offset);
191 unsigned long offset)
192{
193 unsigned long value;
194
195 /* Avoid a function call if the bitmap size is a constant */
196 /* and not bigger than BITS_PER_LONG. */
197
198 /* insert a sentinel so that __ffs returns size if there */
199 /* are no set bits in the bitmap */
200 if (__builtin_constant_p(size) && (size < BITS_PER_LONG)) {
201 value = (*addr) & ((~0ul) << offset);
202 value |= (1ul << size);
203 return __ffs(value);
204 }
205
206 /* the result of __ffs(0) is undefined, so it needs to be */
207 /* handled separately */
208 if (__builtin_constant_p(size) && (size == BITS_PER_LONG)) {
209 value = (*addr) & ((~0ul) << offset);
210 return (value == 0) ? BITS_PER_LONG : __ffs(value);
211 }
212
213 /* size is not constant or too big */
214 return __find_next_bit(addr, size, offset);
215}
216
217extern unsigned long __find_next_zero_bit(const unsigned long *addr,
218 unsigned long size, unsigned long offset);
219 150
220/** 151/**
221 * find_next_zero_bit - find the next cleared bit in a memory region 152 * find_next_zero_bit - find the next cleared bit in a memory region
@@ -223,33 +154,11 @@ extern unsigned long __find_next_zero_bit(const unsigned long *addr,
223 * @offset: The bitnumber to start searching at 154 * @offset: The bitnumber to start searching at
224 * @size: The bitmap size in bits 155 * @size: The bitmap size in bits
225 */ 156 */
226static __always_inline unsigned long 157
227find_next_zero_bit(const unsigned long *addr, unsigned long size, 158extern unsigned long find_next_zero_bit(const unsigned long *addr,
228 unsigned long offset) 159 unsigned long size,
229{ 160 unsigned long offset);
230 unsigned long value; 161
231
232 /* Avoid a function call if the bitmap size is a constant */
233 /* and not bigger than BITS_PER_LONG. */
234
235 /* insert a sentinel so that __ffs returns size if there */
236 /* are no set bits in the bitmap */
237 if (__builtin_constant_p(size) && (size < BITS_PER_LONG)) {
238 value = (~(*addr)) & ((~0ul) << offset);
239 value |= (1ul << size);
240 return __ffs(value);
241 }
242
243 /* the result of __ffs(0) is undefined, so it needs to be */
244 /* handled separately */
245 if (__builtin_constant_p(size) && (size == BITS_PER_LONG)) {
246 value = (~(*addr)) & ((~0ul) << offset);
247 return (value == 0) ? BITS_PER_LONG : __ffs(value);
248 }
249
250 /* size is not constant or too big */
251 return __find_next_zero_bit(addr, size, offset);
252}
253#endif /* CONFIG_GENERIC_FIND_NEXT_BIT */ 162#endif /* CONFIG_GENERIC_FIND_NEXT_BIT */
254#endif /* __KERNEL__ */ 163#endif /* __KERNEL__ */
255#endif 164#endif