atomic-long.h 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. #ifndef _ASM_GENERIC_ATOMIC_LONG_H
  2. #define _ASM_GENERIC_ATOMIC_LONG_H
  3. /*
  4. * Copyright (C) 2005 Silicon Graphics, Inc.
  5. * Christoph Lameter
  6. *
  7. * Allows to provide arch independent atomic definitions without the need to
  8. * edit all arch specific atomic.h files.
  9. */
  10. #include <asm/types.h>
  11. /*
  12. * Suppport for atomic_long_t
  13. *
  14. * Casts for parameters are avoided for existing atomic functions in order to
  15. * avoid issues with cast-as-lval under gcc 4.x and other limitations that the
  16. * macros of a platform may have.
  17. */
  18. #if BITS_PER_LONG == 64
  19. typedef atomic64_t atomic_long_t;
  20. #define ATOMIC_LONG_INIT(i) ATOMIC64_INIT(i)
  21. #define ATOMIC_LONG_PFX(x) atomic64 ## x
  22. #else
  23. typedef atomic_t atomic_long_t;
  24. #define ATOMIC_LONG_INIT(i) ATOMIC_INIT(i)
  25. #define ATOMIC_LONG_PFX(x) atomic ## x
  26. #endif
  27. #define ATOMIC_LONG_READ_OP(mo) \
  28. static inline long atomic_long_read##mo(const atomic_long_t *l) \
  29. { \
  30. ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l; \
  31. \
  32. return (long)ATOMIC_LONG_PFX(_read##mo)(v); \
  33. }
  34. ATOMIC_LONG_READ_OP()
  35. ATOMIC_LONG_READ_OP(_acquire)
  36. #undef ATOMIC_LONG_READ_OP
  37. #define ATOMIC_LONG_SET_OP(mo) \
  38. static inline void atomic_long_set##mo(atomic_long_t *l, long i) \
  39. { \
  40. ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l; \
  41. \
  42. ATOMIC_LONG_PFX(_set##mo)(v, i); \
  43. }
  44. ATOMIC_LONG_SET_OP()
  45. ATOMIC_LONG_SET_OP(_release)
  46. #undef ATOMIC_LONG_SET_OP
  47. #define ATOMIC_LONG_ADD_SUB_OP(op, mo) \
  48. static inline long \
  49. atomic_long_##op##_return##mo(long i, atomic_long_t *l) \
  50. { \
  51. ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l; \
  52. \
  53. return (long)ATOMIC_LONG_PFX(_##op##_return##mo)(i, v); \
  54. }
  55. ATOMIC_LONG_ADD_SUB_OP(add,)
  56. ATOMIC_LONG_ADD_SUB_OP(add, _relaxed)
  57. ATOMIC_LONG_ADD_SUB_OP(add, _acquire)
  58. ATOMIC_LONG_ADD_SUB_OP(add, _release)
  59. ATOMIC_LONG_ADD_SUB_OP(sub,)
  60. ATOMIC_LONG_ADD_SUB_OP(sub, _relaxed)
  61. ATOMIC_LONG_ADD_SUB_OP(sub, _acquire)
  62. ATOMIC_LONG_ADD_SUB_OP(sub, _release)
  63. #undef ATOMIC_LONG_ADD_SUB_OP
  64. #define atomic_long_cmpxchg_relaxed(l, old, new) \
  65. (ATOMIC_LONG_PFX(_cmpxchg_relaxed)((ATOMIC_LONG_PFX(_t) *)(l), \
  66. (old), (new)))
  67. #define atomic_long_cmpxchg_acquire(l, old, new) \
  68. (ATOMIC_LONG_PFX(_cmpxchg_acquire)((ATOMIC_LONG_PFX(_t) *)(l), \
  69. (old), (new)))
  70. #define atomic_long_cmpxchg_release(l, old, new) \
  71. (ATOMIC_LONG_PFX(_cmpxchg_release)((ATOMIC_LONG_PFX(_t) *)(l), \
  72. (old), (new)))
  73. #define atomic_long_cmpxchg(l, old, new) \
  74. (ATOMIC_LONG_PFX(_cmpxchg)((ATOMIC_LONG_PFX(_t) *)(l), (old), (new)))
  75. #define atomic_long_xchg_relaxed(v, new) \
  76. (ATOMIC_LONG_PFX(_xchg_relaxed)((ATOMIC_LONG_PFX(_t) *)(v), (new)))
  77. #define atomic_long_xchg_acquire(v, new) \
  78. (ATOMIC_LONG_PFX(_xchg_acquire)((ATOMIC_LONG_PFX(_t) *)(v), (new)))
  79. #define atomic_long_xchg_release(v, new) \
  80. (ATOMIC_LONG_PFX(_xchg_release)((ATOMIC_LONG_PFX(_t) *)(v), (new)))
  81. #define atomic_long_xchg(v, new) \
  82. (ATOMIC_LONG_PFX(_xchg)((ATOMIC_LONG_PFX(_t) *)(v), (new)))
  83. static __always_inline void atomic_long_inc(atomic_long_t *l)
  84. {
  85. ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l;
  86. ATOMIC_LONG_PFX(_inc)(v);
  87. }
  88. static __always_inline void atomic_long_dec(atomic_long_t *l)
  89. {
  90. ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l;
  91. ATOMIC_LONG_PFX(_dec)(v);
  92. }
  93. #define ATOMIC_LONG_FETCH_OP(op, mo) \
  94. static inline long \
  95. atomic_long_fetch_##op##mo(long i, atomic_long_t *l) \
  96. { \
  97. ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l; \
  98. \
  99. return (long)ATOMIC_LONG_PFX(_fetch_##op##mo)(i, v); \
  100. }
  101. ATOMIC_LONG_FETCH_OP(add, )
  102. ATOMIC_LONG_FETCH_OP(add, _relaxed)
  103. ATOMIC_LONG_FETCH_OP(add, _acquire)
  104. ATOMIC_LONG_FETCH_OP(add, _release)
  105. ATOMIC_LONG_FETCH_OP(sub, )
  106. ATOMIC_LONG_FETCH_OP(sub, _relaxed)
  107. ATOMIC_LONG_FETCH_OP(sub, _acquire)
  108. ATOMIC_LONG_FETCH_OP(sub, _release)
  109. ATOMIC_LONG_FETCH_OP(and, )
  110. ATOMIC_LONG_FETCH_OP(and, _relaxed)
  111. ATOMIC_LONG_FETCH_OP(and, _acquire)
  112. ATOMIC_LONG_FETCH_OP(and, _release)
  113. ATOMIC_LONG_FETCH_OP(andnot, )
  114. ATOMIC_LONG_FETCH_OP(andnot, _relaxed)
  115. ATOMIC_LONG_FETCH_OP(andnot, _acquire)
  116. ATOMIC_LONG_FETCH_OP(andnot, _release)
  117. ATOMIC_LONG_FETCH_OP(or, )
  118. ATOMIC_LONG_FETCH_OP(or, _relaxed)
  119. ATOMIC_LONG_FETCH_OP(or, _acquire)
  120. ATOMIC_LONG_FETCH_OP(or, _release)
  121. ATOMIC_LONG_FETCH_OP(xor, )
  122. ATOMIC_LONG_FETCH_OP(xor, _relaxed)
  123. ATOMIC_LONG_FETCH_OP(xor, _acquire)
  124. ATOMIC_LONG_FETCH_OP(xor, _release)
  125. #undef ATOMIC_LONG_FETCH_OP
  126. #define ATOMIC_LONG_FETCH_INC_DEC_OP(op, mo) \
  127. static inline long \
  128. atomic_long_fetch_##op##mo(atomic_long_t *l) \
  129. { \
  130. ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l; \
  131. \
  132. return (long)ATOMIC_LONG_PFX(_fetch_##op##mo)(v); \
  133. }
  134. ATOMIC_LONG_FETCH_INC_DEC_OP(inc,)
  135. ATOMIC_LONG_FETCH_INC_DEC_OP(inc, _relaxed)
  136. ATOMIC_LONG_FETCH_INC_DEC_OP(inc, _acquire)
  137. ATOMIC_LONG_FETCH_INC_DEC_OP(inc, _release)
  138. ATOMIC_LONG_FETCH_INC_DEC_OP(dec,)
  139. ATOMIC_LONG_FETCH_INC_DEC_OP(dec, _relaxed)
  140. ATOMIC_LONG_FETCH_INC_DEC_OP(dec, _acquire)
  141. ATOMIC_LONG_FETCH_INC_DEC_OP(dec, _release)
  142. #undef ATOMIC_LONG_FETCH_INC_DEC_OP
  143. #define ATOMIC_LONG_OP(op) \
  144. static __always_inline void \
  145. atomic_long_##op(long i, atomic_long_t *l) \
  146. { \
  147. ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l; \
  148. \
  149. ATOMIC_LONG_PFX(_##op)(i, v); \
  150. }
  151. ATOMIC_LONG_OP(add)
  152. ATOMIC_LONG_OP(sub)
  153. ATOMIC_LONG_OP(and)
  154. ATOMIC_LONG_OP(andnot)
  155. ATOMIC_LONG_OP(or)
  156. ATOMIC_LONG_OP(xor)
  157. #undef ATOMIC_LONG_OP
  158. static inline int atomic_long_sub_and_test(long i, atomic_long_t *l)
  159. {
  160. ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l;
  161. return ATOMIC_LONG_PFX(_sub_and_test)(i, v);
  162. }
  163. static inline int atomic_long_dec_and_test(atomic_long_t *l)
  164. {
  165. ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l;
  166. return ATOMIC_LONG_PFX(_dec_and_test)(v);
  167. }
  168. static inline int atomic_long_inc_and_test(atomic_long_t *l)
  169. {
  170. ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l;
  171. return ATOMIC_LONG_PFX(_inc_and_test)(v);
  172. }
  173. static inline int atomic_long_add_negative(long i, atomic_long_t *l)
  174. {
  175. ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l;
  176. return ATOMIC_LONG_PFX(_add_negative)(i, v);
  177. }
  178. #define ATOMIC_LONG_INC_DEC_OP(op, mo) \
  179. static inline long \
  180. atomic_long_##op##_return##mo(atomic_long_t *l) \
  181. { \
  182. ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l; \
  183. \
  184. return (long)ATOMIC_LONG_PFX(_##op##_return##mo)(v); \
  185. }
  186. ATOMIC_LONG_INC_DEC_OP(inc,)
  187. ATOMIC_LONG_INC_DEC_OP(inc, _relaxed)
  188. ATOMIC_LONG_INC_DEC_OP(inc, _acquire)
  189. ATOMIC_LONG_INC_DEC_OP(inc, _release)
  190. ATOMIC_LONG_INC_DEC_OP(dec,)
  191. ATOMIC_LONG_INC_DEC_OP(dec, _relaxed)
  192. ATOMIC_LONG_INC_DEC_OP(dec, _acquire)
  193. ATOMIC_LONG_INC_DEC_OP(dec, _release)
  194. #undef ATOMIC_LONG_INC_DEC_OP
  195. static inline long atomic_long_add_unless(atomic_long_t *l, long a, long u)
  196. {
  197. ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l;
  198. return (long)ATOMIC_LONG_PFX(_add_unless)(v, a, u);
  199. }
  200. #define atomic_long_inc_not_zero(l) \
  201. ATOMIC_LONG_PFX(_inc_not_zero)((ATOMIC_LONG_PFX(_t) *)(l))
  202. #endif /* _ASM_GENERIC_ATOMIC_LONG_H */