home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2006 November (DVD) / PCWELT_11_2006.ISO / casper / filesystem.squashfs / usr / src / linux-headers-2.6.17-6 / include / asm-cris / bitops.h < prev    next >
Encoding:
C/C++ Source or Header  |  2006-08-11  |  4.4 KB  |  169 lines

  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.  */
  25. struct __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. /*
  43.  * clear_bit - Clears a bit in memory
  44.  * @nr: Bit to clear
  45.  * @addr: Address to start counting from
  46.  *
  47.  * clear_bit() is atomic and may not be reordered.  However, it does
  48.  * not contain a memory barrier, so if it is used for locking purposes,
  49.  * you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit()
  50.  * in order to ensure changes are visible on other processors.
  51.  */
  52.  
  53. #define clear_bit(nr, addr)  (void)test_and_clear_bit(nr, addr)
  54.  
  55. /*
  56.  * change_bit - Toggle a bit in memory
  57.  * @nr: Bit to change
  58.  * @addr: Address to start counting from
  59.  *
  60.  * change_bit() is atomic and may not be reordered.
  61.  * Note that @nr may be almost arbitrarily large; this function is not
  62.  * restricted to acting on a single-word quantity.
  63.  */
  64.  
  65. #define change_bit(nr, addr) (void)test_and_change_bit(nr, addr)
  66.  
  67. /**
  68.  * test_and_set_bit - Set a bit and return its old value
  69.  * @nr: Bit to set
  70.  * @addr: Address to count from
  71.  *
  72.  * This operation is atomic and cannot be reordered.  
  73.  * It also implies a memory barrier.
  74.  */
  75.  
  76. static inline int test_and_set_bit(int nr, volatile unsigned long *addr)
  77. {
  78.     unsigned int mask, retval;
  79.     unsigned long flags;
  80.     unsigned int *adr = (unsigned int *)addr;
  81.     
  82.     adr += nr >> 5;
  83.     mask = 1 << (nr & 0x1f);
  84.     cris_atomic_save(addr, flags);
  85.     retval = (mask & *adr) != 0;
  86.     *adr |= mask;
  87.     cris_atomic_restore(addr, flags);
  88.     return retval;
  89. }
  90.  
  91. /*
  92.  * clear_bit() doesn't provide any barrier for the compiler.
  93.  */
  94. #define smp_mb__before_clear_bit()      barrier()
  95. #define smp_mb__after_clear_bit()       barrier()
  96.  
  97. /**
  98.  * test_and_clear_bit - Clear a bit and return its old value
  99.  * @nr: Bit to clear
  100.  * @addr: Address to count from
  101.  *
  102.  * This operation is atomic and cannot be reordered.  
  103.  * It also implies a memory barrier.
  104.  */
  105.  
  106. static inline int test_and_clear_bit(int nr, volatile unsigned long *addr)
  107. {
  108.     unsigned int mask, retval;
  109.     unsigned long flags;
  110.     unsigned int *adr = (unsigned int *)addr;
  111.     
  112.     adr += nr >> 5;
  113.     mask = 1 << (nr & 0x1f);
  114.     cris_atomic_save(addr, flags);
  115.     retval = (mask & *adr) != 0;
  116.     *adr &= ~mask;
  117.     cris_atomic_restore(addr, flags);
  118.     return retval;
  119. }
  120.  
  121. /**
  122.  * test_and_change_bit - Change a bit and return its old value
  123.  * @nr: Bit to change
  124.  * @addr: Address to count from
  125.  *
  126.  * This operation is atomic and cannot be reordered.  
  127.  * It also implies a memory barrier.
  128.  */
  129.  
  130. static inline int test_and_change_bit(int nr, volatile unsigned long *addr)
  131. {
  132.     unsigned int mask, retval;
  133.     unsigned long flags;
  134.     unsigned int *adr = (unsigned int *)addr;
  135.     adr += nr >> 5;
  136.     mask = 1 << (nr & 0x1f);
  137.     cris_atomic_save(addr, flags);
  138.     retval = (mask & *adr) != 0;
  139.     *adr ^= mask;
  140.     cris_atomic_restore(addr, flags);
  141.     return retval;
  142. }
  143.  
  144. #include <asm-generic/bitops/non-atomic.h>
  145.  
  146. /*
  147.  * Since we define it "external", it collides with the built-in
  148.  * definition, which doesn't have the same semantics.  We don't want to
  149.  * use -fno-builtin, so just hide the name ffs.
  150.  */
  151. #define ffs kernel_ffs
  152.  
  153. #include <asm-generic/bitops/fls.h>
  154. #include <asm-generic/bitops/fls64.h>
  155. #include <asm-generic/bitops/hweight.h>
  156. #include <asm-generic/bitops/find.h>
  157.  
  158. #include <asm-generic/bitops/ext2-non-atomic.h>
  159.  
  160. #define ext2_set_bit_atomic(l,n,a)   test_and_set_bit(n,a)
  161. #define ext2_clear_bit_atomic(l,n,a) test_and_clear_bit(n,a)
  162.  
  163. #include <asm-generic/bitops/minix.h>
  164. #include <asm-generic/bitops/sched.h>
  165.  
  166. #endif /* __KERNEL__ */
  167.  
  168. #endif /* _CRIS_BITOPS_H */
  169.