stdatomic.h 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. // -*- C++ -*- compatibility header.
  2. // Copyright (C) 2008, 2009 Free Software Foundation, Inc.
  3. //
  4. // This file is part of the GNU ISO C++ Library. This library is free
  5. // software; you can redistribute it and/or modify it under the
  6. // terms of the GNU General Public License as published by the
  7. // Free Software Foundation; either version 3, or (at your option)
  8. // any later version.
  9. // This library is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. // Under Section 7 of GPL version 3, you are granted additional
  14. // permissions described in the GCC Runtime Library Exception, version
  15. // 3.1, as published by the Free Software Foundation.
  16. // You should have received a copy of the GNU General Public License and
  17. // a copy of the GCC Runtime Library Exception along with this program;
  18. // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
  19. // <http://www.gnu.org/licenses/>.
  20. /** @file stdatomic.h
  21. * This is a Standard C++ Library header.
  22. */
  23. #include <bits/c++config.h>
  24. #include <stddef.h>
  25. #include <stdbool.h> // XXX need to define bool w/o stdbool.h in tr1/cstdbool
  26. #ifndef _GLIBCXX_STDATOMIC_H
  27. #define _GLIBCXX_STDATOMIC_H 1
  28. _GLIBCXX_BEGIN_NAMESPACE(std)
  29. _GLIBCXX_BEGIN_EXTERN_C
  30. /**
  31. * @defgroup atomics Atomics
  32. *
  33. * Components for performing atomic operations.
  34. * @{
  35. */
  36. /// Enumeration for memory_order
  37. typedef enum memory_order
  38. {
  39. memory_order_relaxed,
  40. memory_order_consume,
  41. memory_order_acquire,
  42. memory_order_release,
  43. memory_order_acq_rel,
  44. memory_order_seq_cst
  45. } memory_order;
  46. // Base for atomic_flag.
  47. typedef struct __atomic_flag_base
  48. {
  49. bool _M_i;
  50. } __atomic_flag_base;
  51. #define ATOMIC_FLAG_INIT { false }
  52. /// 29.2 Lock-free Property
  53. #if defined(_GLIBCXX_ATOMIC_BUILTINS_1) && defined(_GLIBCXX_ATOMIC_BUILTINS_2) \
  54. && defined(_GLIBCXX_ATOMIC_BUILTINS_4) && defined(_GLIBCXX_ATOMIC_BUILTINS_8)
  55. # define _GLIBCXX_ATOMIC_PROPERTY 2
  56. # define _GLIBCXX_ATOMIC_NAMESPACE __atomic2
  57. #elif defined(_GLIBCXX_ATOMIC_BUILTINS_1)
  58. # define _GLIBCXX_ATOMIC_PROPERTY 1
  59. # define _GLIBCXX_ATOMIC_NAMESPACE __atomic1
  60. #else
  61. # define _GLIBCXX_ATOMIC_PROPERTY 0
  62. # define _GLIBCXX_ATOMIC_NAMESPACE __atomic0
  63. #endif
  64. #define ATOMIC_INTEGRAL_LOCK_FREE _GLIBCXX_ATOMIC_PROPERTY
  65. #define ATOMIC_ADDRESS_LOCK_FREE _GLIBCXX_ATOMIC_PROPERTY
  66. // Switch atomic integral base types based on C or C++. In
  67. // addition, for "C" only provide type-generic macros for atomic
  68. // operations. (As C++ accomplishes the same thing with sets of
  69. // overloaded functions.
  70. #ifdef __cplusplus
  71. inline namespace _GLIBCXX_ATOMIC_NAMESPACE { }
  72. # include <bits/atomicfwd_cxx.h>
  73. #else
  74. # include <bits/atomicfwd_c.h>
  75. #endif
  76. // Typedefs for other atomic integral types.
  77. typedef atomic_schar atomic_int_least8_t;
  78. typedef atomic_uchar atomic_uint_least8_t;
  79. typedef atomic_short atomic_int_least16_t;
  80. typedef atomic_ushort atomic_uint_least16_t;
  81. typedef atomic_int atomic_int_least32_t;
  82. typedef atomic_uint atomic_uint_least32_t;
  83. typedef atomic_llong atomic_int_least64_t;
  84. typedef atomic_ullong atomic_uint_least64_t;
  85. typedef atomic_schar atomic_int_fast8_t;
  86. typedef atomic_uchar atomic_uint_fast8_t;
  87. typedef atomic_short atomic_int_fast16_t;
  88. typedef atomic_ushort atomic_uint_fast16_t;
  89. typedef atomic_int atomic_int_fast32_t;
  90. typedef atomic_uint atomic_uint_fast32_t;
  91. typedef atomic_llong atomic_int_fast64_t;
  92. typedef atomic_ullong atomic_uint_fast64_t;
  93. typedef atomic_long atomic_intptr_t;
  94. typedef atomic_ulong atomic_uintptr_t;
  95. typedef atomic_long atomic_ssize_t;
  96. typedef atomic_ulong atomic_size_t;
  97. typedef atomic_llong atomic_intmax_t;
  98. typedef atomic_ullong atomic_uintmax_t;
  99. typedef atomic_long atomic_ptrdiff_t;
  100. // Accessor functions for base atomic_flag type.
  101. bool
  102. atomic_flag_test_and_set_explicit(volatile __atomic_flag_base*, memory_order);
  103. inline bool
  104. atomic_flag_test_and_set(volatile __atomic_flag_base* __a)
  105. { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); }
  106. void
  107. atomic_flag_clear_explicit(volatile __atomic_flag_base*, memory_order);
  108. inline void
  109. atomic_flag_clear(volatile __atomic_flag_base* __a)
  110. { atomic_flag_clear_explicit(__a, memory_order_seq_cst); }
  111. void
  112. __atomic_flag_wait_explicit(volatile __atomic_flag_base*, memory_order);
  113. volatile __atomic_flag_base*
  114. __atomic_flag_for_address(const volatile void* __z) __attribute__((const));
  115. // Implementation specific defines.
  116. #define _ATOMIC_LOAD_(__a, __x) \
  117. ({ volatile __typeof__ _ATOMIC_MEMBER_* __p = &_ATOMIC_MEMBER_; \
  118. volatile atomic_flag* __g = __atomic_flag_for_address(__p); \
  119. __atomic_flag_wait_explicit(__g, __x); \
  120. __typeof__ _ATOMIC_MEMBER_ __r = *__p; \
  121. atomic_flag_clear_explicit(__g, __x); \
  122. __r; })
  123. #define _ATOMIC_STORE_(__a, __m, __x) \
  124. ({ volatile __typeof__ _ATOMIC_MEMBER_* __p = &_ATOMIC_MEMBER_; \
  125. __typeof__(__m) __v = (__m); \
  126. volatile atomic_flag* __g = __atomic_flag_for_address(__p); \
  127. __atomic_flag_wait_explicit(__g, __x); \
  128. *__p = __v; \
  129. atomic_flag_clear_explicit(__g, __x); \
  130. __v; })
  131. #define _ATOMIC_MODIFY_(__a, __o, __m, __x) \
  132. ({ volatile __typeof__ _ATOMIC_MEMBER_* __p = &_ATOMIC_MEMBER_; \
  133. __typeof__(__m) __v = (__m); \
  134. volatile atomic_flag* __g = __atomic_flag_for_address(__p); \
  135. __atomic_flag_wait_explicit(__g, __x); \
  136. __typeof__ _ATOMIC_MEMBER_ __r = *__p; \
  137. *__p __o __v; \
  138. atomic_flag_clear_explicit(__g, __x); \
  139. __r; })
  140. #define _ATOMIC_CMPEXCHNG_(__a, __e, __m, __x) \
  141. ({ volatile __typeof__ _ATOMIC_MEMBER_* __p = &_ATOMIC_MEMBER_; \
  142. __typeof__(__e) __q = (__e); \
  143. __typeof__(__m) __v = (__m); \
  144. bool __r; \
  145. volatile atomic_flag* __g = __atomic_flag_for_address(__p); \
  146. __atomic_flag_wait_explicit(__g, __x); \
  147. __typeof__ _ATOMIC_MEMBER_ __t__ = *__p; \
  148. if (__t__ == *__q) { *__p = __v; __r = true; } \
  149. else { *__q = __t__; __r = false; } \
  150. atomic_flag_clear_explicit(__g, __x); \
  151. __r; })
  152. // @} group atomics
  153. _GLIBCXX_END_EXTERN_C
  154. _GLIBCXX_END_NAMESPACE
  155. // Inject into global namespace.
  156. #ifdef __cplusplus
  157. #include <cstdatomic>
  158. using std::memory_order;
  159. using std::memory_order_relaxed;
  160. using std::memory_order_consume;
  161. using std::memory_order_acquire;
  162. using std::memory_order_release;
  163. using std::memory_order_acq_rel;
  164. using std::memory_order_seq_cst;
  165. using std::atomic_flag;
  166. using std::atomic_bool;
  167. using std::atomic_char;
  168. using std::atomic_schar;
  169. using std::atomic_uchar;
  170. using std::atomic_short;
  171. using std::atomic_ushort;
  172. using std::atomic_int;
  173. using std::atomic_uint;
  174. using std::atomic_long;
  175. using std::atomic_ulong;
  176. using std::atomic_llong;
  177. using std::atomic_ullong;
  178. using std::atomic_wchar_t;
  179. using std::atomic_char16_t;
  180. using std::atomic_char32_t;
  181. using std::atomic_address;
  182. using std::atomic;
  183. #endif
  184. #endif