diff options
Diffstat (limited to 'include/linux/bitops.h')
-rw-r--r-- | include/linux/bitops.h | 115 |
1 files changed, 12 insertions, 103 deletions
diff --git a/include/linux/bitops.h b/include/linux/bitops.h index 8340a3aba49a..024f2b027244 100644 --- a/include/linux/bitops.h +++ b/include/linux/bitops.h | |||
@@ -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 |
117 | extern 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 | */ |
127 | static __always_inline unsigned long | 125 | extern unsigned long find_first_bit(const unsigned long *addr, |
128 | find_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 | |||
147 | extern 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 | */ |
157 | static __always_inline unsigned long | 135 | extern unsigned long find_first_zero_bit(const unsigned long *addr, |
158 | find_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 |
180 | extern 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 | */ |
189 | static __always_inline unsigned long | 148 | extern unsigned long find_next_bit(const unsigned long *addr, |
190 | find_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 | |||
217 | extern 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 | */ |
226 | static __always_inline unsigned long | 157 | |
227 | find_next_zero_bit(const unsigned long *addr, unsigned long size, | 158 | extern 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 |