xref: /llvm-project/libcxx/include/stdatomic.h (revision bbd871e2baad2e74dbde202823b3439d2a96d3f8)
1586efd52SLouis Dionne // -*- C++ -*-
2586efd52SLouis Dionne //===----------------------------------------------------------------------===//
3586efd52SLouis Dionne //
4586efd52SLouis Dionne // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5586efd52SLouis Dionne // See https://llvm.org/LICENSE.txt for license information.
6586efd52SLouis Dionne // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7586efd52SLouis Dionne //
8586efd52SLouis Dionne //===----------------------------------------------------------------------===//
9586efd52SLouis Dionne 
10586efd52SLouis Dionne #ifndef _LIBCPP_STDATOMIC_H
11586efd52SLouis Dionne #define _LIBCPP_STDATOMIC_H
12586efd52SLouis Dionne 
13586efd52SLouis Dionne /*
14586efd52SLouis Dionne     stdatomic.h synopsis
15586efd52SLouis Dionne 
16586efd52SLouis Dionne template<class T>
17586efd52SLouis Dionne   using std-atomic = std::atomic<T>;        // exposition only
18586efd52SLouis Dionne 
19586efd52SLouis Dionne #define _Atomic(T) std-atomic<T>
20586efd52SLouis Dionne 
21586efd52SLouis Dionne #define ATOMIC_BOOL_LOCK_FREE see below
22586efd52SLouis Dionne #define ATOMIC_CHAR_LOCK_FREE see below
23586efd52SLouis Dionne #define ATOMIC_CHAR16_T_LOCK_FREE see below
24586efd52SLouis Dionne #define ATOMIC_CHAR32_T_LOCK_FREE see below
25586efd52SLouis Dionne #define ATOMIC_WCHAR_T_LOCK_FREE see below
26586efd52SLouis Dionne #define ATOMIC_SHORT_LOCK_FREE see below
27586efd52SLouis Dionne #define ATOMIC_INT_LOCK_FREE see below
28586efd52SLouis Dionne #define ATOMIC_LONG_LOCK_FREE see below
29586efd52SLouis Dionne #define ATOMIC_LLONG_LOCK_FREE see below
30586efd52SLouis Dionne #define ATOMIC_POINTER_LOCK_FREE see below
31586efd52SLouis Dionne 
32586efd52SLouis Dionne using std::memory_order                // see below
33586efd52SLouis Dionne using std::memory_order_relaxed        // see below
34586efd52SLouis Dionne using std::memory_order_consume        // see below
35586efd52SLouis Dionne using std::memory_order_acquire        // see below
36586efd52SLouis Dionne using std::memory_order_release        // see below
37586efd52SLouis Dionne using std::memory_order_acq_rel        // see below
38586efd52SLouis Dionne using std::memory_order_seq_cst        // see below
39586efd52SLouis Dionne 
40586efd52SLouis Dionne using std::atomic_flag                 // see below
41586efd52SLouis Dionne 
42586efd52SLouis Dionne using std::atomic_bool                 // see below
43586efd52SLouis Dionne using std::atomic_char                 // see below
44586efd52SLouis Dionne using std::atomic_schar                // see below
45586efd52SLouis Dionne using std::atomic_uchar                // see below
46586efd52SLouis Dionne using std::atomic_short                // see below
47586efd52SLouis Dionne using std::atomic_ushort               // see below
48586efd52SLouis Dionne using std::atomic_int                  // see below
49586efd52SLouis Dionne using std::atomic_uint                 // see below
50586efd52SLouis Dionne using std::atomic_long                 // see below
51586efd52SLouis Dionne using std::atomic_ulong                // see below
52586efd52SLouis Dionne using std::atomic_llong                // see below
53586efd52SLouis Dionne using std::atomic_ullong               // see below
54586efd52SLouis Dionne using std::atomic_char8_t              // see below
55586efd52SLouis Dionne using std::atomic_char16_t             // see below
56586efd52SLouis Dionne using std::atomic_char32_t             // see below
57586efd52SLouis Dionne using std::atomic_wchar_t              // see below
58586efd52SLouis Dionne using std::atomic_int8_t               // see below
59586efd52SLouis Dionne using std::atomic_uint8_t              // see below
60586efd52SLouis Dionne using std::atomic_int16_t              // see below
61586efd52SLouis Dionne using std::atomic_uint16_t             // see below
62586efd52SLouis Dionne using std::atomic_int32_t              // see below
63586efd52SLouis Dionne using std::atomic_uint32_t             // see below
64586efd52SLouis Dionne using std::atomic_int64_t              // see below
65586efd52SLouis Dionne using std::atomic_uint64_t             // see below
66586efd52SLouis Dionne using std::atomic_int_least8_t         // see below
67586efd52SLouis Dionne using std::atomic_uint_least8_t        // see below
68586efd52SLouis Dionne using std::atomic_int_least16_t        // see below
69586efd52SLouis Dionne using std::atomic_uint_least16_t       // see below
70586efd52SLouis Dionne using std::atomic_int_least32_t        // see below
71586efd52SLouis Dionne using std::atomic_uint_least32_t       // see below
72586efd52SLouis Dionne using std::atomic_int_least64_t        // see below
73586efd52SLouis Dionne using std::atomic_uint_least64_t       // see below
74586efd52SLouis Dionne using std::atomic_int_fast8_t          // see below
75586efd52SLouis Dionne using std::atomic_uint_fast8_t         // see below
76586efd52SLouis Dionne using std::atomic_int_fast16_t         // see below
77586efd52SLouis Dionne using std::atomic_uint_fast16_t        // see below
78586efd52SLouis Dionne using std::atomic_int_fast32_t         // see below
79586efd52SLouis Dionne using std::atomic_uint_fast32_t        // see below
80586efd52SLouis Dionne using std::atomic_int_fast64_t         // see below
81586efd52SLouis Dionne using std::atomic_uint_fast64_t        // see below
82586efd52SLouis Dionne using std::atomic_intptr_t             // see below
83586efd52SLouis Dionne using std::atomic_uintptr_t            // see below
84586efd52SLouis Dionne using std::atomic_size_t               // see below
85586efd52SLouis Dionne using std::atomic_ptrdiff_t            // see below
86586efd52SLouis Dionne using std::atomic_intmax_t             // see below
87586efd52SLouis Dionne using std::atomic_uintmax_t            // see below
88586efd52SLouis Dionne 
89586efd52SLouis Dionne using std::atomic_is_lock_free                         // see below
90586efd52SLouis Dionne using std::atomic_load                                 // see below
91586efd52SLouis Dionne using std::atomic_load_explicit                        // see below
92586efd52SLouis Dionne using std::atomic_store                                // see below
93586efd52SLouis Dionne using std::atomic_store_explicit                       // see below
94586efd52SLouis Dionne using std::atomic_exchange                             // see below
95586efd52SLouis Dionne using std::atomic_exchange_explicit                    // see below
96586efd52SLouis Dionne using std::atomic_compare_exchange_strong              // see below
97586efd52SLouis Dionne using std::atomic_compare_exchange_strong_explicit     // see below
98586efd52SLouis Dionne using std::atomic_compare_exchange_weak                // see below
99586efd52SLouis Dionne using std::atomic_compare_exchange_weak_explicit       // see below
100586efd52SLouis Dionne using std::atomic_fetch_add                            // see below
101586efd52SLouis Dionne using std::atomic_fetch_add_explicit                   // see below
102586efd52SLouis Dionne using std::atomic_fetch_sub                            // see below
103586efd52SLouis Dionne using std::atomic_fetch_sub_explicit                   // see below
104586efd52SLouis Dionne using std::atomic_fetch_or                             // see below
105586efd52SLouis Dionne using std::atomic_fetch_or_explicit                    // see below
106442c33f3SMark de Wever using std::atomic_fetch_xor                            // see below
107442c33f3SMark de Wever using std::atomic_fetch_xor_explicit                   // see below
108586efd52SLouis Dionne using std::atomic_fetch_and                            // see below
109586efd52SLouis Dionne using std::atomic_fetch_and_explicit                   // see below
110586efd52SLouis Dionne using std::atomic_flag_test_and_set                    // see below
111586efd52SLouis Dionne using std::atomic_flag_test_and_set_explicit           // see below
112586efd52SLouis Dionne using std::atomic_flag_clear                           // see below
113586efd52SLouis Dionne using std::atomic_flag_clear_explicit                  // see below
114586efd52SLouis Dionne 
115586efd52SLouis Dionne using std::atomic_thread_fence                         // see below
116586efd52SLouis Dionne using std::atomic_signal_fence                         // see below
117586efd52SLouis Dionne 
118586efd52SLouis Dionne */
119586efd52SLouis Dionne 
120b9a2658aSNikolas Klauser #if defined(__cplusplus) && __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
121b9a2658aSNikolas Klauser #  include <__cxx03/stdatomic.h>
122b9a2658aSNikolas Klauser #else
123586efd52SLouis Dionne #  include <__config>
124586efd52SLouis Dionne 
125586efd52SLouis Dionne #  if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
126586efd52SLouis Dionne #    pragma GCC system_header
127586efd52SLouis Dionne #  endif
128586efd52SLouis Dionne 
129*bbd871e2SLouis Dionne #  if defined(__cplusplus) && _LIBCPP_STD_VER >= 23
130586efd52SLouis Dionne 
131586efd52SLouis Dionne #    include <atomic>
132586efd52SLouis Dionne #    include <version>
133586efd52SLouis Dionne 
134586efd52SLouis Dionne #    ifdef _Atomic
135586efd52SLouis Dionne #      undef _Atomic
136586efd52SLouis Dionne #    endif
137586efd52SLouis Dionne 
138586efd52SLouis Dionne #    define _Atomic(_Tp) ::std::atomic<_Tp>
139586efd52SLouis Dionne 
140586efd52SLouis Dionne using std::memory_order _LIBCPP_USING_IF_EXISTS;
141586efd52SLouis Dionne using std::memory_order_relaxed _LIBCPP_USING_IF_EXISTS;
142586efd52SLouis Dionne using std::memory_order_consume _LIBCPP_USING_IF_EXISTS;
143586efd52SLouis Dionne using std::memory_order_acquire _LIBCPP_USING_IF_EXISTS;
144586efd52SLouis Dionne using std::memory_order_release _LIBCPP_USING_IF_EXISTS;
145586efd52SLouis Dionne using std::memory_order_acq_rel _LIBCPP_USING_IF_EXISTS;
146586efd52SLouis Dionne using std::memory_order_seq_cst _LIBCPP_USING_IF_EXISTS;
147586efd52SLouis Dionne 
148586efd52SLouis Dionne using std::atomic_flag _LIBCPP_USING_IF_EXISTS;
149586efd52SLouis Dionne 
150586efd52SLouis Dionne using std::atomic_bool _LIBCPP_USING_IF_EXISTS;
151586efd52SLouis Dionne using std::atomic_char _LIBCPP_USING_IF_EXISTS;
152586efd52SLouis Dionne using std::atomic_schar _LIBCPP_USING_IF_EXISTS;
153586efd52SLouis Dionne using std::atomic_uchar _LIBCPP_USING_IF_EXISTS;
154586efd52SLouis Dionne using std::atomic_short _LIBCPP_USING_IF_EXISTS;
155586efd52SLouis Dionne using std::atomic_ushort _LIBCPP_USING_IF_EXISTS;
156586efd52SLouis Dionne using std::atomic_int _LIBCPP_USING_IF_EXISTS;
157586efd52SLouis Dionne using std::atomic_uint _LIBCPP_USING_IF_EXISTS;
158586efd52SLouis Dionne using std::atomic_long _LIBCPP_USING_IF_EXISTS;
159586efd52SLouis Dionne using std::atomic_ulong _LIBCPP_USING_IF_EXISTS;
160586efd52SLouis Dionne using std::atomic_llong _LIBCPP_USING_IF_EXISTS;
161586efd52SLouis Dionne using std::atomic_ullong _LIBCPP_USING_IF_EXISTS;
162ba87515fSNikolas Klauser #    if _LIBCPP_HAS_CHAR8_T
163586efd52SLouis Dionne using std::atomic_char8_t _LIBCPP_USING_IF_EXISTS;
1642d26fc8cSRyan Prichard #    endif
165586efd52SLouis Dionne using std::atomic_char16_t _LIBCPP_USING_IF_EXISTS;
166586efd52SLouis Dionne using std::atomic_char32_t _LIBCPP_USING_IF_EXISTS;
167c6f3b7bcSNikolas Klauser #    if _LIBCPP_HAS_WIDE_CHARACTERS
168586efd52SLouis Dionne using std::atomic_wchar_t _LIBCPP_USING_IF_EXISTS;
1692d26fc8cSRyan Prichard #    endif
170586efd52SLouis Dionne 
171586efd52SLouis Dionne using std::atomic_int8_t _LIBCPP_USING_IF_EXISTS;
172586efd52SLouis Dionne using std::atomic_uint8_t _LIBCPP_USING_IF_EXISTS;
173586efd52SLouis Dionne using std::atomic_int16_t _LIBCPP_USING_IF_EXISTS;
174586efd52SLouis Dionne using std::atomic_uint16_t _LIBCPP_USING_IF_EXISTS;
175586efd52SLouis Dionne using std::atomic_int32_t _LIBCPP_USING_IF_EXISTS;
176586efd52SLouis Dionne using std::atomic_uint32_t _LIBCPP_USING_IF_EXISTS;
177586efd52SLouis Dionne using std::atomic_int64_t _LIBCPP_USING_IF_EXISTS;
178586efd52SLouis Dionne using std::atomic_uint64_t _LIBCPP_USING_IF_EXISTS;
179586efd52SLouis Dionne 
180586efd52SLouis Dionne using std::atomic_int_least8_t _LIBCPP_USING_IF_EXISTS;
181586efd52SLouis Dionne using std::atomic_uint_least8_t _LIBCPP_USING_IF_EXISTS;
182586efd52SLouis Dionne using std::atomic_int_least16_t _LIBCPP_USING_IF_EXISTS;
183586efd52SLouis Dionne using std::atomic_uint_least16_t _LIBCPP_USING_IF_EXISTS;
184586efd52SLouis Dionne using std::atomic_int_least32_t _LIBCPP_USING_IF_EXISTS;
185586efd52SLouis Dionne using std::atomic_uint_least32_t _LIBCPP_USING_IF_EXISTS;
186586efd52SLouis Dionne using std::atomic_int_least64_t _LIBCPP_USING_IF_EXISTS;
187586efd52SLouis Dionne using std::atomic_uint_least64_t _LIBCPP_USING_IF_EXISTS;
188586efd52SLouis Dionne 
189586efd52SLouis Dionne using std::atomic_int_fast8_t _LIBCPP_USING_IF_EXISTS;
190586efd52SLouis Dionne using std::atomic_uint_fast8_t _LIBCPP_USING_IF_EXISTS;
191586efd52SLouis Dionne using std::atomic_int_fast16_t _LIBCPP_USING_IF_EXISTS;
192586efd52SLouis Dionne using std::atomic_uint_fast16_t _LIBCPP_USING_IF_EXISTS;
193586efd52SLouis Dionne using std::atomic_int_fast32_t _LIBCPP_USING_IF_EXISTS;
194586efd52SLouis Dionne using std::atomic_uint_fast32_t _LIBCPP_USING_IF_EXISTS;
195586efd52SLouis Dionne using std::atomic_int_fast64_t _LIBCPP_USING_IF_EXISTS;
196586efd52SLouis Dionne using std::atomic_uint_fast64_t _LIBCPP_USING_IF_EXISTS;
197586efd52SLouis Dionne 
198586efd52SLouis Dionne using std::atomic_intptr_t _LIBCPP_USING_IF_EXISTS;
199586efd52SLouis Dionne using std::atomic_uintptr_t _LIBCPP_USING_IF_EXISTS;
200586efd52SLouis Dionne using std::atomic_size_t _LIBCPP_USING_IF_EXISTS;
201586efd52SLouis Dionne using std::atomic_ptrdiff_t _LIBCPP_USING_IF_EXISTS;
202586efd52SLouis Dionne using std::atomic_intmax_t _LIBCPP_USING_IF_EXISTS;
203586efd52SLouis Dionne using std::atomic_uintmax_t _LIBCPP_USING_IF_EXISTS;
204586efd52SLouis Dionne 
205586efd52SLouis Dionne using std::atomic_compare_exchange_strong _LIBCPP_USING_IF_EXISTS;
206586efd52SLouis Dionne using std::atomic_compare_exchange_strong_explicit _LIBCPP_USING_IF_EXISTS;
207586efd52SLouis Dionne using std::atomic_compare_exchange_weak _LIBCPP_USING_IF_EXISTS;
208586efd52SLouis Dionne using std::atomic_compare_exchange_weak_explicit _LIBCPP_USING_IF_EXISTS;
209586efd52SLouis Dionne using std::atomic_exchange _LIBCPP_USING_IF_EXISTS;
210586efd52SLouis Dionne using std::atomic_exchange_explicit _LIBCPP_USING_IF_EXISTS;
211586efd52SLouis Dionne using std::atomic_fetch_add _LIBCPP_USING_IF_EXISTS;
212586efd52SLouis Dionne using std::atomic_fetch_add_explicit _LIBCPP_USING_IF_EXISTS;
213586efd52SLouis Dionne using std::atomic_fetch_and _LIBCPP_USING_IF_EXISTS;
214586efd52SLouis Dionne using std::atomic_fetch_and_explicit _LIBCPP_USING_IF_EXISTS;
215586efd52SLouis Dionne using std::atomic_fetch_or _LIBCPP_USING_IF_EXISTS;
216442c33f3SMark de Wever using std::atomic_fetch_xor_explicit _LIBCPP_USING_IF_EXISTS;
217442c33f3SMark de Wever using std::atomic_fetch_xor _LIBCPP_USING_IF_EXISTS;
218586efd52SLouis Dionne using std::atomic_fetch_or_explicit _LIBCPP_USING_IF_EXISTS;
219586efd52SLouis Dionne using std::atomic_fetch_sub _LIBCPP_USING_IF_EXISTS;
220586efd52SLouis Dionne using std::atomic_fetch_sub_explicit _LIBCPP_USING_IF_EXISTS;
221586efd52SLouis Dionne using std::atomic_flag_clear _LIBCPP_USING_IF_EXISTS;
222586efd52SLouis Dionne using std::atomic_flag_clear_explicit _LIBCPP_USING_IF_EXISTS;
223586efd52SLouis Dionne using std::atomic_flag_test_and_set _LIBCPP_USING_IF_EXISTS;
224586efd52SLouis Dionne using std::atomic_flag_test_and_set_explicit _LIBCPP_USING_IF_EXISTS;
225586efd52SLouis Dionne using std::atomic_is_lock_free _LIBCPP_USING_IF_EXISTS;
226586efd52SLouis Dionne using std::atomic_load _LIBCPP_USING_IF_EXISTS;
227586efd52SLouis Dionne using std::atomic_load_explicit _LIBCPP_USING_IF_EXISTS;
228586efd52SLouis Dionne using std::atomic_store _LIBCPP_USING_IF_EXISTS;
229586efd52SLouis Dionne using std::atomic_store_explicit _LIBCPP_USING_IF_EXISTS;
230586efd52SLouis Dionne 
231586efd52SLouis Dionne using std::atomic_signal_fence _LIBCPP_USING_IF_EXISTS;
232586efd52SLouis Dionne using std::atomic_thread_fence _LIBCPP_USING_IF_EXISTS;
233586efd52SLouis Dionne 
234*bbd871e2SLouis Dionne #  elif defined(_LIBCPP_COMPILER_CLANG_BASED)
235586efd52SLouis Dionne 
236*bbd871e2SLouis Dionne // Before C++23, we include the next <stdatomic.h> on the path to avoid hijacking
237*bbd871e2SLouis Dionne // the header. We do this because Clang has historically shipped a <stdatomic.h>
238*bbd871e2SLouis Dionne // header that would be available in all Standard modes, and we don't want to
239*bbd871e2SLouis Dionne // break that use case.
240586efd52SLouis Dionne #    if __has_include_next(<stdatomic.h>)
241586efd52SLouis Dionne #      include_next <stdatomic.h>
242586efd52SLouis Dionne #    endif
243586efd52SLouis Dionne 
244*bbd871e2SLouis Dionne #  endif // defined(__cplusplus) && _LIBCPP_STD_VER >= 23
245b9a2658aSNikolas Klauser #endif   // defined(__cplusplus) && __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
246586efd52SLouis Dionne 
247586efd52SLouis Dionne #endif // _LIBCPP_STDATOMIC_H
248