atomic.h 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. /* $OpenBSD: atomic.h,v 1.3 2015/02/10 11:39:18 dlg Exp $ */
  2. /*
  3. * Copyright (c) 2014 David Gwynne <dlg@openbsd.org>
  4. *
  5. * Permission to use, copy, modify, and distribute this software for any
  6. * purpose with or without fee is hereby granted, provided that the above
  7. * copyright notice and this permission notice appear in all copies.
  8. *
  9. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  10. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  11. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  12. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  13. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  14. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  15. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  16. */
  17. #ifndef _SYS_ATOMIC_H_
  18. #define _SYS_ATOMIC_H_
  19. #include <machine/atomic.h>
  20. /*
  21. * an arch wanting to provide its own implementations does so by defining
  22. * macros.
  23. */
  24. /*
  25. * atomic_cas_*
  26. */
  27. #ifndef atomic_cas_uint
  28. static inline unsigned int
  29. atomic_cas_uint(volatile unsigned int *p, unsigned int o, unsigned int n)
  30. {
  31. return __sync_val_compare_and_swap(p, o, n);
  32. }
  33. #endif
  34. #ifndef atomic_cas_ulong
  35. static inline unsigned long
  36. atomic_cas_ulong(volatile unsigned long *p, unsigned long o, unsigned long n)
  37. {
  38. return __sync_val_compare_and_swap(p, o, n);
  39. }
  40. #endif
  41. #ifndef atomic_cas_ptr
  42. static inline void *
  43. atomic_cas_ptr(volatile void *pp, void *o, void *n)
  44. {
  45. void * volatile *p = pp;
  46. return __sync_val_compare_and_swap(p, o, n);
  47. }
  48. #endif
  49. /*
  50. * atomic_swap_*
  51. */
  52. #ifndef atomic_swap_uint
  53. static inline unsigned int
  54. atomic_swap_uint(volatile unsigned int *p, unsigned int v)
  55. {
  56. return __sync_lock_test_and_set(p, v);
  57. }
  58. #endif
  59. #ifndef atomic_swap_ulong
  60. static inline unsigned long
  61. atomic_swap_ulong(volatile unsigned long *p, unsigned long v)
  62. {
  63. return __sync_lock_test_and_set(p, v);
  64. }
  65. #endif
  66. #ifndef atomic_swap_ptr
  67. static inline void *
  68. atomic_swap_ptr(volatile void *pp, void *v)
  69. {
  70. void * volatile *p = pp;
  71. return __sync_lock_test_and_set(p, v);
  72. }
  73. #endif
  74. /*
  75. * atomic_add_*_nv - add and fetch
  76. */
  77. #ifndef atomic_add_int_nv
  78. static inline unsigned int
  79. atomic_add_int_nv(volatile unsigned int *p, unsigned int v)
  80. {
  81. return __sync_add_and_fetch(p, v);
  82. }
  83. #endif
  84. #ifndef atomic_add_long_nv
  85. static inline unsigned long
  86. atomic_add_long_nv(volatile unsigned long *p, unsigned long v)
  87. {
  88. return __sync_add_and_fetch(p, v);
  89. }
  90. #endif
  91. /*
  92. * atomic_add - add
  93. */
  94. #ifndef atomic_add_int
  95. #define atomic_add_int(_p, _v) ((void)atomic_add_int_nv((_p), (_v)))
  96. #endif
  97. #ifndef atomic_add_long
  98. #define atomic_add_long(_p, _v) ((void)atomic_add_long_nv((_p), (_v)))
  99. #endif
  100. /*
  101. * atomic_inc_*_nv - increment and fetch
  102. */
  103. #ifndef atomic_inc_int_nv
  104. #define atomic_inc_int_nv(_p) atomic_add_int_nv((_p), 1)
  105. #endif
  106. #ifndef atomic_inc_long_nv
  107. #define atomic_inc_long_nv(_p) atomic_add_long_nv((_p), 1)
  108. #endif
  109. /*
  110. * atomic_inc_* - increment
  111. */
  112. #ifndef atomic_inc_int
  113. #define atomic_inc_int(_p) ((void)atomic_inc_int_nv(_p))
  114. #endif
  115. #ifndef atomic_inc_long
  116. #define atomic_inc_long(_p) ((void)atomic_inc_long_nv(_p))
  117. #endif
  118. /*
  119. * atomic_sub_*_nv - sub and fetch
  120. */
  121. #ifndef atomic_sub_int_nv
  122. static inline unsigned int
  123. atomic_sub_int_nv(volatile unsigned int *p, unsigned int v)
  124. {
  125. return __sync_sub_and_fetch(p, v);
  126. }
  127. #endif
  128. #ifndef atomic_sub_long_nv
  129. static inline unsigned long
  130. atomic_sub_long_nv(volatile unsigned long *p, unsigned long v)
  131. {
  132. return __sync_sub_and_fetch(p, v);
  133. }
  134. #endif
  135. /*
  136. * atomic_sub_* - sub
  137. */
  138. #ifndef atomic_sub_int
  139. #define atomic_sub_int(_p, _v) ((void)atomic_sub_int_nv((_p), (_v)))
  140. #endif
  141. #ifndef atomic_sub_long
  142. #define atomic_sub_long(_p, _v) ((void)atomic_sub_long_nv((_p), (_v)))
  143. #endif
  144. /*
  145. * atomic_dec_*_nv - decrement and fetch
  146. */
  147. #ifndef atomic_dec_int_nv
  148. #define atomic_dec_int_nv(_p) atomic_sub_int_nv((_p), 1)
  149. #endif
  150. #ifndef atomic_dec_long_nv
  151. #define atomic_dec_long_nv(_p) atomic_sub_long_nv((_p), 1)
  152. #endif
  153. /*
  154. * atomic_dec_* - decrement
  155. */
  156. #ifndef atomic_dec_int
  157. #define atomic_dec_int(_p) ((void)atomic_dec_int_nv(_p))
  158. #endif
  159. #ifndef atomic_dec_long
  160. #define atomic_dec_long(_p) ((void)atomic_dec_long_nv(_p))
  161. #endif
  162. /*
  163. * memory barriers
  164. */
  165. #ifndef membar_enter
  166. #define membar_enter() __sync_synchronize()
  167. #endif
  168. #ifndef membar_exit
  169. #define membar_exit() __sync_synchronize()
  170. #endif
  171. #ifndef membar_producer
  172. #define membar_producer() __sync_synchronize()
  173. #endif
  174. #ifndef membar_consumer
  175. #define membar_consumer() __sync_synchronize()
  176. #endif
  177. #ifndef membar_sync
  178. #define membar_sync() __sync_synchronize()
  179. #endif
  180. #endif /* _SYS_ATOMIC_H_ */