bitops.h 4.3 KB

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