Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
at v2.6.12-rc2 387 lines 9.9 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 <linux/compiler.h> 20 21/* 22 * Some hacks to defeat gcc over-optimizations.. 23 */ 24struct __dummy { unsigned long a[100]; }; 25#define ADDR (*(struct __dummy *) addr) 26#define CONST_ADDR (*(const struct __dummy *) addr) 27 28/* 29 * set_bit - Atomically set a bit in memory 30 * @nr: the bit to set 31 * @addr: the address to start counting from 32 * 33 * This function is atomic and may not be reordered. See __set_bit() 34 * if you do not require the atomic guarantees. 35 * Note that @nr may be almost arbitrarily large; this function is not 36 * restricted to acting on a single-word quantity. 37 */ 38 39#define set_bit(nr, addr) (void)test_and_set_bit(nr, addr) 40 41#define __set_bit(nr, addr) (void)__test_and_set_bit(nr, addr) 42 43/* 44 * clear_bit - Clears a bit in memory 45 * @nr: Bit to clear 46 * @addr: Address to start counting from 47 * 48 * clear_bit() is atomic and may not be reordered. However, it does 49 * not contain a memory barrier, so if it is used for locking purposes, 50 * you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit() 51 * in order to ensure changes are visible on other processors. 52 */ 53 54#define clear_bit(nr, addr) (void)test_and_clear_bit(nr, addr) 55 56#define __clear_bit(nr, addr) (void)__test_and_clear_bit(nr, addr) 57 58/* 59 * change_bit - Toggle a bit in memory 60 * @nr: Bit to change 61 * @addr: Address to start counting from 62 * 63 * change_bit() is atomic and may not be reordered. 64 * Note that @nr may be almost arbitrarily large; this function is not 65 * restricted to acting on a single-word quantity. 66 */ 67 68#define change_bit(nr, addr) (void)test_and_change_bit(nr, addr) 69 70/* 71 * __change_bit - Toggle a bit in memory 72 * @nr: the bit to change 73 * @addr: the address to start counting from 74 * 75 * Unlike change_bit(), this function is non-atomic and may be reordered. 76 * If it's called on the same region of memory simultaneously, the effect 77 * may be that only one operation succeeds. 78 */ 79 80#define __change_bit(nr, addr) (void)__test_and_change_bit(nr, addr) 81 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 * This operation is atomic and cannot be reordered. 88 * It also implies a memory barrier. 89 */ 90 91extern inline int test_and_set_bit(int nr, void *addr) 92{ 93 unsigned int mask, retval; 94 unsigned long flags; 95 unsigned int *adr = (unsigned int *)addr; 96 97 adr += nr >> 5; 98 mask = 1 << (nr & 0x1f); 99 local_save_flags(flags); 100 local_irq_disable(); 101 retval = (mask & *adr) != 0; 102 *adr |= mask; 103 local_irq_restore(flags); 104 return retval; 105} 106 107extern inline int __test_and_set_bit(int nr, void *addr) 108{ 109 unsigned int mask, retval; 110 unsigned int *adr = (unsigned int *)addr; 111 112 adr += nr >> 5; 113 mask = 1 << (nr & 0x1f); 114 retval = (mask & *adr) != 0; 115 *adr |= mask; 116 return retval; 117} 118 119/* 120 * clear_bit() doesn't provide any barrier for the compiler. 121 */ 122#define smp_mb__before_clear_bit() barrier() 123#define smp_mb__after_clear_bit() barrier() 124 125/** 126 * test_and_clear_bit - Clear a bit and return its old value 127 * @nr: Bit to clear 128 * @addr: Address to count from 129 * 130 * This operation is atomic and cannot be reordered. 131 * It also implies a memory barrier. 132 */ 133 134extern inline int test_and_clear_bit(int nr, void *addr) 135{ 136 unsigned int mask, retval; 137 unsigned long flags; 138 unsigned int *adr = (unsigned int *)addr; 139 140 adr += nr >> 5; 141 mask = 1 << (nr & 0x1f); 142 local_save_flags(flags); 143 local_irq_disable(); 144 retval = (mask & *adr) != 0; 145 *adr &= ~mask; 146 local_irq_restore(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 160extern inline int __test_and_clear_bit(int nr, void *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 180extern inline int test_and_change_bit(int nr, void *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 local_save_flags(flags); 188 local_irq_disable(); 189 retval = (mask & *adr) != 0; 190 *adr ^= mask; 191 local_irq_restore(flags); 192 return retval; 193} 194 195/* WARNING: non atomic and it can be reordered! */ 196 197extern inline int __test_and_change_bit(int nr, void *addr) 198{ 199 unsigned int mask, retval; 200 unsigned int *adr = (unsigned int *)addr; 201 202 adr += nr >> 5; 203 mask = 1 << (nr & 0x1f); 204 retval = (mask & *adr) != 0; 205 *adr ^= mask; 206 207 return retval; 208} 209 210/** 211 * test_bit - Determine whether a bit is set 212 * @nr: bit number to test 213 * @addr: Address to start counting from 214 * 215 * This routine doesn't need to be atomic. 216 */ 217 218extern inline int test_bit(int nr, const void *addr) 219{ 220 unsigned int mask; 221 unsigned int *adr = (unsigned int *)addr; 222 223 adr += nr >> 5; 224 mask = 1 << (nr & 0x1f); 225 return ((mask & *adr) != 0); 226} 227 228/* 229 * Find-bit routines.. 230 */ 231 232/* 233 * Since we define it "external", it collides with the built-in 234 * definition, which doesn't have the same semantics. We don't want to 235 * use -fno-builtin, so just hide the name ffs. 236 */ 237#define ffs kernel_ffs 238 239/* 240 * fls: find last bit set. 241 */ 242 243#define fls(x) generic_fls(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 */ 262extern inline int find_next_zero_bit (void * 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(void *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 370extern inline int sched_find_first_bit(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 */