master
  1// -*- C++ -*-
  2//===----------------------------------------------------------------------===//
  3//
  4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  5// See https://llvm.org/LICENSE.txt for license information.
  6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  7//
  8//===----------------------------------------------------------------------===//
  9
 10#ifndef _LIBCPP_STDATOMIC_H
 11#define _LIBCPP_STDATOMIC_H
 12
 13/*
 14    stdatomic.h synopsis
 15
 16template<class T>
 17  using std-atomic = std::atomic<T>;        // exposition only
 18
 19#define _Atomic(T) std-atomic<T>
 20
 21#define ATOMIC_BOOL_LOCK_FREE see below
 22#define ATOMIC_CHAR_LOCK_FREE see below
 23#define ATOMIC_CHAR16_T_LOCK_FREE see below
 24#define ATOMIC_CHAR32_T_LOCK_FREE see below
 25#define ATOMIC_WCHAR_T_LOCK_FREE see below
 26#define ATOMIC_SHORT_LOCK_FREE see below
 27#define ATOMIC_INT_LOCK_FREE see below
 28#define ATOMIC_LONG_LOCK_FREE see below
 29#define ATOMIC_LLONG_LOCK_FREE see below
 30#define ATOMIC_POINTER_LOCK_FREE see below
 31
 32using std::memory_order                // see below
 33using std::memory_order_relaxed        // see below
 34using std::memory_order_consume        // see below
 35using std::memory_order_acquire        // see below
 36using std::memory_order_release        // see below
 37using std::memory_order_acq_rel        // see below
 38using std::memory_order_seq_cst        // see below
 39
 40using std::atomic_flag                 // see below
 41
 42using std::atomic_bool                 // see below
 43using std::atomic_char                 // see below
 44using std::atomic_schar                // see below
 45using std::atomic_uchar                // see below
 46using std::atomic_short                // see below
 47using std::atomic_ushort               // see below
 48using std::atomic_int                  // see below
 49using std::atomic_uint                 // see below
 50using std::atomic_long                 // see below
 51using std::atomic_ulong                // see below
 52using std::atomic_llong                // see below
 53using std::atomic_ullong               // see below
 54using std::atomic_char8_t              // see below
 55using std::atomic_char16_t             // see below
 56using std::atomic_char32_t             // see below
 57using std::atomic_wchar_t              // see below
 58using std::atomic_int8_t               // see below
 59using std::atomic_uint8_t              // see below
 60using std::atomic_int16_t              // see below
 61using std::atomic_uint16_t             // see below
 62using std::atomic_int32_t              // see below
 63using std::atomic_uint32_t             // see below
 64using std::atomic_int64_t              // see below
 65using std::atomic_uint64_t             // see below
 66using std::atomic_int_least8_t         // see below
 67using std::atomic_uint_least8_t        // see below
 68using std::atomic_int_least16_t        // see below
 69using std::atomic_uint_least16_t       // see below
 70using std::atomic_int_least32_t        // see below
 71using std::atomic_uint_least32_t       // see below
 72using std::atomic_int_least64_t        // see below
 73using std::atomic_uint_least64_t       // see below
 74using std::atomic_int_fast8_t          // see below
 75using std::atomic_uint_fast8_t         // see below
 76using std::atomic_int_fast16_t         // see below
 77using std::atomic_uint_fast16_t        // see below
 78using std::atomic_int_fast32_t         // see below
 79using std::atomic_uint_fast32_t        // see below
 80using std::atomic_int_fast64_t         // see below
 81using std::atomic_uint_fast64_t        // see below
 82using std::atomic_intptr_t             // see below
 83using std::atomic_uintptr_t            // see below
 84using std::atomic_size_t               // see below
 85using std::atomic_ptrdiff_t            // see below
 86using std::atomic_intmax_t             // see below
 87using std::atomic_uintmax_t            // see below
 88
 89using std::atomic_is_lock_free                         // see below
 90using std::atomic_load                                 // see below
 91using std::atomic_load_explicit                        // see below
 92using std::atomic_store                                // see below
 93using std::atomic_store_explicit                       // see below
 94using std::atomic_exchange                             // see below
 95using std::atomic_exchange_explicit                    // see below
 96using std::atomic_compare_exchange_strong              // see below
 97using std::atomic_compare_exchange_strong_explicit     // see below
 98using std::atomic_compare_exchange_weak                // see below
 99using std::atomic_compare_exchange_weak_explicit       // see below
100using std::atomic_fetch_add                            // see below
101using std::atomic_fetch_add_explicit                   // see below
102using std::atomic_fetch_sub                            // see below
103using std::atomic_fetch_sub_explicit                   // see below
104using std::atomic_fetch_or                             // see below
105using std::atomic_fetch_or_explicit                    // see below
106using std::atomic_fetch_xor                            // see below
107using std::atomic_fetch_xor_explicit                   // see below
108using std::atomic_fetch_and                            // see below
109using std::atomic_fetch_and_explicit                   // see below
110using std::atomic_flag_test_and_set                    // see below
111using std::atomic_flag_test_and_set_explicit           // see below
112using std::atomic_flag_clear                           // see below
113using std::atomic_flag_clear_explicit                  // see below
114
115using std::atomic_thread_fence                         // see below
116using std::atomic_signal_fence                         // see below
117
118*/
119
120#if defined(__cplusplus) && __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
121#  include <__cxx03/stdatomic.h>
122#else
123#  include <__config>
124
125#  if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
126#    pragma GCC system_header
127#  endif
128
129#  if defined(__cplusplus) && _LIBCPP_STD_VER >= 23
130
131#    include <atomic>
132#    include <version>
133
134#    ifdef _Atomic
135#      undef _Atomic
136#    endif
137
138#    define _Atomic(_Tp) ::std::atomic<_Tp>
139
140using std::memory_order _LIBCPP_USING_IF_EXISTS;
141using std::memory_order_relaxed _LIBCPP_USING_IF_EXISTS;
142using std::memory_order_consume _LIBCPP_USING_IF_EXISTS;
143using std::memory_order_acquire _LIBCPP_USING_IF_EXISTS;
144using std::memory_order_release _LIBCPP_USING_IF_EXISTS;
145using std::memory_order_acq_rel _LIBCPP_USING_IF_EXISTS;
146using std::memory_order_seq_cst _LIBCPP_USING_IF_EXISTS;
147
148using std::atomic_flag _LIBCPP_USING_IF_EXISTS;
149
150using std::atomic_bool _LIBCPP_USING_IF_EXISTS;
151using std::atomic_char _LIBCPP_USING_IF_EXISTS;
152using std::atomic_schar _LIBCPP_USING_IF_EXISTS;
153using std::atomic_uchar _LIBCPP_USING_IF_EXISTS;
154using std::atomic_short _LIBCPP_USING_IF_EXISTS;
155using std::atomic_ushort _LIBCPP_USING_IF_EXISTS;
156using std::atomic_int _LIBCPP_USING_IF_EXISTS;
157using std::atomic_uint _LIBCPP_USING_IF_EXISTS;
158using std::atomic_long _LIBCPP_USING_IF_EXISTS;
159using std::atomic_ulong _LIBCPP_USING_IF_EXISTS;
160using std::atomic_llong _LIBCPP_USING_IF_EXISTS;
161using std::atomic_ullong _LIBCPP_USING_IF_EXISTS;
162#    if _LIBCPP_HAS_CHAR8_T
163using std::atomic_char8_t _LIBCPP_USING_IF_EXISTS;
164#    endif
165using std::atomic_char16_t _LIBCPP_USING_IF_EXISTS;
166using std::atomic_char32_t _LIBCPP_USING_IF_EXISTS;
167#    if _LIBCPP_HAS_WIDE_CHARACTERS
168using std::atomic_wchar_t _LIBCPP_USING_IF_EXISTS;
169#    endif
170
171using std::atomic_int8_t _LIBCPP_USING_IF_EXISTS;
172using std::atomic_uint8_t _LIBCPP_USING_IF_EXISTS;
173using std::atomic_int16_t _LIBCPP_USING_IF_EXISTS;
174using std::atomic_uint16_t _LIBCPP_USING_IF_EXISTS;
175using std::atomic_int32_t _LIBCPP_USING_IF_EXISTS;
176using std::atomic_uint32_t _LIBCPP_USING_IF_EXISTS;
177using std::atomic_int64_t _LIBCPP_USING_IF_EXISTS;
178using std::atomic_uint64_t _LIBCPP_USING_IF_EXISTS;
179
180using std::atomic_int_least8_t _LIBCPP_USING_IF_EXISTS;
181using std::atomic_uint_least8_t _LIBCPP_USING_IF_EXISTS;
182using std::atomic_int_least16_t _LIBCPP_USING_IF_EXISTS;
183using std::atomic_uint_least16_t _LIBCPP_USING_IF_EXISTS;
184using std::atomic_int_least32_t _LIBCPP_USING_IF_EXISTS;
185using std::atomic_uint_least32_t _LIBCPP_USING_IF_EXISTS;
186using std::atomic_int_least64_t _LIBCPP_USING_IF_EXISTS;
187using std::atomic_uint_least64_t _LIBCPP_USING_IF_EXISTS;
188
189using std::atomic_int_fast8_t _LIBCPP_USING_IF_EXISTS;
190using std::atomic_uint_fast8_t _LIBCPP_USING_IF_EXISTS;
191using std::atomic_int_fast16_t _LIBCPP_USING_IF_EXISTS;
192using std::atomic_uint_fast16_t _LIBCPP_USING_IF_EXISTS;
193using std::atomic_int_fast32_t _LIBCPP_USING_IF_EXISTS;
194using std::atomic_uint_fast32_t _LIBCPP_USING_IF_EXISTS;
195using std::atomic_int_fast64_t _LIBCPP_USING_IF_EXISTS;
196using std::atomic_uint_fast64_t _LIBCPP_USING_IF_EXISTS;
197
198using std::atomic_intptr_t _LIBCPP_USING_IF_EXISTS;
199using std::atomic_uintptr_t _LIBCPP_USING_IF_EXISTS;
200using std::atomic_size_t _LIBCPP_USING_IF_EXISTS;
201using std::atomic_ptrdiff_t _LIBCPP_USING_IF_EXISTS;
202using std::atomic_intmax_t _LIBCPP_USING_IF_EXISTS;
203using std::atomic_uintmax_t _LIBCPP_USING_IF_EXISTS;
204
205using std::atomic_compare_exchange_strong _LIBCPP_USING_IF_EXISTS;
206using std::atomic_compare_exchange_strong_explicit _LIBCPP_USING_IF_EXISTS;
207using std::atomic_compare_exchange_weak _LIBCPP_USING_IF_EXISTS;
208using std::atomic_compare_exchange_weak_explicit _LIBCPP_USING_IF_EXISTS;
209using std::atomic_exchange _LIBCPP_USING_IF_EXISTS;
210using std::atomic_exchange_explicit _LIBCPP_USING_IF_EXISTS;
211using std::atomic_fetch_add _LIBCPP_USING_IF_EXISTS;
212using std::atomic_fetch_add_explicit _LIBCPP_USING_IF_EXISTS;
213using std::atomic_fetch_and _LIBCPP_USING_IF_EXISTS;
214using std::atomic_fetch_and_explicit _LIBCPP_USING_IF_EXISTS;
215using std::atomic_fetch_or _LIBCPP_USING_IF_EXISTS;
216using std::atomic_fetch_xor_explicit _LIBCPP_USING_IF_EXISTS;
217using std::atomic_fetch_xor _LIBCPP_USING_IF_EXISTS;
218using std::atomic_fetch_or_explicit _LIBCPP_USING_IF_EXISTS;
219using std::atomic_fetch_sub _LIBCPP_USING_IF_EXISTS;
220using std::atomic_fetch_sub_explicit _LIBCPP_USING_IF_EXISTS;
221using std::atomic_flag_clear _LIBCPP_USING_IF_EXISTS;
222using std::atomic_flag_clear_explicit _LIBCPP_USING_IF_EXISTS;
223using std::atomic_flag_test_and_set _LIBCPP_USING_IF_EXISTS;
224using std::atomic_flag_test_and_set_explicit _LIBCPP_USING_IF_EXISTS;
225using std::atomic_is_lock_free _LIBCPP_USING_IF_EXISTS;
226using std::atomic_load _LIBCPP_USING_IF_EXISTS;
227using std::atomic_load_explicit _LIBCPP_USING_IF_EXISTS;
228using std::atomic_store _LIBCPP_USING_IF_EXISTS;
229using std::atomic_store_explicit _LIBCPP_USING_IF_EXISTS;
230
231using std::atomic_signal_fence _LIBCPP_USING_IF_EXISTS;
232using std::atomic_thread_fence _LIBCPP_USING_IF_EXISTS;
233
234#  elif defined(_LIBCPP_COMPILER_CLANG_BASED)
235
236// Before C++23, we include the next <stdatomic.h> on the path to avoid hijacking
237// the header. We do this because Clang has historically shipped a <stdatomic.h>
238// header that would be available in all Standard modes, and we don't want to
239// break that use case.
240#    if __has_include_next(<stdatomic.h>)
241#      include_next <stdatomic.h>
242#    endif
243
244#  endif // defined(__cplusplus) && _LIBCPP_STD_VER >= 23
245#endif   // defined(__cplusplus) && __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
246
247#endif // _LIBCPP_STDATOMIC_H