at v2.6.16-rc2 387 lines 10 kB view raw
1/* asm/bitops.h for Linux/CRIS 2 * 3 * TODO: asm versions if speed is needed 4 * 5 * All bit operations return 0 if the bit was cleared before the 6 * operation and != 0 if it was not. 7 * 8 * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1). 9 */ 10 11#ifndef _CRIS_BITOPS_H 12#define _CRIS_BITOPS_H 13 14/* Currently this is unsuitable for consumption outside the kernel. */ 15#ifdef __KERNEL__ 16 17#include <asm/arch/bitops.h> 18#include <asm/system.h> 19#include <asm/atomic.h> 20#include <linux/compiler.h> 21 22/* 23 * Some hacks to defeat gcc over-optimizations.. 24 */ 25struct __dummy { unsigned long a[100]; }; 26#define ADDR (*(struct __dummy *) addr) 27#define CONST_ADDR (*(const struct __dummy *) addr) 28 29/* 30 * set_bit - Atomically set a bit in memory 31 * @nr: the bit to set 32 * @addr: the address to start counting from 33 * 34 * This function is atomic and may not be reordered. See __set_bit() 35 * if you do not require the atomic guarantees. 36 * Note that @nr may be almost arbitrarily large; this function is not 37 * restricted to acting on a single-word quantity. 38 */ 39 40#define set_bit(nr, addr) (void)test_and_set_bit(nr, addr) 41 42#define __set_bit(nr, addr) (void)__test_and_set_bit(nr, addr) 43 44/* 45 * clear_bit - Clears a bit in memory 46 * @nr: Bit to clear 47 * @addr: Address to start counting from 48 * 49 * clear_bit() is atomic and may not be reordered. However, it does 50 * not contain a memory barrier, so if it is used for locking purposes, 51 * you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit() 52 * in order to ensure changes are visible on other processors. 53 */ 54 55#define clear_bit(nr, addr) (void)test_and_clear_bit(nr, addr) 56 57#define __clear_bit(nr, addr) (void)__test_and_clear_bit(nr, addr) 58 59/* 60 * change_bit - Toggle a bit in memory 61 * @nr: Bit to change 62 * @addr: Address to start counting from 63 * 64 * change_bit() is atomic and may not be reordered. 65 * Note that @nr may be almost arbitrarily large; this function is not 66 * restricted to acting on a single-word quantity. 67 */ 68 69#define change_bit(nr, addr) (void)test_and_change_bit(nr, addr) 70 71/* 72 * __change_bit - Toggle a bit in memory 73 * @nr: the bit to change 74 * @addr: the address to start counting from 75 * 76 * Unlike change_bit(), this function is non-atomic and may be reordered. 77 * If it's called on the same region of memory simultaneously, the effect 78 * may be that only one operation succeeds. 79 */ 80 81#define __change_bit(nr, addr) (void)__test_and_change_bit(nr, addr) 82 83/** 84 * test_and_set_bit - Set a bit and return its old value 85 * @nr: Bit to set 86 * @addr: Address to count from 87 * 88 * This operation is atomic and cannot be reordered. 89 * It also implies a memory barrier. 90 */ 91 92static inline int test_and_set_bit(int nr, volatile unsigned long *addr) 93{ 94 unsigned int mask, retval; 95 unsigned long flags; 96 unsigned int *adr = (unsigned int *)addr; 97 98 adr += nr >> 5; 99 mask = 1 << (nr & 0x1f); 100 cris_atomic_save(addr, flags); 101 retval = (mask & *adr) != 0; 102 *adr |= mask; 103 cris_atomic_restore(addr, flags); 104 local_irq_restore(flags); 105 return retval; 106} 107 108static inline int __test_and_set_bit(int nr, volatile unsigned long *addr) 109{ 110 unsigned int mask, retval; 111 unsigned int *adr = (unsigned int *)addr; 112 113 adr += nr >> 5; 114 mask = 1 << (nr & 0x1f); 115 retval = (mask & *adr) != 0; 116 *adr |= mask; 117 return retval; 118} 119 120/* 121 * clear_bit() doesn't provide any barrier for the compiler. 122 */ 123#define smp_mb__before_clear_bit() barrier() 124#define smp_mb__after_clear_bit() barrier() 125 126/** 127 * test_and_clear_bit - Clear a bit and return its old value 128 * @nr: Bit to clear 129 * @addr: Address to count from 130 * 131 * This operation is atomic and cannot be reordered. 132 * It also implies a memory barrier. 133 */ 134 135static inline int test_and_clear_bit(int nr, volatile unsigned long *addr) 136{ 137 unsigned int mask, retval; 138 unsigned long flags; 139 unsigned int *adr = (unsigned int *)addr; 140 141 adr += nr >> 5; 142 mask = 1 << (nr & 0x1f); 143 cris_atomic_save(addr, flags); 144 retval = (mask & *adr) != 0; 145 *adr &= ~mask; 146 cris_atomic_restore(addr, flags); 147 return retval; 148} 149 150/** 151 * __test_and_clear_bit - Clear a bit and return its old value 152 * @nr: Bit to clear 153 * @addr: Address to count from 154 * 155 * This operation is non-atomic and can be reordered. 156 * If two examples of this operation race, one can appear to succeed 157 * but actually fail. You must protect multiple accesses with a lock. 158 */ 159 160static inline int __test_and_clear_bit(int nr, volatile unsigned long *addr) 161{ 162 unsigned int mask, retval; 163 unsigned int *adr = (unsigned int *)addr; 164 165 adr += nr >> 5; 166 mask = 1 << (nr & 0x1f); 167 retval = (mask & *adr) != 0; 168 *adr &= ~mask; 169 return retval; 170} 171/** 172 * test_and_change_bit - Change a bit and return its old value 173 * @nr: Bit to change 174 * @addr: Address to count from 175 * 176 * This operation is atomic and cannot be reordered. 177 * It also implies a memory barrier. 178 */ 179 180static inline int test_and_change_bit(int nr, volatile unsigned long *addr) 181{ 182 unsigned int mask, retval; 183 unsigned long flags; 184 unsigned int *adr = (unsigned int *)addr; 185 adr += nr >> 5; 186 mask = 1 << (nr & 0x1f); 187 cris_atomic_save(addr, flags); 188 retval = (mask & *adr) != 0; 189 *adr ^= mask; 190 cris_atomic_restore(addr, flags); 191 return retval; 192} 193 194/* WARNING: non atomic and it can be reordered! */ 195 196static inline int __test_and_change_bit(int nr, volatile unsigned long *addr) 197{ 198 unsigned int mask, retval; 199 unsigned int *adr = (unsigned int *)addr; 200 201 adr += nr >> 5; 202 mask = 1 << (nr & 0x1f); 203 retval = (mask & *adr) != 0; 204 *adr ^= mask; 205 206 return retval; 207} 208 209/** 210 * test_bit - Determine whether a bit is set 211 * @nr: bit number to test 212 * @addr: Address to start counting from 213 * 214 * This routine doesn't need to be atomic. 215 */ 216 217static inline int test_bit(int nr, const volatile unsigned long *addr) 218{ 219 unsigned int mask; 220 unsigned int *adr = (unsigned int *)addr; 221 222 adr += nr >> 5; 223 mask = 1 << (nr & 0x1f); 224 return ((mask & *adr) != 0); 225} 226 227/* 228 * Find-bit routines.. 229 */ 230 231/* 232 * Since we define it "external", it collides with the built-in 233 * definition, which doesn't have the same semantics. We don't want to 234 * use -fno-builtin, so just hide the name ffs. 235 */ 236#define ffs kernel_ffs 237 238/* 239 * fls: find last bit set. 240 */ 241 242#define fls(x) generic_fls(x) 243#define fls64(x) generic_fls64(x) 244 245/* 246 * hweightN - returns the hamming weight of a N-bit word 247 * @x: the word to weigh 248 * 249 * The Hamming Weight of a number is the total number of bits set in it. 250 */ 251 252#define hweight32(x) generic_hweight32(x) 253#define hweight16(x) generic_hweight16(x) 254#define hweight8(x) generic_hweight8(x) 255 256/** 257 * find_next_zero_bit - find the first zero bit in a memory region 258 * @addr: The address to base the search on 259 * @offset: The bitnumber to start searching at 260 * @size: The maximum size to search 261 */ 262static inline int find_next_zero_bit (const unsigned long * addr, int size, int offset) 263{ 264 unsigned long *p = ((unsigned long *) addr) + (offset >> 5); 265 unsigned long result = offset & ~31UL; 266 unsigned long tmp; 267 268 if (offset >= size) 269 return size; 270 size -= result; 271 offset &= 31UL; 272 if (offset) { 273 tmp = *(p++); 274 tmp |= ~0UL >> (32-offset); 275 if (size < 32) 276 goto found_first; 277 if (~tmp) 278 goto found_middle; 279 size -= 32; 280 result += 32; 281 } 282 while (size & ~31UL) { 283 if (~(tmp = *(p++))) 284 goto found_middle; 285 result += 32; 286 size -= 32; 287 } 288 if (!size) 289 return result; 290 tmp = *p; 291 292 found_first: 293 tmp |= ~0UL >> size; 294 found_middle: 295 return result + ffz(tmp); 296} 297 298/** 299 * find_next_bit - find the first set bit in a memory region 300 * @addr: The address to base the search on 301 * @offset: The bitnumber to start searching at 302 * @size: The maximum size to search 303 */ 304static __inline__ int find_next_bit(const unsigned long *addr, int size, int offset) 305{ 306 unsigned long *p = ((unsigned long *) addr) + (offset >> 5); 307 unsigned long result = offset & ~31UL; 308 unsigned long tmp; 309 310 if (offset >= size) 311 return size; 312 size -= result; 313 offset &= 31UL; 314 if (offset) { 315 tmp = *(p++); 316 tmp &= (~0UL << offset); 317 if (size < 32) 318 goto found_first; 319 if (tmp) 320 goto found_middle; 321 size -= 32; 322 result += 32; 323 } 324 while (size & ~31UL) { 325 if ((tmp = *(p++))) 326 goto found_middle; 327 result += 32; 328 size -= 32; 329 } 330 if (!size) 331 return result; 332 tmp = *p; 333 334found_first: 335 tmp &= (~0UL >> (32 - size)); 336 if (tmp == 0UL) /* Are any bits set? */ 337 return result + size; /* Nope. */ 338found_middle: 339 return result + __ffs(tmp); 340} 341 342/** 343 * find_first_zero_bit - find the first zero bit in a memory region 344 * @addr: The address to start the search at 345 * @size: The maximum size to search 346 * 347 * Returns the bit-number of the first zero bit, not the number of the byte 348 * containing a bit. 349 */ 350 351#define find_first_zero_bit(addr, size) \ 352 find_next_zero_bit((addr), (size), 0) 353#define find_first_bit(addr, size) \ 354 find_next_bit((addr), (size), 0) 355 356#define ext2_set_bit test_and_set_bit 357#define ext2_set_bit_atomic(l,n,a) test_and_set_bit(n,a) 358#define ext2_clear_bit test_and_clear_bit 359#define ext2_clear_bit_atomic(l,n,a) test_and_clear_bit(n,a) 360#define ext2_test_bit test_bit 361#define ext2_find_first_zero_bit find_first_zero_bit 362#define ext2_find_next_zero_bit find_next_zero_bit 363 364/* Bitmap functions for the minix filesystem. */ 365#define minix_set_bit(nr,addr) test_and_set_bit(nr,addr) 366#define minix_clear_bit(nr,addr) test_and_clear_bit(nr,addr) 367#define minix_test_bit(nr,addr) test_bit(nr,addr) 368#define minix_find_first_zero_bit(addr,size) find_first_zero_bit(addr,size) 369 370static inline int sched_find_first_bit(const unsigned long *b) 371{ 372 if (unlikely(b[0])) 373 return __ffs(b[0]); 374 if (unlikely(b[1])) 375 return __ffs(b[1]) + 32; 376 if (unlikely(b[2])) 377 return __ffs(b[2]) + 64; 378 if (unlikely(b[3])) 379 return __ffs(b[3]) + 96; 380 if (b[4]) 381 return __ffs(b[4]) + 128; 382 return __ffs(b[5]) + 32 + 128; 383} 384 385#endif /* __KERNEL__ */ 386 387#endif /* _CRIS_BITOPS_H */