bitops.h 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  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. #ifndef _CRIS_BITOPS_H
  11. #define _CRIS_BITOPS_H
  12. /* Currently this is unsuitable for consumption outside the kernel. */
  13. #ifdef __KERNEL__
  14. #ifndef _LINUX_BITOPS_H
  15. #error only <linux/bitops.h> can be included directly
  16. #endif
  17. #include <asm/arch/bitops.h>
  18. #include <asm/system.h>
  19. #include <asm/atomic.h>
  20. #include <linux/compiler.h>
  21. /*
  22. * Some hacks to defeat gcc over-optimizations..
  23. */
  24. struct __dummy { unsigned long a[100]; };
  25. #define ADDR (*(struct __dummy *) addr)
  26. #define CONST_ADDR (*(const struct __dummy *) addr)
  27. /*
  28. * set_bit - Atomically set a bit in memory
  29. * @nr: the bit to set
  30. * @addr: the address to start counting from
  31. *
  32. * This function is atomic and may not be reordered. See __set_bit()
  33. * if you do not require the atomic guarantees.
  34. * Note that @nr may be almost arbitrarily large; this function is not
  35. * restricted to acting on a single-word quantity.
  36. */
  37. #define set_bit(nr, addr) (void)test_and_set_bit(nr, addr)
  38. /*
  39. * clear_bit - Clears a bit in memory
  40. * @nr: Bit to clear
  41. * @addr: Address to start counting from
  42. *
  43. * clear_bit() is atomic and may not be reordered. However, it does
  44. * not contain a memory barrier, so if it is used for locking purposes,
  45. * you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit()
  46. * in order to ensure changes are visible on other processors.
  47. */
  48. #define clear_bit(nr, addr) (void)test_and_clear_bit(nr, addr)
  49. /*
  50. * change_bit - Toggle a bit in memory
  51. * @nr: Bit to change
  52. * @addr: Address to start counting from
  53. *
  54. * change_bit() is atomic and may not be reordered.
  55. * Note that @nr may be almost arbitrarily large; this function is not
  56. * restricted to acting on a single-word quantity.
  57. */
  58. #define change_bit(nr, addr) (void)test_and_change_bit(nr, addr)
  59. /**
  60. * test_and_set_bit - Set a bit and return its old value
  61. * @nr: Bit to set
  62. * @addr: Address to count from
  63. *
  64. * This operation is atomic and cannot be reordered.
  65. * It also implies a memory barrier.
  66. */
  67. static inline int test_and_set_bit(int nr, volatile unsigned long *addr)
  68. {
  69. unsigned int mask, retval;
  70. unsigned long flags;
  71. unsigned int *adr = (unsigned int *)addr;
  72. adr += nr >> 5;
  73. mask = 1 << (nr & 0x1f);
  74. cris_atomic_save(addr, flags);
  75. retval = (mask & *adr) != 0;
  76. *adr |= mask;
  77. cris_atomic_restore(addr, flags);
  78. return retval;
  79. }
  80. /*
  81. * clear_bit() doesn't provide any barrier for the compiler.
  82. */
  83. #define smp_mb__before_clear_bit() barrier()
  84. #define smp_mb__after_clear_bit() barrier()
  85. /**
  86. * test_and_clear_bit - Clear a bit and return its old value
  87. * @nr: Bit to clear
  88. * @addr: Address to count from
  89. *
  90. * This operation is atomic and cannot be reordered.
  91. * It also implies a memory barrier.
  92. */
  93. static inline int test_and_clear_bit(int nr, volatile unsigned long *addr)
  94. {
  95. unsigned int mask, retval;
  96. unsigned long flags;
  97. unsigned int *adr = (unsigned int *)addr;
  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. return retval;
  105. }
  106. /**
  107. * test_and_change_bit - Change a bit and return its old value
  108. * @nr: Bit to change
  109. * @addr: Address to count from
  110. *
  111. * This operation is atomic and cannot be reordered.
  112. * It also implies a memory barrier.
  113. */
  114. static inline int test_and_change_bit(int nr, volatile unsigned long *addr)
  115. {
  116. unsigned int mask, retval;
  117. unsigned long flags;
  118. unsigned int *adr = (unsigned int *)addr;
  119. adr += nr >> 5;
  120. mask = 1 << (nr & 0x1f);
  121. cris_atomic_save(addr, flags);
  122. retval = (mask & *adr) != 0;
  123. *adr ^= mask;
  124. cris_atomic_restore(addr, flags);
  125. return retval;
  126. }
  127. #include <asm-generic/bitops/non-atomic.h>
  128. /*
  129. * Since we define it "external", it collides with the built-in
  130. * definition, which doesn't have the same semantics. We don't want to
  131. * use -fno-builtin, so just hide the name ffs.
  132. */
  133. #define ffs kernel_ffs
  134. #include <asm-generic/bitops/fls.h>
  135. #include <asm-generic/bitops/fls64.h>
  136. #include <asm-generic/bitops/hweight.h>
  137. #include <asm-generic/bitops/find.h>
  138. #include <asm-generic/bitops/lock.h>
  139. #include <asm-generic/bitops/ext2-non-atomic.h>
  140. #define ext2_set_bit_atomic(l,n,a) test_and_set_bit(n,a)
  141. #define ext2_clear_bit_atomic(l,n,a) test_and_clear_bit(n,a)
  142. #include <asm-generic/bitops/minix.h>
  143. #include <asm-generic/bitops/sched.h>
  144. #endif /* __KERNEL__ */
  145. #endif /* _CRIS_BITOPS_H */