blob: 4b4c347a570460e81bbf8c2b131c321d104b0db2 [file] [log] [blame]
Howard Hinnant71be7292010-09-27 21:17:38 +00001// -*- C++ -*-
Louis Dionne9bd93882021-11-17 16:25:01 -05002//===----------------------------------------------------------------------===//
Howard Hinnant71be7292010-09-27 21:17:38 +00003//
Chandler Carruth7642bb12019-01-19 08:50:56 +00004// 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
Howard Hinnant71be7292010-09-27 21:17:38 +00007//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP_ATOMIC
11#define _LIBCPP_ATOMIC
12
13/*
14 atomic synopsis
15
16namespace std
17{
18
Olivier Girouxdf5bfa32020-09-09 10:00:09 -070019// feature test macro [version.syn]
JF Bastienfdb42c22016-03-25 15:48:21 +000020
Olivier Girouxdf5bfa32020-09-09 10:00:09 -070021#define __cpp_lib_atomic_is_always_lock_free
22#define __cpp_lib_atomic_flag_test
23#define __cpp_lib_atomic_lock_free_type_aliases
24#define __cpp_lib_atomic_wait
JF Bastienfdb42c22016-03-25 15:48:21 +000025
Davide Italiano011f80a2019-03-05 18:40:49 +000026 // order and consistency
Howard Hinnant71be7292010-09-27 21:17:38 +000027
Davide Italiano011f80a2019-03-05 18:40:49 +000028 enum memory_order: unspecified // enum class in C++20
29 {
30 relaxed,
31 consume, // load-consume
32 acquire, // load-acquire
33 release, // store-release
34 acq_rel, // store-release load-acquire
35 seq_cst // store-release load-acquire
36 };
37
38 inline constexpr auto memory_order_relaxed = memory_order::relaxed;
39 inline constexpr auto memory_order_consume = memory_order::consume;
40 inline constexpr auto memory_order_acquire = memory_order::acquire;
41 inline constexpr auto memory_order_release = memory_order::release;
42 inline constexpr auto memory_order_acq_rel = memory_order::acq_rel;
43 inline constexpr auto memory_order_seq_cst = memory_order::seq_cst;
Howard Hinnant71be7292010-09-27 21:17:38 +000044
Howard Hinnanteee2c142012-04-11 20:14:21 +000045template <class T> T kill_dependency(T y) noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +000046
47// lock-free property
48
Howard Hinnant931e3402013-01-21 20:39:41 +000049#define ATOMIC_BOOL_LOCK_FREE unspecified
Howard Hinnant71be7292010-09-27 21:17:38 +000050#define ATOMIC_CHAR_LOCK_FREE unspecified
Marek Kurdej91bebaa2020-11-24 21:07:06 +010051#define ATOMIC_CHAR8_T_LOCK_FREE unspecified // C++20
Howard Hinnant71be7292010-09-27 21:17:38 +000052#define ATOMIC_CHAR16_T_LOCK_FREE unspecified
53#define ATOMIC_CHAR32_T_LOCK_FREE unspecified
54#define ATOMIC_WCHAR_T_LOCK_FREE unspecified
55#define ATOMIC_SHORT_LOCK_FREE unspecified
56#define ATOMIC_INT_LOCK_FREE unspecified
57#define ATOMIC_LONG_LOCK_FREE unspecified
58#define ATOMIC_LLONG_LOCK_FREE unspecified
Howard Hinnant931e3402013-01-21 20:39:41 +000059#define ATOMIC_POINTER_LOCK_FREE unspecified
Howard Hinnant71be7292010-09-27 21:17:38 +000060
Howard Hinnant71be7292010-09-27 21:17:38 +000061template <class T>
62struct atomic
63{
Olivier Giroux6031a712020-06-01 14:30:13 -070064 using value_type = T;
65
JF Bastienfdb42c22016-03-25 15:48:21 +000066 static constexpr bool is_always_lock_free;
Howard Hinnanteee2c142012-04-11 20:14:21 +000067 bool is_lock_free() const volatile noexcept;
68 bool is_lock_free() const noexcept;
Olivier Giroux6031a712020-06-01 14:30:13 -070069
Raul Tambre4e0e88f2021-06-06 19:02:20 +030070 atomic() noexcept = default; // until C++20
71 constexpr atomic() noexcept(is_nothrow_default_constructible_v<T>); // since C++20
Olivier Giroux6031a712020-06-01 14:30:13 -070072 constexpr atomic(T desr) noexcept;
73 atomic(const atomic&) = delete;
74 atomic& operator=(const atomic&) = delete;
75 atomic& operator=(const atomic&) volatile = delete;
76
Howard Hinnanteee2c142012-04-11 20:14:21 +000077 T load(memory_order m = memory_order_seq_cst) const volatile noexcept;
78 T load(memory_order m = memory_order_seq_cst) const noexcept;
79 operator T() const volatile noexcept;
80 operator T() const noexcept;
Olivier Giroux6031a712020-06-01 14:30:13 -070081 void store(T desr, memory_order m = memory_order_seq_cst) volatile noexcept;
82 void store(T desr, memory_order m = memory_order_seq_cst) noexcept;
83 T operator=(T) volatile noexcept;
84 T operator=(T) noexcept;
85
Howard Hinnanteee2c142012-04-11 20:14:21 +000086 T exchange(T desr, memory_order m = memory_order_seq_cst) volatile noexcept;
87 T exchange(T desr, memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +000088 bool compare_exchange_weak(T& expc, T desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +000089 memory_order s, memory_order f) volatile noexcept;
90 bool compare_exchange_weak(T& expc, T desr, memory_order s, memory_order f) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +000091 bool compare_exchange_strong(T& expc, T desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +000092 memory_order s, memory_order f) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +000093 bool compare_exchange_strong(T& expc, T desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +000094 memory_order s, memory_order f) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +000095 bool compare_exchange_weak(T& expc, T desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +000096 memory_order m = memory_order_seq_cst) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +000097 bool compare_exchange_weak(T& expc, T desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +000098 memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +000099 bool compare_exchange_strong(T& expc, T desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000100 memory_order m = memory_order_seq_cst) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000101 bool compare_exchange_strong(T& expc, T desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000102 memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +0000103
Olivier Giroux6031a712020-06-01 14:30:13 -0700104 void wait(T, memory_order = memory_order::seq_cst) const volatile noexcept;
105 void wait(T, memory_order = memory_order::seq_cst) const noexcept;
106 void notify_one() volatile noexcept;
107 void notify_one() noexcept;
108 void notify_all() volatile noexcept;
109 void notify_all() noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +0000110};
111
112template <>
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000113struct atomic<integral>
Howard Hinnant71be7292010-09-27 21:17:38 +0000114{
Olivier Giroux6031a712020-06-01 14:30:13 -0700115 using value_type = integral;
Olivier Girouxdf5bfa32020-09-09 10:00:09 -0700116 using difference_type = value_type;
Olivier Giroux6031a712020-06-01 14:30:13 -0700117
JF Bastienfdb42c22016-03-25 15:48:21 +0000118 static constexpr bool is_always_lock_free;
Howard Hinnanteee2c142012-04-11 20:14:21 +0000119 bool is_lock_free() const volatile noexcept;
120 bool is_lock_free() const noexcept;
Olivier Giroux6031a712020-06-01 14:30:13 -0700121
122 atomic() noexcept = default;
123 constexpr atomic(integral desr) noexcept;
124 atomic(const atomic&) = delete;
125 atomic& operator=(const atomic&) = delete;
126 atomic& operator=(const atomic&) volatile = delete;
127
Howard Hinnanteee2c142012-04-11 20:14:21 +0000128 integral load(memory_order m = memory_order_seq_cst) const volatile noexcept;
129 integral load(memory_order m = memory_order_seq_cst) const noexcept;
130 operator integral() const volatile noexcept;
131 operator integral() const noexcept;
Olivier Giroux6031a712020-06-01 14:30:13 -0700132 void store(integral desr, memory_order m = memory_order_seq_cst) volatile noexcept;
133 void store(integral desr, memory_order m = memory_order_seq_cst) noexcept;
134 integral operator=(integral desr) volatile noexcept;
135 integral operator=(integral desr) noexcept;
136
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000137 integral exchange(integral desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000138 memory_order m = memory_order_seq_cst) volatile noexcept;
139 integral exchange(integral desr, memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000140 bool compare_exchange_weak(integral& expc, integral desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000141 memory_order s, memory_order f) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000142 bool compare_exchange_weak(integral& expc, integral desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000143 memory_order s, memory_order f) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000144 bool compare_exchange_strong(integral& expc, integral desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000145 memory_order s, memory_order f) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000146 bool compare_exchange_strong(integral& expc, integral desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000147 memory_order s, memory_order f) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000148 bool compare_exchange_weak(integral& expc, integral desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000149 memory_order m = memory_order_seq_cst) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000150 bool compare_exchange_weak(integral& expc, integral desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000151 memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000152 bool compare_exchange_strong(integral& expc, integral desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000153 memory_order m = memory_order_seq_cst) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000154 bool compare_exchange_strong(integral& expc, integral desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000155 memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +0000156
Olivier Giroux6031a712020-06-01 14:30:13 -0700157 integral fetch_add(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
Howard Hinnanteee2c142012-04-11 20:14:21 +0000158 integral fetch_add(integral op, memory_order m = memory_order_seq_cst) noexcept;
Olivier Giroux6031a712020-06-01 14:30:13 -0700159 integral fetch_sub(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
Howard Hinnanteee2c142012-04-11 20:14:21 +0000160 integral fetch_sub(integral op, memory_order m = memory_order_seq_cst) noexcept;
Olivier Giroux6031a712020-06-01 14:30:13 -0700161 integral fetch_and(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
Howard Hinnanteee2c142012-04-11 20:14:21 +0000162 integral fetch_and(integral op, memory_order m = memory_order_seq_cst) noexcept;
Olivier Giroux6031a712020-06-01 14:30:13 -0700163 integral fetch_or(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
Howard Hinnanteee2c142012-04-11 20:14:21 +0000164 integral fetch_or(integral op, memory_order m = memory_order_seq_cst) noexcept;
Olivier Giroux6031a712020-06-01 14:30:13 -0700165 integral fetch_xor(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
Howard Hinnanteee2c142012-04-11 20:14:21 +0000166 integral fetch_xor(integral op, memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +0000167
Howard Hinnanteee2c142012-04-11 20:14:21 +0000168 integral operator++(int) volatile noexcept;
169 integral operator++(int) noexcept;
170 integral operator--(int) volatile noexcept;
171 integral operator--(int) noexcept;
172 integral operator++() volatile noexcept;
173 integral operator++() noexcept;
174 integral operator--() volatile noexcept;
175 integral operator--() noexcept;
176 integral operator+=(integral op) volatile noexcept;
177 integral operator+=(integral op) noexcept;
178 integral operator-=(integral op) volatile noexcept;
179 integral operator-=(integral op) noexcept;
180 integral operator&=(integral op) volatile noexcept;
181 integral operator&=(integral op) noexcept;
182 integral operator|=(integral op) volatile noexcept;
183 integral operator|=(integral op) noexcept;
184 integral operator^=(integral op) volatile noexcept;
185 integral operator^=(integral op) noexcept;
Olivier Giroux6031a712020-06-01 14:30:13 -0700186
187 void wait(integral, memory_order = memory_order::seq_cst) const volatile noexcept;
188 void wait(integral, memory_order = memory_order::seq_cst) const noexcept;
189 void notify_one() volatile noexcept;
190 void notify_one() noexcept;
191 void notify_all() volatile noexcept;
192 void notify_all() noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +0000193};
194
195template <class T>
196struct atomic<T*>
Howard Hinnant71be7292010-09-27 21:17:38 +0000197{
Olivier Giroux6031a712020-06-01 14:30:13 -0700198 using value_type = T*;
Olivier Girouxdf5bfa32020-09-09 10:00:09 -0700199 using difference_type = ptrdiff_t;
Olivier Giroux6031a712020-06-01 14:30:13 -0700200
JF Bastienfdb42c22016-03-25 15:48:21 +0000201 static constexpr bool is_always_lock_free;
Howard Hinnanteee2c142012-04-11 20:14:21 +0000202 bool is_lock_free() const volatile noexcept;
203 bool is_lock_free() const noexcept;
Olivier Giroux6031a712020-06-01 14:30:13 -0700204
Raul Tambre4e0e88f2021-06-06 19:02:20 +0300205 atomic() noexcept = default; // until C++20
206 constexpr atomic() noexcept; // since C++20
Olivier Giroux6031a712020-06-01 14:30:13 -0700207 constexpr atomic(T* desr) noexcept;
208 atomic(const atomic&) = delete;
209 atomic& operator=(const atomic&) = delete;
210 atomic& operator=(const atomic&) volatile = delete;
211
Howard Hinnanteee2c142012-04-11 20:14:21 +0000212 T* load(memory_order m = memory_order_seq_cst) const volatile noexcept;
213 T* load(memory_order m = memory_order_seq_cst) const noexcept;
214 operator T*() const volatile noexcept;
215 operator T*() const noexcept;
Olivier Giroux6031a712020-06-01 14:30:13 -0700216 void store(T* desr, memory_order m = memory_order_seq_cst) volatile noexcept;
217 void store(T* desr, memory_order m = memory_order_seq_cst) noexcept;
218 T* operator=(T*) volatile noexcept;
219 T* operator=(T*) noexcept;
220
Howard Hinnanteee2c142012-04-11 20:14:21 +0000221 T* exchange(T* desr, memory_order m = memory_order_seq_cst) volatile noexcept;
222 T* exchange(T* desr, memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000223 bool compare_exchange_weak(T*& expc, T* desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000224 memory_order s, memory_order f) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000225 bool compare_exchange_weak(T*& expc, T* desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000226 memory_order s, memory_order f) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000227 bool compare_exchange_strong(T*& expc, T* desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000228 memory_order s, memory_order f) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000229 bool compare_exchange_strong(T*& expc, T* desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000230 memory_order s, memory_order f) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000231 bool compare_exchange_weak(T*& expc, T* desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000232 memory_order m = memory_order_seq_cst) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000233 bool compare_exchange_weak(T*& expc, T* desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000234 memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000235 bool compare_exchange_strong(T*& expc, T* desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000236 memory_order m = memory_order_seq_cst) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000237 bool compare_exchange_strong(T*& expc, T* desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000238 memory_order m = memory_order_seq_cst) noexcept;
239 T* fetch_add(ptrdiff_t op, memory_order m = memory_order_seq_cst) volatile noexcept;
240 T* fetch_add(ptrdiff_t op, memory_order m = memory_order_seq_cst) noexcept;
241 T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst) volatile noexcept;
242 T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000243
Howard Hinnanteee2c142012-04-11 20:14:21 +0000244 T* operator++(int) volatile noexcept;
245 T* operator++(int) noexcept;
246 T* operator--(int) volatile noexcept;
247 T* operator--(int) noexcept;
248 T* operator++() volatile noexcept;
249 T* operator++() noexcept;
250 T* operator--() volatile noexcept;
251 T* operator--() noexcept;
252 T* operator+=(ptrdiff_t op) volatile noexcept;
253 T* operator+=(ptrdiff_t op) noexcept;
254 T* operator-=(ptrdiff_t op) volatile noexcept;
255 T* operator-=(ptrdiff_t op) noexcept;
Olivier Giroux6031a712020-06-01 14:30:13 -0700256
257 void wait(T*, memory_order = memory_order::seq_cst) const volatile noexcept;
258 void wait(T*, memory_order = memory_order::seq_cst) const noexcept;
259 void notify_one() volatile noexcept;
260 void notify_one() noexcept;
261 void notify_all() volatile noexcept;
262 void notify_all() noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +0000263};
264
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000265
Mark de Wever7d5df422021-06-06 14:48:08 +0200266// [atomics.nonmembers], non-member functions
267template<class T>
268 bool atomic_is_lock_free(const volatile atomic<T>*) noexcept;
269template<class T>
270 bool atomic_is_lock_free(const atomic<T>*) noexcept;
271template<class T>
272 void atomic_store(volatile atomic<T>*, atomic<T>::value_type) noexcept;
273template<class T>
274 void atomic_store(atomic<T>*, atomic<T>::value_type) noexcept;
275template<class T>
276 void atomic_store_explicit(volatile atomic<T>*, atomic<T>::value_type,
277 memory_order) noexcept;
278template<class T>
279 void atomic_store_explicit(atomic<T>*, atomic<T>::value_type,
280 memory_order) noexcept;
281template<class T>
282 T atomic_load(const volatile atomic<T>*) noexcept;
283template<class T>
284 T atomic_load(const atomic<T>*) noexcept;
285template<class T>
286 T atomic_load_explicit(const volatile atomic<T>*, memory_order) noexcept;
287template<class T>
288 T atomic_load_explicit(const atomic<T>*, memory_order) noexcept;
289template<class T>
290 T atomic_exchange(volatile atomic<T>*, atomic<T>::value_type) noexcept;
291template<class T>
292 T atomic_exchange(atomic<T>*, atomic<T>::value_type) noexcept;
293template<class T>
294 T atomic_exchange_explicit(volatile atomic<T>*, atomic<T>::value_type,
295 memory_order) noexcept;
296template<class T>
297 T atomic_exchange_explicit(atomic<T>*, atomic<T>::value_type,
298 memory_order) noexcept;
299template<class T>
300 bool atomic_compare_exchange_weak(volatile atomic<T>*, atomic<T>::value_type*,
301 atomic<T>::value_type) noexcept;
302template<class T>
303 bool atomic_compare_exchange_weak(atomic<T>*, atomic<T>::value_type*,
304 atomic<T>::value_type) noexcept;
305template<class T>
306 bool atomic_compare_exchange_strong(volatile atomic<T>*, atomic<T>::value_type*,
307 atomic<T>::value_type) noexcept;
308template<class T>
309 bool atomic_compare_exchange_strong(atomic<T>*, atomic<T>::value_type*,
310 atomic<T>::value_type) noexcept;
311template<class T>
312 bool atomic_compare_exchange_weak_explicit(volatile atomic<T>*, atomic<T>::value_type*,
313 atomic<T>::value_type,
314 memory_order, memory_order) noexcept;
315template<class T>
316 bool atomic_compare_exchange_weak_explicit(atomic<T>*, atomic<T>::value_type*,
317 atomic<T>::value_type,
318 memory_order, memory_order) noexcept;
319template<class T>
320 bool atomic_compare_exchange_strong_explicit(volatile atomic<T>*, atomic<T>::value_type*,
321 atomic<T>::value_type,
322 memory_order, memory_order) noexcept;
323template<class T>
324 bool atomic_compare_exchange_strong_explicit(atomic<T>*, atomic<T>::value_type*,
325 atomic<T>::value_type,
326 memory_order, memory_order) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000327
Mark de Wever7d5df422021-06-06 14:48:08 +0200328template<class T>
329 T atomic_fetch_add(volatile atomic<T>*, atomic<T>::difference_type) noexcept;
330template<class T>
331 T atomic_fetch_add(atomic<T>*, atomic<T>::difference_type) noexcept;
332template<class T>
333 T atomic_fetch_add_explicit(volatile atomic<T>*, atomic<T>::difference_type,
334 memory_order) noexcept;
335template<class T>
336 T atomic_fetch_add_explicit(atomic<T>*, atomic<T>::difference_type,
337 memory_order) noexcept;
338template<class T>
339 T atomic_fetch_sub(volatile atomic<T>*, atomic<T>::difference_type) noexcept;
340template<class T>
341 T atomic_fetch_sub(atomic<T>*, atomic<T>::difference_type) noexcept;
342template<class T>
343 T atomic_fetch_sub_explicit(volatile atomic<T>*, atomic<T>::difference_type,
344 memory_order) noexcept;
345template<class T>
346 T atomic_fetch_sub_explicit(atomic<T>*, atomic<T>::difference_type,
347 memory_order) noexcept;
348template<class T>
349 T atomic_fetch_and(volatile atomic<T>*, atomic<T>::value_type) noexcept;
350template<class T>
351 T atomic_fetch_and(atomic<T>*, atomic<T>::value_type) noexcept;
352template<class T>
353 T atomic_fetch_and_explicit(volatile atomic<T>*, atomic<T>::value_type,
354 memory_order) noexcept;
355template<class T>
356 T atomic_fetch_and_explicit(atomic<T>*, atomic<T>::value_type,
357 memory_order) noexcept;
358template<class T>
359 T atomic_fetch_or(volatile atomic<T>*, atomic<T>::value_type) noexcept;
360template<class T>
361 T atomic_fetch_or(atomic<T>*, atomic<T>::value_type) noexcept;
362template<class T>
363 T atomic_fetch_or_explicit(volatile atomic<T>*, atomic<T>::value_type,
364 memory_order) noexcept;
365template<class T>
366 T atomic_fetch_or_explicit(atomic<T>*, atomic<T>::value_type,
367 memory_order) noexcept;
368template<class T>
369 T atomic_fetch_xor(volatile atomic<T>*, atomic<T>::value_type) noexcept;
370template<class T>
371 T atomic_fetch_xor(atomic<T>*, atomic<T>::value_type) noexcept;
372template<class T>
373 T atomic_fetch_xor_explicit(volatile atomic<T>*, atomic<T>::value_type,
374 memory_order) noexcept;
375template<class T>
376 T atomic_fetch_xor_explicit(atomic<T>*, atomic<T>::value_type,
377 memory_order) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000378
Mark de Wever7d5df422021-06-06 14:48:08 +0200379template<class T>
380 void atomic_wait(const volatile atomic<T>*, atomic<T>::value_type);
381template<class T>
382 void atomic_wait(const atomic<T>*, atomic<T>::value_type);
383template<class T>
384 void atomic_wait_explicit(const volatile atomic<T>*, atomic<T>::value_type,
385 memory_order);
386template<class T>
387 void atomic_wait_explicit(const atomic<T>*, atomic<T>::value_type,
388 memory_order);
389template<class T>
390 void atomic_notify_one(volatile atomic<T>*);
391template<class T>
392 void atomic_notify_one(atomic<T>*);
393template<class T>
394 void atomic_notify_all(volatile atomic<T>*);
395template<class T>
396 void atomic_notify_all(atomic<T>*);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000397
398// Atomics for standard typedef types
399
Howard Hinnantf0af8d92013-01-04 18:58:50 +0000400typedef atomic<bool> atomic_bool;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000401typedef atomic<char> atomic_char;
402typedef atomic<signed char> atomic_schar;
403typedef atomic<unsigned char> atomic_uchar;
404typedef atomic<short> atomic_short;
405typedef atomic<unsigned short> atomic_ushort;
406typedef atomic<int> atomic_int;
407typedef atomic<unsigned int> atomic_uint;
408typedef atomic<long> atomic_long;
409typedef atomic<unsigned long> atomic_ulong;
410typedef atomic<long long> atomic_llong;
411typedef atomic<unsigned long long> atomic_ullong;
Marek Kurdej91bebaa2020-11-24 21:07:06 +0100412typedef atomic<char8_t> atomic_char8_t; // C++20
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000413typedef atomic<char16_t> atomic_char16_t;
414typedef atomic<char32_t> atomic_char32_t;
415typedef atomic<wchar_t> atomic_wchar_t;
416
417typedef atomic<int_least8_t> atomic_int_least8_t;
418typedef atomic<uint_least8_t> atomic_uint_least8_t;
419typedef atomic<int_least16_t> atomic_int_least16_t;
420typedef atomic<uint_least16_t> atomic_uint_least16_t;
421typedef atomic<int_least32_t> atomic_int_least32_t;
422typedef atomic<uint_least32_t> atomic_uint_least32_t;
423typedef atomic<int_least64_t> atomic_int_least64_t;
424typedef atomic<uint_least64_t> atomic_uint_least64_t;
425
426typedef atomic<int_fast8_t> atomic_int_fast8_t;
427typedef atomic<uint_fast8_t> atomic_uint_fast8_t;
428typedef atomic<int_fast16_t> atomic_int_fast16_t;
429typedef atomic<uint_fast16_t> atomic_uint_fast16_t;
Louis Dionneb39adc52020-11-04 14:07:59 -0500430typedef atomic<int_fast32_t> atomic_int_fast32_t;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000431typedef atomic<uint_fast32_t> atomic_uint_fast32_t;
432typedef atomic<int_fast64_t> atomic_int_fast64_t;
433typedef atomic<uint_fast64_t> atomic_uint_fast64_t;
434
Marshall Clowf710afc2016-06-30 15:28:38 +0000435typedef atomic<int8_t> atomic_int8_t;
436typedef atomic<uint8_t> atomic_uint8_t;
437typedef atomic<int16_t> atomic_int16_t;
438typedef atomic<uint16_t> atomic_uint16_t;
439typedef atomic<int32_t> atomic_int32_t;
440typedef atomic<uint32_t> atomic_uint32_t;
441typedef atomic<int64_t> atomic_int64_t;
442typedef atomic<uint64_t> atomic_uint64_t;
443
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000444typedef atomic<intptr_t> atomic_intptr_t;
445typedef atomic<uintptr_t> atomic_uintptr_t;
446typedef atomic<size_t> atomic_size_t;
447typedef atomic<ptrdiff_t> atomic_ptrdiff_t;
448typedef atomic<intmax_t> atomic_intmax_t;
449typedef atomic<uintmax_t> atomic_uintmax_t;
450
Olivier Giroux6031a712020-06-01 14:30:13 -0700451// flag type and operations
452
453typedef struct atomic_flag
454{
Raul Tambre4e0e88f2021-06-06 19:02:20 +0300455 atomic_flag() noexcept = default; // until C++20
456 constexpr atomic_flag() noexcept; // since C++20
Olivier Giroux6031a712020-06-01 14:30:13 -0700457 atomic_flag(const atomic_flag&) = delete;
458 atomic_flag& operator=(const atomic_flag&) = delete;
459 atomic_flag& operator=(const atomic_flag&) volatile = delete;
460
461 bool test(memory_order m = memory_order_seq_cst) volatile noexcept;
462 bool test(memory_order m = memory_order_seq_cst) noexcept;
463 bool test_and_set(memory_order m = memory_order_seq_cst) volatile noexcept;
464 bool test_and_set(memory_order m = memory_order_seq_cst) noexcept;
465 void clear(memory_order m = memory_order_seq_cst) volatile noexcept;
466 void clear(memory_order m = memory_order_seq_cst) noexcept;
467
468 void wait(bool, memory_order = memory_order::seq_cst) const volatile noexcept;
469 void wait(bool, memory_order = memory_order::seq_cst) const noexcept;
470 void notify_one() volatile noexcept;
471 void notify_one() noexcept;
472 void notify_all() volatile noexcept;
473 void notify_all() noexcept;
474} atomic_flag;
475
476bool atomic_flag_test(volatile atomic_flag* obj) noexcept;
477bool atomic_flag_test(atomic_flag* obj) noexcept;
478bool atomic_flag_test_explicit(volatile atomic_flag* obj,
479 memory_order m) noexcept;
480bool atomic_flag_test_explicit(atomic_flag* obj, memory_order m) noexcept;
481bool atomic_flag_test_and_set(volatile atomic_flag* obj) noexcept;
482bool atomic_flag_test_and_set(atomic_flag* obj) noexcept;
483bool atomic_flag_test_and_set_explicit(volatile atomic_flag* obj,
484 memory_order m) noexcept;
485bool atomic_flag_test_and_set_explicit(atomic_flag* obj, memory_order m) noexcept;
486void atomic_flag_clear(volatile atomic_flag* obj) noexcept;
487void atomic_flag_clear(atomic_flag* obj) noexcept;
488void atomic_flag_clear_explicit(volatile atomic_flag* obj, memory_order m) noexcept;
489void atomic_flag_clear_explicit(atomic_flag* obj, memory_order m) noexcept;
490
491void atomic_wait(const volatile atomic_flag* obj, T old) noexcept;
492void atomic_wait(const atomic_flag* obj, T old) noexcept;
493void atomic_wait_explicit(const volatile atomic_flag* obj, T old, memory_order m) noexcept;
494void atomic_wait_explicit(const atomic_flag* obj, T old, memory_order m) noexcept;
495void atomic_one(volatile atomic_flag* obj) noexcept;
496void atomic_one(atomic_flag* obj) noexcept;
497void atomic_all(volatile atomic_flag* obj) noexcept;
498void atomic_all(atomic_flag* obj) noexcept;
499
Howard Hinnant71be7292010-09-27 21:17:38 +0000500// fences
501
Howard Hinnanteee2c142012-04-11 20:14:21 +0000502void atomic_thread_fence(memory_order m) noexcept;
503void atomic_signal_fence(memory_order m) noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +0000504
Olivier Giroux6031a712020-06-01 14:30:13 -0700505// deprecated
506
507template <class T>
Mark de Wever7d5df422021-06-06 14:48:08 +0200508 void atomic_init(volatile atomic<T>* obj, atomic<T>::value_type desr) noexcept;
Olivier Giroux6031a712020-06-01 14:30:13 -0700509
510template <class T>
Mark de Wever7d5df422021-06-06 14:48:08 +0200511 void atomic_init(atomic<T>* obj, atomic<T>::value_type desr) noexcept;
Olivier Giroux6031a712020-06-01 14:30:13 -0700512
513#define ATOMIC_VAR_INIT(value) see below
514
515#define ATOMIC_FLAG_INIT see below
516
Howard Hinnant71be7292010-09-27 21:17:38 +0000517} // std
518
519*/
520
Louis Dionne73912b22020-11-04 15:01:25 -0500521#include <__availability>
Arthur O'Dwyeref181602021-05-19 11:57:04 -0400522#include <__config>
Louis Dionneaf2d2a82021-11-17 10:59:31 -0500523#include <__thread/poll_with_backoff.h>
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000524#include <cstddef>
525#include <cstdint>
Olivier Giroux161e6e82020-02-18 09:58:34 -0500526#include <cstring>
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000527#include <type_traits>
Marshall Clow0a1e7502018-09-12 19:41:40 +0000528#include <version>
Howard Hinnant71be7292010-09-27 21:17:38 +0000529
Louis Dionneaf2d2a82021-11-17 10:59:31 -0500530#ifndef _LIBCPP_HAS_NO_THREADS
531# include <__threading_support>
532#endif
533
Howard Hinnantaaaa52b2011-10-17 20:05:10 +0000534#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
Howard Hinnant71be7292010-09-27 21:17:38 +0000535#pragma GCC system_header
Howard Hinnantaaaa52b2011-10-17 20:05:10 +0000536#endif
Howard Hinnant71be7292010-09-27 21:17:38 +0000537
Davide Italiano011f80a2019-03-05 18:40:49 +0000538#ifdef _LIBCPP_HAS_NO_ATOMIC_HEADER
539# error <atomic> is not implemented
Eric Fiselier8020b6c2015-08-19 17:21:46 +0000540#endif
Volodymyr Sapsaif3ed1fd2018-05-15 22:38:31 +0000541#ifdef kill_dependency
Davide Italiano011f80a2019-03-05 18:40:49 +0000542# error C++ standard library is incompatible with <stdatomic.h>
Volodymyr Sapsaif3ed1fd2018-05-15 22:38:31 +0000543#endif
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000544
Eric Fiselierb5ab51d2017-01-13 23:45:39 +0000545#define _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) \
546 _LIBCPP_DIAGNOSE_WARNING(__m == memory_order_consume || \
547 __m == memory_order_acquire || \
548 __m == memory_order_acq_rel, \
549 "memory order argument to atomic operation is invalid")
550
551#define _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) \
552 _LIBCPP_DIAGNOSE_WARNING(__m == memory_order_release || \
553 __m == memory_order_acq_rel, \
554 "memory order argument to atomic operation is invalid")
555
556#define _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__m, __f) \
557 _LIBCPP_DIAGNOSE_WARNING(__f == memory_order_release || \
558 __f == memory_order_acq_rel, \
559 "memory order argument to atomic operation is invalid")
560
Howard Hinnant71be7292010-09-27 21:17:38 +0000561_LIBCPP_BEGIN_NAMESPACE_STD
562
Eric Fiselierd4e3e5b2019-03-08 23:15:54 +0000563// Figure out what the underlying type for `memory_order` would be if it were
564// declared as an unscoped enum (accounting for -fshort-enums). Use this result
565// to pin the underlying type in C++20.
566enum __legacy_memory_order {
567 __mo_relaxed,
568 __mo_consume,
569 __mo_acquire,
570 __mo_release,
571 __mo_acq_rel,
572 __mo_seq_cst
573};
574
575typedef underlying_type<__legacy_memory_order>::type __memory_order_underlying_t;
576
Davide Italiano011f80a2019-03-05 18:40:49 +0000577#if _LIBCPP_STD_VER > 17
578
Eric Fiselierd4e3e5b2019-03-08 23:15:54 +0000579enum class memory_order : __memory_order_underlying_t {
580 relaxed = __mo_relaxed,
581 consume = __mo_consume,
582 acquire = __mo_acquire,
583 release = __mo_release,
584 acq_rel = __mo_acq_rel,
585 seq_cst = __mo_seq_cst
Davide Italiano011f80a2019-03-05 18:40:49 +0000586};
587
588inline constexpr auto memory_order_relaxed = memory_order::relaxed;
589inline constexpr auto memory_order_consume = memory_order::consume;
590inline constexpr auto memory_order_acquire = memory_order::acquire;
591inline constexpr auto memory_order_release = memory_order::release;
592inline constexpr auto memory_order_acq_rel = memory_order::acq_rel;
593inline constexpr auto memory_order_seq_cst = memory_order::seq_cst;
594
Davide Italiano011f80a2019-03-05 18:40:49 +0000595#else
596
597typedef enum memory_order {
Eric Fiselierd4e3e5b2019-03-08 23:15:54 +0000598 memory_order_relaxed = __mo_relaxed,
599 memory_order_consume = __mo_consume,
600 memory_order_acquire = __mo_acquire,
601 memory_order_release = __mo_release,
602 memory_order_acq_rel = __mo_acq_rel,
603 memory_order_seq_cst = __mo_seq_cst,
Howard Hinnantdca6e712010-09-28 17:13:38 +0000604} memory_order;
605
Davide Italiano011f80a2019-03-05 18:40:49 +0000606#endif // _LIBCPP_STD_VER > 17
607
Olivier Giroux161e6e82020-02-18 09:58:34 -0500608template <typename _Tp> _LIBCPP_INLINE_VISIBILITY
609bool __cxx_nonatomic_compare_equal(_Tp const& __lhs, _Tp const& __rhs) {
Arthur O'Dwyer22236632020-12-07 21:50:15 -0500610 return _VSTD::memcmp(&__lhs, &__rhs, sizeof(_Tp)) == 0;
Olivier Giroux161e6e82020-02-18 09:58:34 -0500611}
612
Eric Fiselier51525172019-03-08 23:30:26 +0000613static_assert((is_same<underlying_type<memory_order>::type, __memory_order_underlying_t>::value),
Eric Fiselierd4e3e5b2019-03-08 23:15:54 +0000614 "unexpected underlying type for std::memory_order");
Davide Italiano011f80a2019-03-05 18:40:49 +0000615
616#if defined(_LIBCPP_HAS_GCC_ATOMIC_IMP) || \
Arthur O'Dwyer2fc9b5d2021-04-17 17:03:20 -0400617 defined(_LIBCPP_ATOMIC_ONLY_USE_BUILTINS)
Davide Italiano011f80a2019-03-05 18:40:49 +0000618
619// [atomics.types.generic]p1 guarantees _Tp is trivially copyable. Because
620// the default operator= in an object is not volatile, a byte-by-byte copy
621// is required.
622template <typename _Tp, typename _Tv> _LIBCPP_INLINE_VISIBILITY
623typename enable_if<is_assignable<_Tp&, _Tv>::value>::type
624__cxx_atomic_assign_volatile(_Tp& __a_value, _Tv const& __val) {
625 __a_value = __val;
626}
627template <typename _Tp, typename _Tv> _LIBCPP_INLINE_VISIBILITY
628typename enable_if<is_assignable<_Tp&, _Tv>::value>::type
629__cxx_atomic_assign_volatile(_Tp volatile& __a_value, _Tv volatile const& __val) {
630 volatile char* __to = reinterpret_cast<volatile char*>(&__a_value);
631 volatile char* __end = __to + sizeof(_Tp);
632 volatile const char* __from = reinterpret_cast<volatile const char*>(&__val);
633 while (__to != __end)
634 *__to++ = *__from++;
635}
636
Davide Italiano31f218a2019-03-05 17:38:33 +0000637#endif
Louis Dionnea1ae0032019-03-04 15:26:27 +0000638
Davide Italiano011f80a2019-03-05 18:40:49 +0000639#if defined(_LIBCPP_HAS_GCC_ATOMIC_IMP)
640
641template <typename _Tp>
642struct __cxx_atomic_base_impl {
643
Eric Fiselier684aaca2015-10-14 08:36:22 +0000644 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier07b2b552016-11-18 06:42:17 +0000645#ifndef _LIBCPP_CXX03_LANG
Davide Italiano011f80a2019-03-05 18:40:49 +0000646 __cxx_atomic_base_impl() _NOEXCEPT = default;
Eric Fiselier684aaca2015-10-14 08:36:22 +0000647#else
Davide Italiano011f80a2019-03-05 18:40:49 +0000648 __cxx_atomic_base_impl() _NOEXCEPT : __a_value() {}
Eric Fiselier07b2b552016-11-18 06:42:17 +0000649#endif // _LIBCPP_CXX03_LANG
Davide Italiano011f80a2019-03-05 18:40:49 +0000650 _LIBCPP_CONSTEXPR explicit __cxx_atomic_base_impl(_Tp value) _NOEXCEPT
Eric Fiselier719e0442015-07-14 17:50:27 +0000651 : __a_value(value) {}
Marshall Clow290eb3f2015-01-11 06:15:59 +0000652 _Tp __a_value;
Dan Albert7b65ace2014-08-09 23:51:51 +0000653};
Dan Albert7b65ace2014-08-09 23:51:51 +0000654
Davide Italiano011f80a2019-03-05 18:40:49 +0000655_LIBCPP_INLINE_VISIBILITY inline _LIBCPP_CONSTEXPR int __to_gcc_order(memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000656 // Avoid switch statement to make this a constexpr.
657 return __order == memory_order_relaxed ? __ATOMIC_RELAXED:
658 (__order == memory_order_acquire ? __ATOMIC_ACQUIRE:
659 (__order == memory_order_release ? __ATOMIC_RELEASE:
660 (__order == memory_order_seq_cst ? __ATOMIC_SEQ_CST:
661 (__order == memory_order_acq_rel ? __ATOMIC_ACQ_REL:
662 __ATOMIC_CONSUME))));
663}
664
Davide Italiano011f80a2019-03-05 18:40:49 +0000665_LIBCPP_INLINE_VISIBILITY inline _LIBCPP_CONSTEXPR int __to_gcc_failure_order(memory_order __order) {
Dan Albert48815f22015-01-06 18:39:37 +0000666 // Avoid switch statement to make this a constexpr.
667 return __order == memory_order_relaxed ? __ATOMIC_RELAXED:
668 (__order == memory_order_acquire ? __ATOMIC_ACQUIRE:
669 (__order == memory_order_release ? __ATOMIC_RELAXED:
670 (__order == memory_order_seq_cst ? __ATOMIC_SEQ_CST:
671 (__order == memory_order_acq_rel ? __ATOMIC_ACQUIRE:
672 __ATOMIC_CONSUME))));
673}
674
Davide Italiano011f80a2019-03-05 18:40:49 +0000675template <typename _Tp>
676_LIBCPP_INLINE_VISIBILITY
677void __cxx_atomic_init(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __val) {
678 __cxx_atomic_assign_volatile(__a->__a_value, __val);
679}
Dan Albert7b65ace2014-08-09 23:51:51 +0000680
681template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000682_LIBCPP_INLINE_VISIBILITY
683void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp>* __a, _Tp __val) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000684 __a->__a_value = __val;
685}
686
Davide Italiano011f80a2019-03-05 18:40:49 +0000687_LIBCPP_INLINE_VISIBILITY inline
688void __cxx_atomic_thread_fence(memory_order __order) {
689 __atomic_thread_fence(__to_gcc_order(__order));
690}
691
692_LIBCPP_INLINE_VISIBILITY inline
693void __cxx_atomic_signal_fence(memory_order __order) {
694 __atomic_signal_fence(__to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000695}
696
697template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000698_LIBCPP_INLINE_VISIBILITY
699void __cxx_atomic_store(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __val,
700 memory_order __order) {
Dan Albert48815f22015-01-06 18:39:37 +0000701 __atomic_store(&__a->__a_value, &__val,
Davide Italiano011f80a2019-03-05 18:40:49 +0000702 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000703}
704
705template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000706_LIBCPP_INLINE_VISIBILITY
707void __cxx_atomic_store(__cxx_atomic_base_impl<_Tp>* __a, _Tp __val,
708 memory_order __order) {
709 __atomic_store(&__a->__a_value, &__val,
710 __to_gcc_order(__order));
711}
712
713template <typename _Tp>
714_LIBCPP_INLINE_VISIBILITY
715_Tp __cxx_atomic_load(const volatile __cxx_atomic_base_impl<_Tp>* __a,
716 memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000717 _Tp __ret;
718 __atomic_load(&__a->__a_value, &__ret,
Davide Italiano011f80a2019-03-05 18:40:49 +0000719 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000720 return __ret;
721}
722
723template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000724_LIBCPP_INLINE_VISIBILITY
725_Tp __cxx_atomic_load(const __cxx_atomic_base_impl<_Tp>* __a, memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000726 _Tp __ret;
727 __atomic_load(&__a->__a_value, &__ret,
Davide Italiano011f80a2019-03-05 18:40:49 +0000728 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000729 return __ret;
730}
731
732template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000733_LIBCPP_INLINE_VISIBILITY
734_Tp __cxx_atomic_exchange(volatile __cxx_atomic_base_impl<_Tp>* __a,
735 _Tp __value, memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000736 _Tp __ret;
737 __atomic_exchange(&__a->__a_value, &__value, &__ret,
Davide Italiano011f80a2019-03-05 18:40:49 +0000738 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000739 return __ret;
740}
741
742template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000743_LIBCPP_INLINE_VISIBILITY
744_Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp>* __a, _Tp __value,
745 memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000746 _Tp __ret;
747 __atomic_exchange(&__a->__a_value, &__value, &__ret,
Davide Italiano011f80a2019-03-05 18:40:49 +0000748 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000749 return __ret;
750}
751
752template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000753_LIBCPP_INLINE_VISIBILITY
754bool __cxx_atomic_compare_exchange_strong(
755 volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value,
JF Bastien6e412d92018-05-26 19:44:45 +0000756 memory_order __success, memory_order __failure) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000757 return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
758 false,
Davide Italiano011f80a2019-03-05 18:40:49 +0000759 __to_gcc_order(__success),
760 __to_gcc_failure_order(__failure));
Dan Albert7b65ace2014-08-09 23:51:51 +0000761}
762
763template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000764_LIBCPP_INLINE_VISIBILITY
765bool __cxx_atomic_compare_exchange_strong(
766 __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success,
JF Bastien6e412d92018-05-26 19:44:45 +0000767 memory_order __failure) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000768 return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
769 false,
Davide Italiano011f80a2019-03-05 18:40:49 +0000770 __to_gcc_order(__success),
771 __to_gcc_failure_order(__failure));
Dan Albert7b65ace2014-08-09 23:51:51 +0000772}
773
774template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000775_LIBCPP_INLINE_VISIBILITY
776bool __cxx_atomic_compare_exchange_weak(
777 volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value,
JF Bastien6e412d92018-05-26 19:44:45 +0000778 memory_order __success, memory_order __failure) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000779 return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
780 true,
Davide Italiano011f80a2019-03-05 18:40:49 +0000781 __to_gcc_order(__success),
782 __to_gcc_failure_order(__failure));
Dan Albert7b65ace2014-08-09 23:51:51 +0000783}
784
785template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000786_LIBCPP_INLINE_VISIBILITY
787bool __cxx_atomic_compare_exchange_weak(
788 __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success,
JF Bastien6e412d92018-05-26 19:44:45 +0000789 memory_order __failure) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000790 return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
791 true,
Davide Italiano011f80a2019-03-05 18:40:49 +0000792 __to_gcc_order(__success),
793 __to_gcc_failure_order(__failure));
Dan Albert7b65ace2014-08-09 23:51:51 +0000794}
795
796template <typename _Tp>
797struct __skip_amt { enum {value = 1}; };
798
799template <typename _Tp>
800struct __skip_amt<_Tp*> { enum {value = sizeof(_Tp)}; };
801
802// FIXME: Haven't figured out what the spec says about using arrays with
803// atomic_fetch_add. Force a failure rather than creating bad behavior.
804template <typename _Tp>
805struct __skip_amt<_Tp[]> { };
806template <typename _Tp, int n>
807struct __skip_amt<_Tp[n]> { };
808
809template <typename _Tp, typename _Td>
Davide Italiano011f80a2019-03-05 18:40:49 +0000810_LIBCPP_INLINE_VISIBILITY
811_Tp __cxx_atomic_fetch_add(volatile __cxx_atomic_base_impl<_Tp>* __a,
812 _Td __delta, memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000813 return __atomic_fetch_add(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
Davide Italiano011f80a2019-03-05 18:40:49 +0000814 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000815}
816
817template <typename _Tp, typename _Td>
Davide Italiano011f80a2019-03-05 18:40:49 +0000818_LIBCPP_INLINE_VISIBILITY
819_Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp>* __a, _Td __delta,
820 memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000821 return __atomic_fetch_add(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
Davide Italiano011f80a2019-03-05 18:40:49 +0000822 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000823}
824
825template <typename _Tp, typename _Td>
Davide Italiano011f80a2019-03-05 18:40:49 +0000826_LIBCPP_INLINE_VISIBILITY
827_Tp __cxx_atomic_fetch_sub(volatile __cxx_atomic_base_impl<_Tp>* __a,
828 _Td __delta, memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000829 return __atomic_fetch_sub(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
Davide Italiano011f80a2019-03-05 18:40:49 +0000830 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000831}
832
833template <typename _Tp, typename _Td>
Davide Italiano011f80a2019-03-05 18:40:49 +0000834_LIBCPP_INLINE_VISIBILITY
835_Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp>* __a, _Td __delta,
836 memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000837 return __atomic_fetch_sub(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
Davide Italiano011f80a2019-03-05 18:40:49 +0000838 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000839}
840
841template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000842_LIBCPP_INLINE_VISIBILITY
843_Tp __cxx_atomic_fetch_and(volatile __cxx_atomic_base_impl<_Tp>* __a,
844 _Tp __pattern, memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000845 return __atomic_fetch_and(&__a->__a_value, __pattern,
Davide Italiano011f80a2019-03-05 18:40:49 +0000846 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000847}
848
849template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000850_LIBCPP_INLINE_VISIBILITY
851_Tp __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp>* __a,
852 _Tp __pattern, memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000853 return __atomic_fetch_and(&__a->__a_value, __pattern,
Davide Italiano011f80a2019-03-05 18:40:49 +0000854 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000855}
856
857template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000858_LIBCPP_INLINE_VISIBILITY
859_Tp __cxx_atomic_fetch_or(volatile __cxx_atomic_base_impl<_Tp>* __a,
860 _Tp __pattern, memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000861 return __atomic_fetch_or(&__a->__a_value, __pattern,
Davide Italiano011f80a2019-03-05 18:40:49 +0000862 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000863}
864
865template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000866_LIBCPP_INLINE_VISIBILITY
867_Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern,
868 memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000869 return __atomic_fetch_or(&__a->__a_value, __pattern,
Davide Italiano011f80a2019-03-05 18:40:49 +0000870 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000871}
872
873template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000874_LIBCPP_INLINE_VISIBILITY
875_Tp __cxx_atomic_fetch_xor(volatile __cxx_atomic_base_impl<_Tp>* __a,
876 _Tp __pattern, memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000877 return __atomic_fetch_xor(&__a->__a_value, __pattern,
Davide Italiano011f80a2019-03-05 18:40:49 +0000878 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000879}
880
881template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000882_LIBCPP_INLINE_VISIBILITY
883_Tp __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern,
884 memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000885 return __atomic_fetch_xor(&__a->__a_value, __pattern,
Davide Italiano011f80a2019-03-05 18:40:49 +0000886 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000887}
Davide Italiano011f80a2019-03-05 18:40:49 +0000888
889#define __cxx_atomic_is_lock_free(__s) __atomic_is_lock_free(__s, 0)
890
891#elif defined(_LIBCPP_HAS_C_ATOMIC_IMP)
892
893template <typename _Tp>
894struct __cxx_atomic_base_impl {
895
896 _LIBCPP_INLINE_VISIBILITY
897#ifndef _LIBCPP_CXX03_LANG
898 __cxx_atomic_base_impl() _NOEXCEPT = default;
899#else
900 __cxx_atomic_base_impl() _NOEXCEPT : __a_value() {}
901#endif // _LIBCPP_CXX03_LANG
902 _LIBCPP_CONSTEXPR explicit __cxx_atomic_base_impl(_Tp value) _NOEXCEPT
903 : __a_value(value) {}
Louis Dionnefaa17452019-09-04 12:44:19 +0000904 _LIBCPP_DISABLE_EXTENSION_WARNING _Atomic(_Tp) __a_value;
Davide Italiano011f80a2019-03-05 18:40:49 +0000905};
906
907#define __cxx_atomic_is_lock_free(__s) __c11_atomic_is_lock_free(__s)
908
909_LIBCPP_INLINE_VISIBILITY inline
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000910void __cxx_atomic_thread_fence(memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +0000911 __c11_atomic_thread_fence(static_cast<__memory_order_underlying_t>(__order));
912}
913
914_LIBCPP_INLINE_VISIBILITY inline
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000915void __cxx_atomic_signal_fence(memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +0000916 __c11_atomic_signal_fence(static_cast<__memory_order_underlying_t>(__order));
917}
918
919template<class _Tp>
920_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000921void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __val) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +0000922 __c11_atomic_init(&__a->__a_value, __val);
923}
924template<class _Tp>
925_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000926void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp> * __a, _Tp __val) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +0000927 __c11_atomic_init(&__a->__a_value, __val);
928}
929
930template<class _Tp>
931_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000932void __cxx_atomic_store(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __val, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +0000933 __c11_atomic_store(&__a->__a_value, __val, static_cast<__memory_order_underlying_t>(__order));
934}
935template<class _Tp>
936_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000937void __cxx_atomic_store(__cxx_atomic_base_impl<_Tp> * __a, _Tp __val, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +0000938 __c11_atomic_store(&__a->__a_value, __val, static_cast<__memory_order_underlying_t>(__order));
939}
940
941template<class _Tp>
942_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000943_Tp __cxx_atomic_load(__cxx_atomic_base_impl<_Tp> const volatile* __a, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +0000944 using __ptr_type = typename remove_const<decltype(__a->__a_value)>::type*;
945 return __c11_atomic_load(const_cast<__ptr_type>(&__a->__a_value), static_cast<__memory_order_underlying_t>(__order));
946}
947template<class _Tp>
948_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000949_Tp __cxx_atomic_load(__cxx_atomic_base_impl<_Tp> const* __a, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +0000950 using __ptr_type = typename remove_const<decltype(__a->__a_value)>::type*;
951 return __c11_atomic_load(const_cast<__ptr_type>(&__a->__a_value), static_cast<__memory_order_underlying_t>(__order));
952}
953
954template<class _Tp>
955_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000956_Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __value, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +0000957 return __c11_atomic_exchange(&__a->__a_value, __value, static_cast<__memory_order_underlying_t>(__order));
958}
959template<class _Tp>
960_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000961_Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp> * __a, _Tp __value, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +0000962 return __c11_atomic_exchange(&__a->__a_value, __value, static_cast<__memory_order_underlying_t>(__order));
963}
964
Jordan Rupprechtd2e31a82021-06-15 07:55:23 -0700965_LIBCPP_INLINE_VISIBILITY inline _LIBCPP_CONSTEXPR memory_order __to_failure_order(memory_order __order) {
966 // Avoid switch statement to make this a constexpr.
967 return __order == memory_order_release ? memory_order_relaxed:
968 (__order == memory_order_acq_rel ? memory_order_acquire:
969 __order);
970}
971
Davide Italiano011f80a2019-03-05 18:40:49 +0000972template<class _Tp>
973_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000974bool __cxx_atomic_compare_exchange_strong(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT {
Jordan Rupprechtd2e31a82021-06-15 07:55:23 -0700975 return __c11_atomic_compare_exchange_strong(&__a->__a_value, __expected, __value, static_cast<__memory_order_underlying_t>(__success), static_cast<__memory_order_underlying_t>(__to_failure_order(__failure)));
Davide Italiano011f80a2019-03-05 18:40:49 +0000976}
977template<class _Tp>
978_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000979bool __cxx_atomic_compare_exchange_strong(__cxx_atomic_base_impl<_Tp> * __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT {
Jordan Rupprechtd2e31a82021-06-15 07:55:23 -0700980 return __c11_atomic_compare_exchange_strong(&__a->__a_value, __expected, __value, static_cast<__memory_order_underlying_t>(__success), static_cast<__memory_order_underlying_t>(__to_failure_order(__failure)));
Davide Italiano011f80a2019-03-05 18:40:49 +0000981}
982
983template<class _Tp>
984_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000985bool __cxx_atomic_compare_exchange_weak(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT {
Jordan Rupprechtd2e31a82021-06-15 07:55:23 -0700986 return __c11_atomic_compare_exchange_weak(&__a->__a_value, __expected, __value, static_cast<__memory_order_underlying_t>(__success), static_cast<__memory_order_underlying_t>(__to_failure_order(__failure)));
Davide Italiano011f80a2019-03-05 18:40:49 +0000987}
988template<class _Tp>
989_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000990bool __cxx_atomic_compare_exchange_weak(__cxx_atomic_base_impl<_Tp> * __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT {
Jordan Rupprechtd2e31a82021-06-15 07:55:23 -0700991 return __c11_atomic_compare_exchange_weak(&__a->__a_value, __expected, __value, static_cast<__memory_order_underlying_t>(__success), static_cast<__memory_order_underlying_t>(__to_failure_order(__failure)));
Davide Italiano011f80a2019-03-05 18:40:49 +0000992}
993
994template<class _Tp>
995_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000996_Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __delta, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +0000997 return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
998}
999template<class _Tp>
1000_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001001_Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp> * __a, _Tp __delta, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +00001002 return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
1003}
1004
1005template<class _Tp>
1006_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001007_Tp* __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp*> volatile* __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +00001008 return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
1009}
1010template<class _Tp>
1011_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001012_Tp* __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp*> * __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +00001013 return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
1014}
1015
1016template<class _Tp>
1017_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001018_Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __delta, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +00001019 return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
1020}
1021template<class _Tp>
1022_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001023_Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp> * __a, _Tp __delta, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +00001024 return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
1025}
1026template<class _Tp>
1027_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001028_Tp* __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp*> volatile* __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +00001029 return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
1030}
1031template<class _Tp>
1032_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001033_Tp* __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp*> * __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +00001034 return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
1035}
1036
1037template<class _Tp>
1038_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001039_Tp __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +00001040 return __c11_atomic_fetch_and(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
1041}
1042template<class _Tp>
1043_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001044_Tp __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +00001045 return __c11_atomic_fetch_and(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
1046}
1047
1048template<class _Tp>
1049_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001050_Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +00001051 return __c11_atomic_fetch_or(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
1052}
1053template<class _Tp>
1054_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001055_Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +00001056 return __c11_atomic_fetch_or(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
1057}
1058
1059template<class _Tp>
1060_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001061_Tp __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +00001062 return __c11_atomic_fetch_xor(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
1063}
1064template<class _Tp>
1065_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001066_Tp __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +00001067 return __c11_atomic_fetch_xor(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
1068}
1069
1070#endif // _LIBCPP_HAS_GCC_ATOMIC_IMP, _LIBCPP_HAS_C_ATOMIC_IMP
Dan Albert7b65ace2014-08-09 23:51:51 +00001071
Howard Hinnantdca6e712010-09-28 17:13:38 +00001072template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001073_LIBCPP_INLINE_VISIBILITY
1074_Tp kill_dependency(_Tp __y) _NOEXCEPT
Howard Hinnantdca6e712010-09-28 17:13:38 +00001075{
1076 return __y;
1077}
Howard Hinnant71be7292010-09-27 21:17:38 +00001078
Eric Fiselierbed42df2017-04-20 23:22:46 +00001079#if defined(__CLANG_ATOMIC_BOOL_LOCK_FREE)
1080# define ATOMIC_BOOL_LOCK_FREE __CLANG_ATOMIC_BOOL_LOCK_FREE
1081# define ATOMIC_CHAR_LOCK_FREE __CLANG_ATOMIC_CHAR_LOCK_FREE
Arthur O'Dwyerafa5d5f2021-04-18 21:47:08 -04001082#ifndef _LIBCPP_HAS_NO_CHAR8_T
Marek Kurdej91bebaa2020-11-24 21:07:06 +01001083# define ATOMIC_CHAR8_T_LOCK_FREE __CLANG_ATOMIC_CHAR8_T_LOCK_FREE
1084#endif
Eric Fiselierbed42df2017-04-20 23:22:46 +00001085# define ATOMIC_CHAR16_T_LOCK_FREE __CLANG_ATOMIC_CHAR16_T_LOCK_FREE
1086# define ATOMIC_CHAR32_T_LOCK_FREE __CLANG_ATOMIC_CHAR32_T_LOCK_FREE
1087# define ATOMIC_WCHAR_T_LOCK_FREE __CLANG_ATOMIC_WCHAR_T_LOCK_FREE
1088# define ATOMIC_SHORT_LOCK_FREE __CLANG_ATOMIC_SHORT_LOCK_FREE
1089# define ATOMIC_INT_LOCK_FREE __CLANG_ATOMIC_INT_LOCK_FREE
1090# define ATOMIC_LONG_LOCK_FREE __CLANG_ATOMIC_LONG_LOCK_FREE
1091# define ATOMIC_LLONG_LOCK_FREE __CLANG_ATOMIC_LLONG_LOCK_FREE
1092# define ATOMIC_POINTER_LOCK_FREE __CLANG_ATOMIC_POINTER_LOCK_FREE
Davide Italiano011f80a2019-03-05 18:40:49 +00001093#elif defined(__GCC_ATOMIC_BOOL_LOCK_FREE)
Eric Fiselierbed42df2017-04-20 23:22:46 +00001094# define ATOMIC_BOOL_LOCK_FREE __GCC_ATOMIC_BOOL_LOCK_FREE
1095# define ATOMIC_CHAR_LOCK_FREE __GCC_ATOMIC_CHAR_LOCK_FREE
Arthur O'Dwyerafa5d5f2021-04-18 21:47:08 -04001096#ifndef _LIBCPP_HAS_NO_CHAR8_T
Marek Kurdej91bebaa2020-11-24 21:07:06 +01001097# define ATOMIC_CHAR8_T_LOCK_FREE __GCC_ATOMIC_CHAR8_T_LOCK_FREE
1098#endif
Eric Fiselierbed42df2017-04-20 23:22:46 +00001099# define ATOMIC_CHAR16_T_LOCK_FREE __GCC_ATOMIC_CHAR16_T_LOCK_FREE
1100# define ATOMIC_CHAR32_T_LOCK_FREE __GCC_ATOMIC_CHAR32_T_LOCK_FREE
1101# define ATOMIC_WCHAR_T_LOCK_FREE __GCC_ATOMIC_WCHAR_T_LOCK_FREE
1102# define ATOMIC_SHORT_LOCK_FREE __GCC_ATOMIC_SHORT_LOCK_FREE
1103# define ATOMIC_INT_LOCK_FREE __GCC_ATOMIC_INT_LOCK_FREE
1104# define ATOMIC_LONG_LOCK_FREE __GCC_ATOMIC_LONG_LOCK_FREE
1105# define ATOMIC_LLONG_LOCK_FREE __GCC_ATOMIC_LLONG_LOCK_FREE
1106# define ATOMIC_POINTER_LOCK_FREE __GCC_ATOMIC_POINTER_LOCK_FREE
1107#endif
JF Bastienfdb42c22016-03-25 15:48:21 +00001108
Davide Italiano011f80a2019-03-05 18:40:49 +00001109#ifdef _LIBCPP_ATOMIC_ONLY_USE_BUILTINS
1110
1111template<typename _Tp>
1112struct __cxx_atomic_lock_impl {
1113
1114 _LIBCPP_INLINE_VISIBILITY
1115 __cxx_atomic_lock_impl() _NOEXCEPT
1116 : __a_value(), __a_lock(0) {}
1117 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR explicit
1118 __cxx_atomic_lock_impl(_Tp value) _NOEXCEPT
1119 : __a_value(value), __a_lock(0) {}
1120
1121 _Tp __a_value;
1122 mutable __cxx_atomic_base_impl<_LIBCPP_ATOMIC_FLAG_TYPE> __a_lock;
1123
1124 _LIBCPP_INLINE_VISIBILITY void __lock() const volatile {
1125 while(1 == __cxx_atomic_exchange(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(true), memory_order_acquire))
1126 /*spin*/;
1127 }
1128 _LIBCPP_INLINE_VISIBILITY void __lock() const {
1129 while(1 == __cxx_atomic_exchange(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(true), memory_order_acquire))
1130 /*spin*/;
1131 }
1132 _LIBCPP_INLINE_VISIBILITY void __unlock() const volatile {
1133 __cxx_atomic_store(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(false), memory_order_release);
1134 }
1135 _LIBCPP_INLINE_VISIBILITY void __unlock() const {
1136 __cxx_atomic_store(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(false), memory_order_release);
1137 }
1138 _LIBCPP_INLINE_VISIBILITY _Tp __read() const volatile {
1139 __lock();
1140 _Tp __old;
1141 __cxx_atomic_assign_volatile(__old, __a_value);
1142 __unlock();
1143 return __old;
1144 }
1145 _LIBCPP_INLINE_VISIBILITY _Tp __read() const {
1146 __lock();
1147 _Tp __old = __a_value;
1148 __unlock();
1149 return __old;
1150 }
1151};
1152
1153template <typename _Tp>
1154_LIBCPP_INLINE_VISIBILITY
1155void __cxx_atomic_init(volatile __cxx_atomic_lock_impl<_Tp>* __a, _Tp __val) {
1156 __cxx_atomic_assign_volatile(__a->__a_value, __val);
1157}
1158template <typename _Tp>
1159_LIBCPP_INLINE_VISIBILITY
1160void __cxx_atomic_init(__cxx_atomic_lock_impl<_Tp>* __a, _Tp __val) {
1161 __a->__a_value = __val;
1162}
1163
1164template <typename _Tp>
1165_LIBCPP_INLINE_VISIBILITY
1166void __cxx_atomic_store(volatile __cxx_atomic_lock_impl<_Tp>* __a, _Tp __val, memory_order) {
1167 __a->__lock();
1168 __cxx_atomic_assign_volatile(__a->__a_value, __val);
1169 __a->__unlock();
1170}
1171template <typename _Tp>
1172_LIBCPP_INLINE_VISIBILITY
1173void __cxx_atomic_store(__cxx_atomic_lock_impl<_Tp>* __a, _Tp __val, memory_order) {
1174 __a->__lock();
1175 __a->__a_value = __val;
1176 __a->__unlock();
1177}
1178
1179template <typename _Tp>
1180_LIBCPP_INLINE_VISIBILITY
1181_Tp __cxx_atomic_load(const volatile __cxx_atomic_lock_impl<_Tp>* __a, memory_order) {
1182 return __a->__read();
1183}
1184template <typename _Tp>
1185_LIBCPP_INLINE_VISIBILITY
1186_Tp __cxx_atomic_load(const __cxx_atomic_lock_impl<_Tp>* __a, memory_order) {
1187 return __a->__read();
1188}
1189
1190template <typename _Tp>
1191_LIBCPP_INLINE_VISIBILITY
1192_Tp __cxx_atomic_exchange(volatile __cxx_atomic_lock_impl<_Tp>* __a, _Tp __value, memory_order) {
1193 __a->__lock();
1194 _Tp __old;
1195 __cxx_atomic_assign_volatile(__old, __a->__a_value);
1196 __cxx_atomic_assign_volatile(__a->__a_value, __value);
1197 __a->__unlock();
1198 return __old;
1199}
1200template <typename _Tp>
1201_LIBCPP_INLINE_VISIBILITY
1202_Tp __cxx_atomic_exchange(__cxx_atomic_lock_impl<_Tp>* __a, _Tp __value, memory_order) {
1203 __a->__lock();
1204 _Tp __old = __a->__a_value;
1205 __a->__a_value = __value;
1206 __a->__unlock();
1207 return __old;
1208}
1209
1210template <typename _Tp>
1211_LIBCPP_INLINE_VISIBILITY
1212bool __cxx_atomic_compare_exchange_strong(volatile __cxx_atomic_lock_impl<_Tp>* __a,
1213 _Tp* __expected, _Tp __value, memory_order, memory_order) {
Olivier Giroux161e6e82020-02-18 09:58:34 -05001214 _Tp __temp;
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07001215 __a->__lock();
Olivier Giroux161e6e82020-02-18 09:58:34 -05001216 __cxx_atomic_assign_volatile(__temp, __a->__a_value);
Arthur O'Dwyer22236632020-12-07 21:50:15 -05001217 bool __ret = (_VSTD::memcmp(&__temp, __expected, sizeof(_Tp)) == 0);
Davide Italiano011f80a2019-03-05 18:40:49 +00001218 if(__ret)
1219 __cxx_atomic_assign_volatile(__a->__a_value, __value);
1220 else
1221 __cxx_atomic_assign_volatile(*__expected, __a->__a_value);
1222 __a->__unlock();
1223 return __ret;
1224}
1225template <typename _Tp>
1226_LIBCPP_INLINE_VISIBILITY
1227bool __cxx_atomic_compare_exchange_strong(__cxx_atomic_lock_impl<_Tp>* __a,
1228 _Tp* __expected, _Tp __value, memory_order, memory_order) {
1229 __a->__lock();
Arthur O'Dwyer22236632020-12-07 21:50:15 -05001230 bool __ret = (_VSTD::memcmp(&__a->__a_value, __expected, sizeof(_Tp)) == 0);
Davide Italiano011f80a2019-03-05 18:40:49 +00001231 if(__ret)
Arthur O'Dwyer22236632020-12-07 21:50:15 -05001232 _VSTD::memcpy(&__a->__a_value, &__value, sizeof(_Tp));
Davide Italiano011f80a2019-03-05 18:40:49 +00001233 else
Arthur O'Dwyer22236632020-12-07 21:50:15 -05001234 _VSTD::memcpy(__expected, &__a->__a_value, sizeof(_Tp));
Davide Italiano011f80a2019-03-05 18:40:49 +00001235 __a->__unlock();
1236 return __ret;
1237}
1238
1239template <typename _Tp>
1240_LIBCPP_INLINE_VISIBILITY
1241bool __cxx_atomic_compare_exchange_weak(volatile __cxx_atomic_lock_impl<_Tp>* __a,
1242 _Tp* __expected, _Tp __value, memory_order, memory_order) {
Olivier Giroux161e6e82020-02-18 09:58:34 -05001243 _Tp __temp;
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07001244 __a->__lock();
Olivier Giroux161e6e82020-02-18 09:58:34 -05001245 __cxx_atomic_assign_volatile(__temp, __a->__a_value);
Arthur O'Dwyer22236632020-12-07 21:50:15 -05001246 bool __ret = (_VSTD::memcmp(&__temp, __expected, sizeof(_Tp)) == 0);
Davide Italiano011f80a2019-03-05 18:40:49 +00001247 if(__ret)
1248 __cxx_atomic_assign_volatile(__a->__a_value, __value);
1249 else
1250 __cxx_atomic_assign_volatile(*__expected, __a->__a_value);
1251 __a->__unlock();
1252 return __ret;
1253}
1254template <typename _Tp>
1255_LIBCPP_INLINE_VISIBILITY
1256bool __cxx_atomic_compare_exchange_weak(__cxx_atomic_lock_impl<_Tp>* __a,
1257 _Tp* __expected, _Tp __value, memory_order, memory_order) {
1258 __a->__lock();
Arthur O'Dwyer22236632020-12-07 21:50:15 -05001259 bool __ret = (_VSTD::memcmp(&__a->__a_value, __expected, sizeof(_Tp)) == 0);
Davide Italiano011f80a2019-03-05 18:40:49 +00001260 if(__ret)
Arthur O'Dwyer22236632020-12-07 21:50:15 -05001261 _VSTD::memcpy(&__a->__a_value, &__value, sizeof(_Tp));
Davide Italiano011f80a2019-03-05 18:40:49 +00001262 else
Arthur O'Dwyer22236632020-12-07 21:50:15 -05001263 _VSTD::memcpy(__expected, &__a->__a_value, sizeof(_Tp));
Davide Italiano011f80a2019-03-05 18:40:49 +00001264 __a->__unlock();
1265 return __ret;
1266}
1267
1268template <typename _Tp, typename _Td>
1269_LIBCPP_INLINE_VISIBILITY
1270_Tp __cxx_atomic_fetch_add(volatile __cxx_atomic_lock_impl<_Tp>* __a,
1271 _Td __delta, memory_order) {
1272 __a->__lock();
1273 _Tp __old;
1274 __cxx_atomic_assign_volatile(__old, __a->__a_value);
1275 __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old + __delta));
1276 __a->__unlock();
1277 return __old;
1278}
1279template <typename _Tp, typename _Td>
1280_LIBCPP_INLINE_VISIBILITY
1281_Tp __cxx_atomic_fetch_add(__cxx_atomic_lock_impl<_Tp>* __a,
1282 _Td __delta, memory_order) {
1283 __a->__lock();
1284 _Tp __old = __a->__a_value;
1285 __a->__a_value += __delta;
1286 __a->__unlock();
1287 return __old;
1288}
1289
1290template <typename _Tp, typename _Td>
1291_LIBCPP_INLINE_VISIBILITY
1292_Tp* __cxx_atomic_fetch_add(volatile __cxx_atomic_lock_impl<_Tp*>* __a,
1293 ptrdiff_t __delta, memory_order) {
1294 __a->__lock();
1295 _Tp* __old;
1296 __cxx_atomic_assign_volatile(__old, __a->__a_value);
1297 __cxx_atomic_assign_volatile(__a->__a_value, __old + __delta);
1298 __a->__unlock();
1299 return __old;
1300}
1301template <typename _Tp, typename _Td>
1302_LIBCPP_INLINE_VISIBILITY
1303_Tp* __cxx_atomic_fetch_add(__cxx_atomic_lock_impl<_Tp*>* __a,
1304 ptrdiff_t __delta, memory_order) {
1305 __a->__lock();
1306 _Tp* __old = __a->__a_value;
1307 __a->__a_value += __delta;
1308 __a->__unlock();
1309 return __old;
1310}
1311
1312template <typename _Tp, typename _Td>
1313_LIBCPP_INLINE_VISIBILITY
1314_Tp __cxx_atomic_fetch_sub(volatile __cxx_atomic_lock_impl<_Tp>* __a,
1315 _Td __delta, memory_order) {
1316 __a->__lock();
1317 _Tp __old;
1318 __cxx_atomic_assign_volatile(__old, __a->__a_value);
1319 __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old - __delta));
1320 __a->__unlock();
1321 return __old;
1322}
1323template <typename _Tp, typename _Td>
1324_LIBCPP_INLINE_VISIBILITY
1325_Tp __cxx_atomic_fetch_sub(__cxx_atomic_lock_impl<_Tp>* __a,
1326 _Td __delta, memory_order) {
1327 __a->__lock();
1328 _Tp __old = __a->__a_value;
1329 __a->__a_value -= __delta;
1330 __a->__unlock();
1331 return __old;
1332}
1333
1334template <typename _Tp>
1335_LIBCPP_INLINE_VISIBILITY
1336_Tp __cxx_atomic_fetch_and(volatile __cxx_atomic_lock_impl<_Tp>* __a,
1337 _Tp __pattern, memory_order) {
1338 __a->__lock();
1339 _Tp __old;
1340 __cxx_atomic_assign_volatile(__old, __a->__a_value);
1341 __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old & __pattern));
1342 __a->__unlock();
1343 return __old;
1344}
1345template <typename _Tp>
1346_LIBCPP_INLINE_VISIBILITY
1347_Tp __cxx_atomic_fetch_and(__cxx_atomic_lock_impl<_Tp>* __a,
1348 _Tp __pattern, memory_order) {
1349 __a->__lock();
1350 _Tp __old = __a->__a_value;
1351 __a->__a_value &= __pattern;
1352 __a->__unlock();
1353 return __old;
1354}
1355
1356template <typename _Tp>
1357_LIBCPP_INLINE_VISIBILITY
1358_Tp __cxx_atomic_fetch_or(volatile __cxx_atomic_lock_impl<_Tp>* __a,
1359 _Tp __pattern, memory_order) {
1360 __a->__lock();
1361 _Tp __old;
1362 __cxx_atomic_assign_volatile(__old, __a->__a_value);
1363 __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old | __pattern));
1364 __a->__unlock();
1365 return __old;
1366}
1367template <typename _Tp>
1368_LIBCPP_INLINE_VISIBILITY
1369_Tp __cxx_atomic_fetch_or(__cxx_atomic_lock_impl<_Tp>* __a,
1370 _Tp __pattern, memory_order) {
1371 __a->__lock();
1372 _Tp __old = __a->__a_value;
1373 __a->__a_value |= __pattern;
1374 __a->__unlock();
1375 return __old;
1376}
1377
1378template <typename _Tp>
1379_LIBCPP_INLINE_VISIBILITY
1380_Tp __cxx_atomic_fetch_xor(volatile __cxx_atomic_lock_impl<_Tp>* __a,
1381 _Tp __pattern, memory_order) {
1382 __a->__lock();
1383 _Tp __old;
1384 __cxx_atomic_assign_volatile(__old, __a->__a_value);
1385 __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old ^ __pattern));
1386 __a->__unlock();
1387 return __old;
1388}
1389template <typename _Tp>
1390_LIBCPP_INLINE_VISIBILITY
1391_Tp __cxx_atomic_fetch_xor(__cxx_atomic_lock_impl<_Tp>* __a,
1392 _Tp __pattern, memory_order) {
1393 __a->__lock();
1394 _Tp __old = __a->__a_value;
1395 __a->__a_value ^= __pattern;
1396 __a->__unlock();
1397 return __old;
1398}
1399
1400#ifdef __cpp_lib_atomic_is_always_lock_free
1401
1402template<typename _Tp> struct __cxx_is_always_lock_free {
1403 enum { __value = __atomic_always_lock_free(sizeof(_Tp), 0) }; };
1404
1405#else
1406
1407template<typename _Tp> struct __cxx_is_always_lock_free { enum { __value = false }; };
1408// Implementations must match the C ATOMIC_*_LOCK_FREE macro values.
1409template<> struct __cxx_is_always_lock_free<bool> { enum { __value = 2 == ATOMIC_BOOL_LOCK_FREE }; };
1410template<> struct __cxx_is_always_lock_free<char> { enum { __value = 2 == ATOMIC_CHAR_LOCK_FREE }; };
1411template<> struct __cxx_is_always_lock_free<signed char> { enum { __value = 2 == ATOMIC_CHAR_LOCK_FREE }; };
1412template<> struct __cxx_is_always_lock_free<unsigned char> { enum { __value = 2 == ATOMIC_CHAR_LOCK_FREE }; };
Arthur O'Dwyerafa5d5f2021-04-18 21:47:08 -04001413#ifndef _LIBCPP_HAS_NO_CHAR8_T
Marek Kurdej91bebaa2020-11-24 21:07:06 +01001414template<> struct __cxx_is_always_lock_free<char8_t> { enum { __value = 2 == ATOMIC_CHAR8_T_LOCK_FREE }; };
1415#endif
Davide Italiano011f80a2019-03-05 18:40:49 +00001416template<> struct __cxx_is_always_lock_free<char16_t> { enum { __value = 2 == ATOMIC_CHAR16_T_LOCK_FREE }; };
1417template<> struct __cxx_is_always_lock_free<char32_t> { enum { __value = 2 == ATOMIC_CHAR32_T_LOCK_FREE }; };
Louis Dionne89258142021-08-23 15:32:36 -04001418#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Davide Italiano011f80a2019-03-05 18:40:49 +00001419template<> struct __cxx_is_always_lock_free<wchar_t> { enum { __value = 2 == ATOMIC_WCHAR_T_LOCK_FREE }; };
Louis Dionne89258142021-08-23 15:32:36 -04001420#endif
Davide Italiano011f80a2019-03-05 18:40:49 +00001421template<> struct __cxx_is_always_lock_free<short> { enum { __value = 2 == ATOMIC_SHORT_LOCK_FREE }; };
1422template<> struct __cxx_is_always_lock_free<unsigned short> { enum { __value = 2 == ATOMIC_SHORT_LOCK_FREE }; };
1423template<> struct __cxx_is_always_lock_free<int> { enum { __value = 2 == ATOMIC_INT_LOCK_FREE }; };
1424template<> struct __cxx_is_always_lock_free<unsigned int> { enum { __value = 2 == ATOMIC_INT_LOCK_FREE }; };
1425template<> struct __cxx_is_always_lock_free<long> { enum { __value = 2 == ATOMIC_LONG_LOCK_FREE }; };
1426template<> struct __cxx_is_always_lock_free<unsigned long> { enum { __value = 2 == ATOMIC_LONG_LOCK_FREE }; };
1427template<> struct __cxx_is_always_lock_free<long long> { enum { __value = 2 == ATOMIC_LLONG_LOCK_FREE }; };
1428template<> struct __cxx_is_always_lock_free<unsigned long long> { enum { __value = 2 == ATOMIC_LLONG_LOCK_FREE }; };
1429template<typename _Tp> struct __cxx_is_always_lock_free<_Tp*> { enum { __value = 2 == ATOMIC_POINTER_LOCK_FREE }; };
1430template<> struct __cxx_is_always_lock_free<std::nullptr_t> { enum { __value = 2 == ATOMIC_POINTER_LOCK_FREE }; };
1431
1432#endif //__cpp_lib_atomic_is_always_lock_free
1433
1434template <typename _Tp,
1435 typename _Base = typename conditional<__cxx_is_always_lock_free<_Tp>::__value,
1436 __cxx_atomic_base_impl<_Tp>,
1437 __cxx_atomic_lock_impl<_Tp> >::type>
1438#else
1439template <typename _Tp,
1440 typename _Base = __cxx_atomic_base_impl<_Tp> >
1441#endif //_LIBCPP_ATOMIC_ONLY_USE_BUILTINS
1442struct __cxx_atomic_impl : public _Base {
Davide Italiano011f80a2019-03-05 18:40:49 +00001443 static_assert(is_trivially_copyable<_Tp>::value,
Louis Dionne2f766432021-11-17 11:09:55 -05001444 "std::atomic<T> requires that 'T' be a trivially copyable type");
Davide Italiano011f80a2019-03-05 18:40:49 +00001445
Nikolas Klauser6766be32021-12-07 20:29:35 +01001446 _LIBCPP_INLINE_VISIBILITY __cxx_atomic_impl() _NOEXCEPT = default;
Davide Italiano011f80a2019-03-05 18:40:49 +00001447 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR explicit __cxx_atomic_impl(_Tp value) _NOEXCEPT
1448 : _Base(value) {}
1449};
1450
Olivier Giroux161e6e82020-02-18 09:58:34 -05001451#ifdef __linux__
1452 using __cxx_contention_t = int32_t;
1453#else
1454 using __cxx_contention_t = int64_t;
1455#endif //__linux__
1456
Olivier Giroux161e6e82020-02-18 09:58:34 -05001457using __cxx_atomic_contention_t = __cxx_atomic_impl<__cxx_contention_t>;
1458
Louis Dionneaf2d2a82021-11-17 10:59:31 -05001459#if defined(_LIBCPP_HAS_NO_THREADS)
1460# define _LIBCPP_HAS_NO_PLATFORM_WAIT
1461#endif
1462
1463// TODO:
1464// _LIBCPP_HAS_NO_PLATFORM_WAIT is currently a "dead" macro, in the sense that
1465// it is not tied anywhere into the build system or even documented. We should
1466// clean it up because it is technically never defined except when threads are
1467// disabled. We should clean it up in its own changeset in case we break "bad"
1468// users.
Olivier Giroux161e6e82020-02-18 09:58:34 -05001469#ifndef _LIBCPP_HAS_NO_PLATFORM_WAIT
1470
Louis Dionne48a828b2020-02-24 10:08:41 -05001471_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_one(void const volatile*);
1472_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_all(void const volatile*);
1473_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t __libcpp_atomic_monitor(void const volatile*);
1474_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __libcpp_atomic_wait(void const volatile*, __cxx_contention_t);
Olivier Giroux161e6e82020-02-18 09:58:34 -05001475
Louis Dionne48a828b2020-02-24 10:08:41 -05001476_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_one(__cxx_atomic_contention_t const volatile*);
1477_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_all(__cxx_atomic_contention_t const volatile*);
1478_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t __libcpp_atomic_monitor(__cxx_atomic_contention_t const volatile*);
1479_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __libcpp_atomic_wait(__cxx_atomic_contention_t const volatile*, __cxx_contention_t);
Olivier Giroux161e6e82020-02-18 09:58:34 -05001480
1481template <class _Atp, class _Fn>
Louis Dionne08cd5cb2020-02-24 11:39:48 -05001482struct __libcpp_atomic_wait_backoff_impl {
1483 _Atp* __a;
1484 _Fn __test_fn;
Louis Dionne3dde4ab2020-02-24 10:09:29 -05001485 _LIBCPP_AVAILABILITY_SYNC
Louis Dionne08cd5cb2020-02-24 11:39:48 -05001486 _LIBCPP_INLINE_VISIBILITY bool operator()(chrono::nanoseconds __elapsed) const
1487 {
Olivier Giroux161e6e82020-02-18 09:58:34 -05001488 if(__elapsed > chrono::microseconds(64))
1489 {
1490 auto const __monitor = __libcpp_atomic_monitor(__a);
1491 if(__test_fn())
1492 return true;
1493 __libcpp_atomic_wait(__a, __monitor);
1494 }
1495 else if(__elapsed > chrono::microseconds(4))
1496 __libcpp_thread_yield();
1497 else
Marek Kurdejc79652f2020-11-15 16:17:52 +01001498 {} // poll
Olivier Giroux161e6e82020-02-18 09:58:34 -05001499 return false;
Louis Dionne08cd5cb2020-02-24 11:39:48 -05001500 }
1501};
1502
1503template <class _Atp, class _Fn>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05001504_LIBCPP_AVAILABILITY_SYNC
Louis Dionne08cd5cb2020-02-24 11:39:48 -05001505_LIBCPP_INLINE_VISIBILITY bool __cxx_atomic_wait(_Atp* __a, _Fn && __test_fn)
1506{
1507 __libcpp_atomic_wait_backoff_impl<_Atp, typename decay<_Fn>::type> __backoff_fn = {__a, __test_fn};
1508 return __libcpp_thread_poll_with_backoff(__test_fn, __backoff_fn);
Olivier Giroux161e6e82020-02-18 09:58:34 -05001509}
1510
1511#else // _LIBCPP_HAS_NO_PLATFORM_WAIT
1512
1513template <class _Tp>
1514_LIBCPP_INLINE_VISIBILITY void __cxx_atomic_notify_all(__cxx_atomic_impl<_Tp> const volatile*) { }
1515template <class _Tp>
1516_LIBCPP_INLINE_VISIBILITY void __cxx_atomic_notify_one(__cxx_atomic_impl<_Tp> const volatile*) { }
1517template <class _Atp, class _Fn>
1518_LIBCPP_INLINE_VISIBILITY bool __cxx_atomic_wait(_Atp*, _Fn && __test_fn)
1519{
Louis Dionneaf2d2a82021-11-17 10:59:31 -05001520#if defined(_LIBCPP_HAS_NO_THREADS)
1521 using _Policy = __spinning_backoff_policy;
1522#else
1523 using _Policy = __libcpp_timed_backoff_policy;
1524#endif
1525 return __libcpp_thread_poll_with_backoff(__test_fn, _Policy());
Olivier Giroux161e6e82020-02-18 09:58:34 -05001526}
1527
1528#endif // _LIBCPP_HAS_NO_PLATFORM_WAIT
1529
1530template <class _Atp, class _Tp>
Louis Dionne08cd5cb2020-02-24 11:39:48 -05001531struct __cxx_atomic_wait_test_fn_impl {
1532 _Atp* __a;
1533 _Tp __val;
1534 memory_order __order;
1535 _LIBCPP_INLINE_VISIBILITY bool operator()() const
1536 {
1537 return !__cxx_nonatomic_compare_equal(__cxx_atomic_load(__a, __order), __val);
1538 }
1539};
1540
1541template <class _Atp, class _Tp>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05001542_LIBCPP_AVAILABILITY_SYNC
Olivier Giroux161e6e82020-02-18 09:58:34 -05001543_LIBCPP_INLINE_VISIBILITY bool __cxx_atomic_wait(_Atp* __a, _Tp const __val, memory_order __order)
1544{
Louis Dionne08cd5cb2020-02-24 11:39:48 -05001545 __cxx_atomic_wait_test_fn_impl<_Atp, _Tp> __test_fn = {__a, __val, __order};
Olivier Giroux161e6e82020-02-18 09:58:34 -05001546 return __cxx_atomic_wait(__a, __test_fn);
1547}
1548
Howard Hinnant138f5922010-12-07 20:46:14 +00001549// general atomic<T>
1550
1551template <class _Tp, bool = is_integral<_Tp>::value && !is_same<_Tp, bool>::value>
1552struct __atomic_base // false
1553{
Davide Italiano011f80a2019-03-05 18:40:49 +00001554 mutable __cxx_atomic_impl<_Tp> __a_;
Howard Hinnant138f5922010-12-07 20:46:14 +00001555
JF Bastienfdb42c22016-03-25 15:48:21 +00001556#if defined(__cpp_lib_atomic_is_always_lock_free)
1557 static _LIBCPP_CONSTEXPR bool is_always_lock_free = __atomic_always_lock_free(sizeof(__a_), 0);
1558#endif
1559
Howard Hinnant138f5922010-12-07 20:46:14 +00001560 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001561 bool is_lock_free() const volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001562 {return __cxx_atomic_is_lock_free(sizeof(_Tp));}
Howard Hinnant138f5922010-12-07 20:46:14 +00001563 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001564 bool is_lock_free() const _NOEXCEPT
Eric Fiselier3fd22c22015-06-13 00:23:07 +00001565 {return static_cast<__atomic_base const volatile*>(this)->is_lock_free();}
Howard Hinnant138f5922010-12-07 20:46:14 +00001566 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001567 void store(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001568 _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
Davide Italiano011f80a2019-03-05 18:40:49 +00001569 {__cxx_atomic_store(&__a_, __d, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001570 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001571 void store(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001572 _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
Davide Italiano011f80a2019-03-05 18:40:49 +00001573 {__cxx_atomic_store(&__a_, __d, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001574 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001575 _Tp load(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001576 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
Davide Italiano011f80a2019-03-05 18:40:49 +00001577 {return __cxx_atomic_load(&__a_, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001578 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001579 _Tp load(memory_order __m = memory_order_seq_cst) const _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001580 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
Davide Italiano011f80a2019-03-05 18:40:49 +00001581 {return __cxx_atomic_load(&__a_, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001582 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001583 operator _Tp() const volatile _NOEXCEPT {return load();}
Howard Hinnant138f5922010-12-07 20:46:14 +00001584 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001585 operator _Tp() const _NOEXCEPT {return load();}
Howard Hinnant138f5922010-12-07 20:46:14 +00001586 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001587 _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001588 {return __cxx_atomic_exchange(&__a_, __d, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001589 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001590 _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001591 {return __cxx_atomic_exchange(&__a_, __d, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001592 _LIBCPP_INLINE_VISIBILITY
1593 bool compare_exchange_weak(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001594 memory_order __s, memory_order __f) volatile _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001595 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Davide Italiano011f80a2019-03-05 18:40:49 +00001596 {return __cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001597 _LIBCPP_INLINE_VISIBILITY
1598 bool compare_exchange_weak(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001599 memory_order __s, memory_order __f) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001600 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Davide Italiano011f80a2019-03-05 18:40:49 +00001601 {return __cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001602 _LIBCPP_INLINE_VISIBILITY
1603 bool compare_exchange_strong(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001604 memory_order __s, memory_order __f) volatile _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001605 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Davide Italiano011f80a2019-03-05 18:40:49 +00001606 {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001607 _LIBCPP_INLINE_VISIBILITY
1608 bool compare_exchange_strong(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001609 memory_order __s, memory_order __f) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001610 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Davide Italiano011f80a2019-03-05 18:40:49 +00001611 {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001612 _LIBCPP_INLINE_VISIBILITY
1613 bool compare_exchange_weak(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001614 memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001615 {return __cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001616 _LIBCPP_INLINE_VISIBILITY
1617 bool compare_exchange_weak(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001618 memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001619 {return __cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001620 _LIBCPP_INLINE_VISIBILITY
1621 bool compare_exchange_strong(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001622 memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001623 {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001624 _LIBCPP_INLINE_VISIBILITY
1625 bool compare_exchange_strong(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001626 memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001627 {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001628
Louis Dionne3dde4ab2020-02-24 10:09:29 -05001629 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void wait(_Tp __v, memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
Olivier Giroux161e6e82020-02-18 09:58:34 -05001630 {__cxx_atomic_wait(&__a_, __v, __m);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05001631 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void wait(_Tp __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT
Olivier Giroux161e6e82020-02-18 09:58:34 -05001632 {__cxx_atomic_wait(&__a_, __v, __m);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05001633 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_one() volatile _NOEXCEPT
Olivier Giroux161e6e82020-02-18 09:58:34 -05001634 {__cxx_atomic_notify_one(&__a_);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05001635 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_one() _NOEXCEPT
Olivier Giroux161e6e82020-02-18 09:58:34 -05001636 {__cxx_atomic_notify_one(&__a_);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05001637 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_all() volatile _NOEXCEPT
Olivier Giroux161e6e82020-02-18 09:58:34 -05001638 {__cxx_atomic_notify_all(&__a_);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05001639 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_all() _NOEXCEPT
Olivier Giroux161e6e82020-02-18 09:58:34 -05001640 {__cxx_atomic_notify_all(&__a_);}
1641
Raul Tambre4e0e88f2021-06-06 19:02:20 +03001642#if _LIBCPP_STD_VER > 17
1643 _LIBCPP_INLINE_VISIBILITY constexpr
1644 __atomic_base() noexcept(is_nothrow_default_constructible_v<_Tp>) : __a_(_Tp()) {}
1645#else
Howard Hinnant138f5922010-12-07 20:46:14 +00001646 _LIBCPP_INLINE_VISIBILITY
Nikolas Klauser6766be32021-12-07 20:29:35 +01001647 __atomic_base() _NOEXCEPT = default;
Raul Tambre4e0e88f2021-06-06 19:02:20 +03001648#endif
Howard Hinnant3d284222013-05-02 20:18:43 +00001649
Davide Italiano011f80a2019-03-05 18:40:49 +00001650 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
1651 __atomic_base(_Tp __d) _NOEXCEPT : __a_(__d) {}
1652
Eric Fiselier2d8515f2017-01-06 20:58:25 +00001653#ifndef _LIBCPP_CXX03_LANG
Howard Hinnant138f5922010-12-07 20:46:14 +00001654 __atomic_base(const __atomic_base&) = delete;
Eric Fiselier2d8515f2017-01-06 20:58:25 +00001655#else
Howard Hinnant6ac60f82010-12-08 17:20:28 +00001656private:
Olivier Giroux161e6e82020-02-18 09:58:34 -05001657 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant6ac60f82010-12-08 17:20:28 +00001658 __atomic_base(const __atomic_base&);
Eric Fiselier2d8515f2017-01-06 20:58:25 +00001659#endif
Howard Hinnant138f5922010-12-07 20:46:14 +00001660};
1661
JF Bastienfdb42c22016-03-25 15:48:21 +00001662#if defined(__cpp_lib_atomic_is_always_lock_free)
1663template <class _Tp, bool __b>
1664_LIBCPP_CONSTEXPR bool __atomic_base<_Tp, __b>::is_always_lock_free;
1665#endif
1666
Howard Hinnant138f5922010-12-07 20:46:14 +00001667// atomic<Integral>
1668
1669template <class _Tp>
1670struct __atomic_base<_Tp, true>
1671 : public __atomic_base<_Tp, false>
1672{
1673 typedef __atomic_base<_Tp, false> __base;
Raul Tambre4e0e88f2021-06-06 19:02:20 +03001674
1675 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
Nikolas Klauser6766be32021-12-07 20:29:35 +01001676 __atomic_base() _NOEXCEPT = default;
Raul Tambre4e0e88f2021-06-06 19:02:20 +03001677
Howard Hinnant138f5922010-12-07 20:46:14 +00001678 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001679 _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __base(__d) {}
Howard Hinnant138f5922010-12-07 20:46:14 +00001680
1681 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001682 _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001683 {return __cxx_atomic_fetch_add(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001684 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001685 _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001686 {return __cxx_atomic_fetch_add(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001687 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001688 _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001689 {return __cxx_atomic_fetch_sub(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001690 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001691 _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001692 {return __cxx_atomic_fetch_sub(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001693 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001694 _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001695 {return __cxx_atomic_fetch_and(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001696 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001697 _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001698 {return __cxx_atomic_fetch_and(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001699 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001700 _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001701 {return __cxx_atomic_fetch_or(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001702 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001703 _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001704 {return __cxx_atomic_fetch_or(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001705 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001706 _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001707 {return __cxx_atomic_fetch_xor(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001708 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001709 _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001710 {return __cxx_atomic_fetch_xor(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001711
1712 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001713 _Tp operator++(int) volatile _NOEXCEPT {return fetch_add(_Tp(1));}
Howard Hinnant138f5922010-12-07 20:46:14 +00001714 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001715 _Tp operator++(int) _NOEXCEPT {return fetch_add(_Tp(1));}
Howard Hinnant138f5922010-12-07 20:46:14 +00001716 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001717 _Tp operator--(int) volatile _NOEXCEPT {return fetch_sub(_Tp(1));}
Howard Hinnant138f5922010-12-07 20:46:14 +00001718 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001719 _Tp operator--(int) _NOEXCEPT {return fetch_sub(_Tp(1));}
Howard Hinnant138f5922010-12-07 20:46:14 +00001720 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001721 _Tp operator++() volatile _NOEXCEPT {return fetch_add(_Tp(1)) + _Tp(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001722 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001723 _Tp operator++() _NOEXCEPT {return fetch_add(_Tp(1)) + _Tp(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001724 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001725 _Tp operator--() volatile _NOEXCEPT {return fetch_sub(_Tp(1)) - _Tp(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001726 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001727 _Tp operator--() _NOEXCEPT {return fetch_sub(_Tp(1)) - _Tp(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001728 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001729 _Tp operator+=(_Tp __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001730 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001731 _Tp operator+=(_Tp __op) _NOEXCEPT {return fetch_add(__op) + __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001732 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001733 _Tp operator-=(_Tp __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001734 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001735 _Tp operator-=(_Tp __op) _NOEXCEPT {return fetch_sub(__op) - __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001736 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001737 _Tp operator&=(_Tp __op) volatile _NOEXCEPT {return fetch_and(__op) & __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001738 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001739 _Tp operator&=(_Tp __op) _NOEXCEPT {return fetch_and(__op) & __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001740 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001741 _Tp operator|=(_Tp __op) volatile _NOEXCEPT {return fetch_or(__op) | __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001742 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001743 _Tp operator|=(_Tp __op) _NOEXCEPT {return fetch_or(__op) | __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001744 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001745 _Tp operator^=(_Tp __op) volatile _NOEXCEPT {return fetch_xor(__op) ^ __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001746 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001747 _Tp operator^=(_Tp __op) _NOEXCEPT {return fetch_xor(__op) ^ __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001748};
1749
1750// atomic<T>
1751
1752template <class _Tp>
1753struct atomic
1754 : public __atomic_base<_Tp>
1755{
1756 typedef __atomic_base<_Tp> __base;
Olivier Giroux161e6e82020-02-18 09:58:34 -05001757 typedef _Tp value_type;
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07001758 typedef value_type difference_type;
Raul Tambre4e0e88f2021-06-06 19:02:20 +03001759
1760#if _LIBCPP_STD_VER > 17
1761 _LIBCPP_INLINE_VISIBILITY
1762 atomic() = default;
1763#else
Howard Hinnant138f5922010-12-07 20:46:14 +00001764 _LIBCPP_INLINE_VISIBILITY
Nikolas Klauser6766be32021-12-07 20:29:35 +01001765 atomic() _NOEXCEPT = default;
Raul Tambre4e0e88f2021-06-06 19:02:20 +03001766#endif
1767
Howard Hinnant138f5922010-12-07 20:46:14 +00001768 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001769 _LIBCPP_CONSTEXPR atomic(_Tp __d) _NOEXCEPT : __base(__d) {}
Howard Hinnant96e4cd62010-12-07 23:24:41 +00001770
1771 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001772 _Tp operator=(_Tp __d) volatile _NOEXCEPT
Howard Hinnant96e4cd62010-12-07 23:24:41 +00001773 {__base::store(__d); return __d;}
1774 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001775 _Tp operator=(_Tp __d) _NOEXCEPT
Howard Hinnant96e4cd62010-12-07 23:24:41 +00001776 {__base::store(__d); return __d;}
Ruslan Arutyunyan033093f2021-02-01 10:12:09 -05001777
1778 atomic& operator=(const atomic&) = delete;
1779 atomic& operator=(const atomic&) volatile = delete;
Howard Hinnant138f5922010-12-07 20:46:14 +00001780};
1781
1782// atomic<T*>
1783
1784template <class _Tp>
1785struct atomic<_Tp*>
1786 : public __atomic_base<_Tp*>
1787{
Howard Hinnant96e4cd62010-12-07 23:24:41 +00001788 typedef __atomic_base<_Tp*> __base;
Olivier Giroux161e6e82020-02-18 09:58:34 -05001789 typedef _Tp* value_type;
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07001790 typedef ptrdiff_t difference_type;
Raul Tambre4e0e88f2021-06-06 19:02:20 +03001791
Howard Hinnant138f5922010-12-07 20:46:14 +00001792 _LIBCPP_INLINE_VISIBILITY
Nikolas Klauser6766be32021-12-07 20:29:35 +01001793 atomic() _NOEXCEPT = default;
Raul Tambre4e0e88f2021-06-06 19:02:20 +03001794
Howard Hinnant138f5922010-12-07 20:46:14 +00001795 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001796 _LIBCPP_CONSTEXPR atomic(_Tp* __d) _NOEXCEPT : __base(__d) {}
Howard Hinnant138f5922010-12-07 20:46:14 +00001797
1798 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001799 _Tp* operator=(_Tp* __d) volatile _NOEXCEPT
Howard Hinnant96e4cd62010-12-07 23:24:41 +00001800 {__base::store(__d); return __d;}
1801 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001802 _Tp* operator=(_Tp* __d) _NOEXCEPT
Howard Hinnant96e4cd62010-12-07 23:24:41 +00001803 {__base::store(__d); return __d;}
1804
1805 _LIBCPP_INLINE_VISIBILITY
Mark de Wever494905b2021-06-09 20:26:34 +02001806 _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
1807 // __atomic_fetch_add accepts function pointers, guard against them.
1808 static_assert(!is_function<typename remove_pointer<_Tp>::type>::value, "Pointer to function isn't allowed");
1809 return __cxx_atomic_fetch_add(&this->__a_, __op, __m);
1810 }
1811
Howard Hinnant138f5922010-12-07 20:46:14 +00001812 _LIBCPP_INLINE_VISIBILITY
Mark de Wever494905b2021-06-09 20:26:34 +02001813 _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
1814 // __atomic_fetch_add accepts function pointers, guard against them.
1815 static_assert(!is_function<typename remove_pointer<_Tp>::type>::value, "Pointer to function isn't allowed");
1816 return __cxx_atomic_fetch_add(&this->__a_, __op, __m);
1817 }
1818
Howard Hinnant138f5922010-12-07 20:46:14 +00001819 _LIBCPP_INLINE_VISIBILITY
Mark de Wever494905b2021-06-09 20:26:34 +02001820 _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
1821 // __atomic_fetch_add accepts function pointers, guard against them.
1822 static_assert(!is_function<typename remove_pointer<_Tp>::type>::value, "Pointer to function isn't allowed");
1823 return __cxx_atomic_fetch_sub(&this->__a_, __op, __m);
1824 }
1825
Howard Hinnant138f5922010-12-07 20:46:14 +00001826 _LIBCPP_INLINE_VISIBILITY
Mark de Wever494905b2021-06-09 20:26:34 +02001827 _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
1828 // __atomic_fetch_add accepts function pointers, guard against them.
1829 static_assert(!is_function<typename remove_pointer<_Tp>::type>::value, "Pointer to function isn't allowed");
1830 return __cxx_atomic_fetch_sub(&this->__a_, __op, __m);
1831 }
Howard Hinnant138f5922010-12-07 20:46:14 +00001832
1833 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001834 _Tp* operator++(int) volatile _NOEXCEPT {return fetch_add(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001835 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001836 _Tp* operator++(int) _NOEXCEPT {return fetch_add(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001837 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001838 _Tp* operator--(int) volatile _NOEXCEPT {return fetch_sub(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001839 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001840 _Tp* operator--(int) _NOEXCEPT {return fetch_sub(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001841 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001842 _Tp* operator++() volatile _NOEXCEPT {return fetch_add(1) + 1;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001843 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001844 _Tp* operator++() _NOEXCEPT {return fetch_add(1) + 1;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001845 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001846 _Tp* operator--() volatile _NOEXCEPT {return fetch_sub(1) - 1;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001847 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001848 _Tp* operator--() _NOEXCEPT {return fetch_sub(1) - 1;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001849 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001850 _Tp* operator+=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001851 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001852 _Tp* operator+=(ptrdiff_t __op) _NOEXCEPT {return fetch_add(__op) + __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001853 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001854 _Tp* operator-=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001855 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001856 _Tp* operator-=(ptrdiff_t __op) _NOEXCEPT {return fetch_sub(__op) - __op;}
Ruslan Arutyunyan033093f2021-02-01 10:12:09 -05001857
1858 atomic& operator=(const atomic&) = delete;
1859 atomic& operator=(const atomic&) volatile = delete;
Howard Hinnant138f5922010-12-07 20:46:14 +00001860};
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001861
1862// atomic_is_lock_free
1863
1864template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001865_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001866bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00001867atomic_is_lock_free(const volatile atomic<_Tp>* __o) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001868{
Howard Hinnant138f5922010-12-07 20:46:14 +00001869 return __o->is_lock_free();
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001870}
1871
1872template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001873_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001874bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00001875atomic_is_lock_free(const atomic<_Tp>* __o) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001876{
Howard Hinnant138f5922010-12-07 20:46:14 +00001877 return __o->is_lock_free();
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001878}
1879
1880// atomic_init
1881
1882template <class _Tp>
Raul Tambre4e0e88f2021-06-06 19:02:20 +03001883_LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001884void
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07001885atomic_init(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001886{
Davide Italiano011f80a2019-03-05 18:40:49 +00001887 __cxx_atomic_init(&__o->__a_, __d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001888}
1889
1890template <class _Tp>
Raul Tambre4e0e88f2021-06-06 19:02:20 +03001891_LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001892void
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07001893atomic_init(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001894{
Davide Italiano011f80a2019-03-05 18:40:49 +00001895 __cxx_atomic_init(&__o->__a_, __d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001896}
1897
1898// atomic_store
1899
1900template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001901_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001902void
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07001903atomic_store(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001904{
Howard Hinnant138f5922010-12-07 20:46:14 +00001905 __o->store(__d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001906}
1907
1908template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001909_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001910void
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07001911atomic_store(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001912{
Howard Hinnant138f5922010-12-07 20:46:14 +00001913 __o->store(__d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001914}
1915
1916// atomic_store_explicit
1917
1918template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001919_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001920void
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07001921atomic_store_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001922 _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001923{
Howard Hinnant138f5922010-12-07 20:46:14 +00001924 __o->store(__d, __m);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001925}
1926
1927template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001928_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001929void
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07001930atomic_store_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001931 _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001932{
Howard Hinnant138f5922010-12-07 20:46:14 +00001933 __o->store(__d, __m);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001934}
1935
1936// atomic_load
1937
1938template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001939_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001940_Tp
Howard Hinnanteee2c142012-04-11 20:14:21 +00001941atomic_load(const volatile atomic<_Tp>* __o) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001942{
Howard Hinnant138f5922010-12-07 20:46:14 +00001943 return __o->load();
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001944}
1945
1946template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001947_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001948_Tp
Howard Hinnanteee2c142012-04-11 20:14:21 +00001949atomic_load(const atomic<_Tp>* __o) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001950{
Howard Hinnant138f5922010-12-07 20:46:14 +00001951 return __o->load();
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001952}
1953
1954// atomic_load_explicit
1955
1956template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001957_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001958_Tp
Howard Hinnanteee2c142012-04-11 20:14:21 +00001959atomic_load_explicit(const volatile atomic<_Tp>* __o, memory_order __m) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001960 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001961{
Howard Hinnant138f5922010-12-07 20:46:14 +00001962 return __o->load(__m);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001963}
1964
1965template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001966_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001967_Tp
Howard Hinnanteee2c142012-04-11 20:14:21 +00001968atomic_load_explicit(const atomic<_Tp>* __o, memory_order __m) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001969 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001970{
Howard Hinnant138f5922010-12-07 20:46:14 +00001971 return __o->load(__m);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001972}
1973
1974// atomic_exchange
1975
1976template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001977_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001978_Tp
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07001979atomic_exchange(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001980{
Howard Hinnant138f5922010-12-07 20:46:14 +00001981 return __o->exchange(__d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001982}
1983
1984template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001985_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001986_Tp
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07001987atomic_exchange(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001988{
Howard Hinnant138f5922010-12-07 20:46:14 +00001989 return __o->exchange(__d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001990}
1991
1992// atomic_exchange_explicit
1993
1994template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001995_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001996_Tp
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07001997atomic_exchange_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001998{
Howard Hinnant138f5922010-12-07 20:46:14 +00001999 return __o->exchange(__d, __m);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002000}
2001
2002template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002003_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002004_Tp
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002005atomic_exchange_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002006{
Howard Hinnant138f5922010-12-07 20:46:14 +00002007 return __o->exchange(__d, __m);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002008}
2009
2010// atomic_compare_exchange_weak
2011
2012template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002013_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002014bool
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002015atomic_compare_exchange_weak(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002016{
Howard Hinnant138f5922010-12-07 20:46:14 +00002017 return __o->compare_exchange_weak(*__e, __d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002018}
2019
2020template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002021_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002022bool
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002023atomic_compare_exchange_weak(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002024{
Howard Hinnant138f5922010-12-07 20:46:14 +00002025 return __o->compare_exchange_weak(*__e, __d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002026}
2027
2028// atomic_compare_exchange_strong
2029
2030template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002031_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002032bool
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002033atomic_compare_exchange_strong(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002034{
Howard Hinnant138f5922010-12-07 20:46:14 +00002035 return __o->compare_exchange_strong(*__e, __d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002036}
2037
2038template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002039_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002040bool
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002041atomic_compare_exchange_strong(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002042{
Howard Hinnant138f5922010-12-07 20:46:14 +00002043 return __o->compare_exchange_strong(*__e, __d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002044}
2045
2046// atomic_compare_exchange_weak_explicit
2047
2048template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002049_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002050bool
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002051atomic_compare_exchange_weak_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e,
2052 typename atomic<_Tp>::value_type __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00002053 memory_order __s, memory_order __f) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00002054 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002055{
Howard Hinnant138f5922010-12-07 20:46:14 +00002056 return __o->compare_exchange_weak(*__e, __d, __s, __f);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002057}
2058
2059template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002060_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002061bool
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002062atomic_compare_exchange_weak_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00002063 memory_order __s, memory_order __f) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00002064 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002065{
Howard Hinnant138f5922010-12-07 20:46:14 +00002066 return __o->compare_exchange_weak(*__e, __d, __s, __f);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002067}
2068
2069// atomic_compare_exchange_strong_explicit
2070
2071template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002072_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002073bool
2074atomic_compare_exchange_strong_explicit(volatile atomic<_Tp>* __o,
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002075 typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00002076 memory_order __s, memory_order __f) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00002077 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002078{
Howard Hinnant138f5922010-12-07 20:46:14 +00002079 return __o->compare_exchange_strong(*__e, __d, __s, __f);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002080}
2081
2082template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002083_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002084bool
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002085atomic_compare_exchange_strong_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e,
2086 typename atomic<_Tp>::value_type __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00002087 memory_order __s, memory_order __f) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00002088 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002089{
Howard Hinnant138f5922010-12-07 20:46:14 +00002090 return __o->compare_exchange_strong(*__e, __d, __s, __f);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002091}
2092
Olivier Giroux161e6e82020-02-18 09:58:34 -05002093// atomic_wait
2094
2095template <class _Tp>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002096_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002097void atomic_wait(const volatile atomic<_Tp>* __o,
2098 typename atomic<_Tp>::value_type __v) _NOEXCEPT
2099{
2100 return __o->wait(__v);
2101}
2102
2103template <class _Tp>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002104_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002105void atomic_wait(const atomic<_Tp>* __o,
2106 typename atomic<_Tp>::value_type __v) _NOEXCEPT
2107{
2108 return __o->wait(__v);
2109}
2110
2111// atomic_wait_explicit
2112
2113template <class _Tp>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002114_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002115void atomic_wait_explicit(const volatile atomic<_Tp>* __o,
2116 typename atomic<_Tp>::value_type __v,
2117 memory_order __m) _NOEXCEPT
2118 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
2119{
2120 return __o->wait(__v, __m);
2121}
2122
2123template <class _Tp>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002124_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002125void atomic_wait_explicit(const atomic<_Tp>* __o,
2126 typename atomic<_Tp>::value_type __v,
2127 memory_order __m) _NOEXCEPT
2128 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
2129{
2130 return __o->wait(__v, __m);
2131}
2132
2133// atomic_notify_one
2134
2135template <class _Tp>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002136_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002137void atomic_notify_one(volatile atomic<_Tp>* __o) _NOEXCEPT
2138{
2139 __o->notify_one();
2140}
2141template <class _Tp>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002142_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002143void atomic_notify_one(atomic<_Tp>* __o) _NOEXCEPT
2144{
2145 __o->notify_one();
2146}
2147
2148// atomic_notify_one
2149
2150template <class _Tp>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002151_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002152void atomic_notify_all(volatile atomic<_Tp>* __o) _NOEXCEPT
2153{
2154 __o->notify_all();
2155}
2156template <class _Tp>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002157_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002158void atomic_notify_all(atomic<_Tp>* __o) _NOEXCEPT
2159{
2160 __o->notify_all();
2161}
2162
Howard Hinnant138f5922010-12-07 20:46:14 +00002163// atomic_fetch_add
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002164
2165template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002166_LIBCPP_INLINE_VISIBILITY
Mark de Wever494905b2021-06-09 20:26:34 +02002167_Tp
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002168atomic_fetch_add(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002169{
Howard Hinnant138f5922010-12-07 20:46:14 +00002170 return __o->fetch_add(__op);
2171}
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002172
Howard Hinnant138f5922010-12-07 20:46:14 +00002173template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002174_LIBCPP_INLINE_VISIBILITY
Mark de Wever494905b2021-06-09 20:26:34 +02002175_Tp
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002176atomic_fetch_add(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002177{
2178 return __o->fetch_add(__op);
2179}
2180
2181// atomic_fetch_add_explicit
2182
2183template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002184_LIBCPP_INLINE_VISIBILITY
Mark de Wever494905b2021-06-09 20:26:34 +02002185_Tp atomic_fetch_add_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002186{
2187 return __o->fetch_add(__op, __m);
2188}
2189
2190template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002191_LIBCPP_INLINE_VISIBILITY
Mark de Wever494905b2021-06-09 20:26:34 +02002192_Tp atomic_fetch_add_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT
Olivier Girouxdf485172020-09-11 12:13:35 -07002193{
2194 return __o->fetch_add(__op, __m);
2195}
2196
Howard Hinnant138f5922010-12-07 20:46:14 +00002197// atomic_fetch_sub
2198
2199template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002200_LIBCPP_INLINE_VISIBILITY
Mark de Wever494905b2021-06-09 20:26:34 +02002201_Tp atomic_fetch_sub(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002202{
2203 return __o->fetch_sub(__op);
2204}
2205
2206template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002207_LIBCPP_INLINE_VISIBILITY
Mark de Wever494905b2021-06-09 20:26:34 +02002208_Tp atomic_fetch_sub(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT
Olivier Girouxdf485172020-09-11 12:13:35 -07002209{
2210 return __o->fetch_sub(__op);
2211}
2212
Howard Hinnant138f5922010-12-07 20:46:14 +00002213// atomic_fetch_sub_explicit
2214
2215template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002216_LIBCPP_INLINE_VISIBILITY
Mark de Wever494905b2021-06-09 20:26:34 +02002217_Tp atomic_fetch_sub_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002218{
2219 return __o->fetch_sub(__op, __m);
2220}
2221
2222template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002223_LIBCPP_INLINE_VISIBILITY
Mark de Wever494905b2021-06-09 20:26:34 +02002224_Tp atomic_fetch_sub_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT
Olivier Girouxdf485172020-09-11 12:13:35 -07002225{
2226 return __o->fetch_sub(__op, __m);
2227}
2228
Howard Hinnant138f5922010-12-07 20:46:14 +00002229// atomic_fetch_and
2230
2231template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002232_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002233typename enable_if
2234<
2235 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2236 _Tp
2237>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002238atomic_fetch_and(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002239{
2240 return __o->fetch_and(__op);
2241}
2242
2243template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002244_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002245typename enable_if
2246<
2247 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2248 _Tp
2249>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002250atomic_fetch_and(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002251{
2252 return __o->fetch_and(__op);
2253}
2254
2255// atomic_fetch_and_explicit
2256
2257template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002258_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002259typename enable_if
2260<
2261 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2262 _Tp
2263>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002264atomic_fetch_and_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002265{
2266 return __o->fetch_and(__op, __m);
2267}
2268
2269template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002270_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002271typename enable_if
2272<
2273 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2274 _Tp
2275>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002276atomic_fetch_and_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002277{
2278 return __o->fetch_and(__op, __m);
2279}
2280
2281// atomic_fetch_or
2282
2283template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002284_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002285typename enable_if
2286<
2287 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2288 _Tp
2289>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002290atomic_fetch_or(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002291{
2292 return __o->fetch_or(__op);
2293}
2294
2295template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002296_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002297typename enable_if
2298<
2299 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2300 _Tp
2301>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002302atomic_fetch_or(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002303{
2304 return __o->fetch_or(__op);
2305}
2306
2307// atomic_fetch_or_explicit
2308
2309template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002310_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002311typename enable_if
2312<
2313 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2314 _Tp
2315>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002316atomic_fetch_or_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002317{
2318 return __o->fetch_or(__op, __m);
2319}
2320
2321template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002322_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002323typename enable_if
2324<
2325 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2326 _Tp
2327>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002328atomic_fetch_or_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002329{
2330 return __o->fetch_or(__op, __m);
2331}
2332
2333// atomic_fetch_xor
2334
2335template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002336_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002337typename enable_if
2338<
2339 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2340 _Tp
2341>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002342atomic_fetch_xor(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002343{
2344 return __o->fetch_xor(__op);
2345}
2346
2347template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002348_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002349typename enable_if
2350<
2351 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2352 _Tp
2353>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002354atomic_fetch_xor(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002355{
2356 return __o->fetch_xor(__op);
2357}
2358
2359// atomic_fetch_xor_explicit
2360
2361template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002362_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002363typename enable_if
2364<
2365 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2366 _Tp
2367>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002368atomic_fetch_xor_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002369{
2370 return __o->fetch_xor(__op, __m);
2371}
2372
2373template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002374_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002375typename enable_if
2376<
2377 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2378 _Tp
2379>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002380atomic_fetch_xor_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002381{
2382 return __o->fetch_xor(__op, __m);
2383}
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002384
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002385// flag type and operations
2386
2387typedef struct atomic_flag
2388{
Davide Italiano011f80a2019-03-05 18:40:49 +00002389 __cxx_atomic_impl<_LIBCPP_ATOMIC_FLAG_TYPE> __a_;
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002390
2391 _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002392 bool test(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
2393 {return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m);}
2394 _LIBCPP_INLINE_VISIBILITY
2395 bool test(memory_order __m = memory_order_seq_cst) const _NOEXCEPT
2396 {return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m);}
2397
2398 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00002399 bool test_and_set(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00002400 {return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);}
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002401 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00002402 bool test_and_set(memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00002403 {return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);}
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002404 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00002405 void clear(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00002406 {__cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);}
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002407 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00002408 void clear(memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00002409 {__cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);}
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002410
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002411 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002412 void wait(bool __v, memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
2413 {__cxx_atomic_wait(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002414 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002415 void wait(bool __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT
2416 {__cxx_atomic_wait(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002417 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002418 void notify_one() volatile _NOEXCEPT
2419 {__cxx_atomic_notify_one(&__a_);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002420 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002421 void notify_one() _NOEXCEPT
2422 {__cxx_atomic_notify_one(&__a_);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002423 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002424 void notify_all() volatile _NOEXCEPT
2425 {__cxx_atomic_notify_all(&__a_);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002426 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002427 void notify_all() _NOEXCEPT
2428 {__cxx_atomic_notify_all(&__a_);}
2429
Raul Tambre4e0e88f2021-06-06 19:02:20 +03002430#if _LIBCPP_STD_VER > 17
2431 _LIBCPP_INLINE_VISIBILITY constexpr
2432 atomic_flag() _NOEXCEPT : __a_(false) {}
2433#else
Olivier Giroux161e6e82020-02-18 09:58:34 -05002434 _LIBCPP_INLINE_VISIBILITY
Nikolas Klauser6766be32021-12-07 20:29:35 +01002435 atomic_flag() _NOEXCEPT = default;
Raul Tambre4e0e88f2021-06-06 19:02:20 +03002436#endif
Howard Hinnant3d284222013-05-02 20:18:43 +00002437
Marshall Clowcf990752018-04-25 14:27:29 +00002438 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
Eric Fiselierfec26a92016-05-03 02:12:26 +00002439 atomic_flag(bool __b) _NOEXCEPT : __a_(__b) {} // EXTENSION
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002440
Eric Fiselier2d8515f2017-01-06 20:58:25 +00002441#ifndef _LIBCPP_CXX03_LANG
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002442 atomic_flag(const atomic_flag&) = delete;
2443 atomic_flag& operator=(const atomic_flag&) = delete;
2444 atomic_flag& operator=(const atomic_flag&) volatile = delete;
Eric Fiselier2d8515f2017-01-06 20:58:25 +00002445#else
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002446private:
Olivier Giroux161e6e82020-02-18 09:58:34 -05002447 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002448 atomic_flag(const atomic_flag&);
Olivier Giroux161e6e82020-02-18 09:58:34 -05002449 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002450 atomic_flag& operator=(const atomic_flag&);
Olivier Giroux161e6e82020-02-18 09:58:34 -05002451 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002452 atomic_flag& operator=(const atomic_flag&) volatile;
Eric Fiselier2d8515f2017-01-06 20:58:25 +00002453#endif
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002454} atomic_flag;
2455
Olivier Giroux161e6e82020-02-18 09:58:34 -05002456
2457inline _LIBCPP_INLINE_VISIBILITY
2458bool
2459atomic_flag_test(const volatile atomic_flag* __o) _NOEXCEPT
2460{
2461 return __o->test();
2462}
2463
2464inline _LIBCPP_INLINE_VISIBILITY
2465bool
2466atomic_flag_test(const atomic_flag* __o) _NOEXCEPT
2467{
2468 return __o->test();
2469}
2470
2471inline _LIBCPP_INLINE_VISIBILITY
2472bool
2473atomic_flag_test_explicit(const volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
2474{
2475 return __o->test(__m);
2476}
2477
2478inline _LIBCPP_INLINE_VISIBILITY
2479bool
2480atomic_flag_test_explicit(const atomic_flag* __o, memory_order __m) _NOEXCEPT
2481{
2482 return __o->test(__m);
2483}
2484
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002485inline _LIBCPP_INLINE_VISIBILITY
2486bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00002487atomic_flag_test_and_set(volatile atomic_flag* __o) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002488{
2489 return __o->test_and_set();
2490}
2491
2492inline _LIBCPP_INLINE_VISIBILITY
2493bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00002494atomic_flag_test_and_set(atomic_flag* __o) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002495{
2496 return __o->test_and_set();
2497}
2498
2499inline _LIBCPP_INLINE_VISIBILITY
2500bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00002501atomic_flag_test_and_set_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002502{
2503 return __o->test_and_set(__m);
2504}
2505
2506inline _LIBCPP_INLINE_VISIBILITY
2507bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00002508atomic_flag_test_and_set_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002509{
2510 return __o->test_and_set(__m);
2511}
2512
2513inline _LIBCPP_INLINE_VISIBILITY
2514void
Howard Hinnanteee2c142012-04-11 20:14:21 +00002515atomic_flag_clear(volatile atomic_flag* __o) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002516{
2517 __o->clear();
2518}
2519
2520inline _LIBCPP_INLINE_VISIBILITY
2521void
Howard Hinnanteee2c142012-04-11 20:14:21 +00002522atomic_flag_clear(atomic_flag* __o) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002523{
2524 __o->clear();
2525}
2526
2527inline _LIBCPP_INLINE_VISIBILITY
2528void
Howard Hinnanteee2c142012-04-11 20:14:21 +00002529atomic_flag_clear_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002530{
2531 __o->clear(__m);
2532}
2533
2534inline _LIBCPP_INLINE_VISIBILITY
2535void
Howard Hinnanteee2c142012-04-11 20:14:21 +00002536atomic_flag_clear_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002537{
2538 __o->clear(__m);
2539}
2540
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002541inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
Olivier Giroux161e6e82020-02-18 09:58:34 -05002542void
2543atomic_flag_wait(const volatile atomic_flag* __o, bool __v) _NOEXCEPT
2544{
2545 __o->wait(__v);
2546}
2547
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002548inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
Olivier Giroux161e6e82020-02-18 09:58:34 -05002549void
2550atomic_flag_wait(const atomic_flag* __o, bool __v) _NOEXCEPT
2551{
2552 __o->wait(__v);
2553}
2554
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002555inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
Olivier Giroux161e6e82020-02-18 09:58:34 -05002556void
2557atomic_flag_wait_explicit(const volatile atomic_flag* __o,
2558 bool __v, memory_order __m) _NOEXCEPT
2559{
2560 __o->wait(__v, __m);
2561}
2562
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002563inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
Olivier Giroux161e6e82020-02-18 09:58:34 -05002564void
2565atomic_flag_wait_explicit(const atomic_flag* __o,
2566 bool __v, memory_order __m) _NOEXCEPT
2567{
2568 __o->wait(__v, __m);
2569}
2570
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002571inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
Olivier Giroux161e6e82020-02-18 09:58:34 -05002572void
2573atomic_flag_notify_one(volatile atomic_flag* __o) _NOEXCEPT
2574{
2575 __o->notify_one();
2576}
2577
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002578inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
Olivier Giroux161e6e82020-02-18 09:58:34 -05002579void
2580atomic_flag_notify_one(atomic_flag* __o) _NOEXCEPT
2581{
2582 __o->notify_one();
2583}
2584
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002585inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
Olivier Giroux161e6e82020-02-18 09:58:34 -05002586void
2587atomic_flag_notify_all(volatile atomic_flag* __o) _NOEXCEPT
2588{
2589 __o->notify_all();
2590}
2591
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002592inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
Olivier Giroux161e6e82020-02-18 09:58:34 -05002593void
2594atomic_flag_notify_all(atomic_flag* __o) _NOEXCEPT
2595{
2596 __o->notify_all();
2597}
2598
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002599// fences
2600
2601inline _LIBCPP_INLINE_VISIBILITY
2602void
Howard Hinnanteee2c142012-04-11 20:14:21 +00002603atomic_thread_fence(memory_order __m) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002604{
Davide Italiano011f80a2019-03-05 18:40:49 +00002605 __cxx_atomic_thread_fence(__m);
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002606}
2607
2608inline _LIBCPP_INLINE_VISIBILITY
2609void
Howard Hinnanteee2c142012-04-11 20:14:21 +00002610atomic_signal_fence(memory_order __m) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002611{
Davide Italiano011f80a2019-03-05 18:40:49 +00002612 __cxx_atomic_signal_fence(__m);
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002613}
2614
Howard Hinnant96e4cd62010-12-07 23:24:41 +00002615// Atomics for standard typedef types
2616
Howard Hinnantf0af8d92013-01-04 18:58:50 +00002617typedef atomic<bool> atomic_bool;
Howard Hinnant96e4cd62010-12-07 23:24:41 +00002618typedef atomic<char> atomic_char;
2619typedef atomic<signed char> atomic_schar;
2620typedef atomic<unsigned char> atomic_uchar;
2621typedef atomic<short> atomic_short;
2622typedef atomic<unsigned short> atomic_ushort;
2623typedef atomic<int> atomic_int;
2624typedef atomic<unsigned int> atomic_uint;
2625typedef atomic<long> atomic_long;
2626typedef atomic<unsigned long> atomic_ulong;
2627typedef atomic<long long> atomic_llong;
2628typedef atomic<unsigned long long> atomic_ullong;
Arthur O'Dwyerafa5d5f2021-04-18 21:47:08 -04002629#ifndef _LIBCPP_HAS_NO_CHAR8_T
Marek Kurdej91bebaa2020-11-24 21:07:06 +01002630typedef atomic<char8_t> atomic_char8_t;
2631#endif
Howard Hinnant96e4cd62010-12-07 23:24:41 +00002632typedef atomic<char16_t> atomic_char16_t;
2633typedef atomic<char32_t> atomic_char32_t;
Louis Dionne89258142021-08-23 15:32:36 -04002634#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnant96e4cd62010-12-07 23:24:41 +00002635typedef atomic<wchar_t> atomic_wchar_t;
Louis Dionne89258142021-08-23 15:32:36 -04002636#endif
Howard Hinnant96e4cd62010-12-07 23:24:41 +00002637
2638typedef atomic<int_least8_t> atomic_int_least8_t;
2639typedef atomic<uint_least8_t> atomic_uint_least8_t;
2640typedef atomic<int_least16_t> atomic_int_least16_t;
2641typedef atomic<uint_least16_t> atomic_uint_least16_t;
2642typedef atomic<int_least32_t> atomic_int_least32_t;
2643typedef atomic<uint_least32_t> atomic_uint_least32_t;
2644typedef atomic<int_least64_t> atomic_int_least64_t;
2645typedef atomic<uint_least64_t> atomic_uint_least64_t;
2646
2647typedef atomic<int_fast8_t> atomic_int_fast8_t;
2648typedef atomic<uint_fast8_t> atomic_uint_fast8_t;
2649typedef atomic<int_fast16_t> atomic_int_fast16_t;
2650typedef atomic<uint_fast16_t> atomic_uint_fast16_t;
2651typedef atomic<int_fast32_t> atomic_int_fast32_t;
2652typedef atomic<uint_fast32_t> atomic_uint_fast32_t;
2653typedef atomic<int_fast64_t> atomic_int_fast64_t;
2654typedef atomic<uint_fast64_t> atomic_uint_fast64_t;
2655
Marshall Clowf710afc2016-06-30 15:28:38 +00002656typedef atomic< int8_t> atomic_int8_t;
2657typedef atomic<uint8_t> atomic_uint8_t;
2658typedef atomic< int16_t> atomic_int16_t;
2659typedef atomic<uint16_t> atomic_uint16_t;
2660typedef atomic< int32_t> atomic_int32_t;
2661typedef atomic<uint32_t> atomic_uint32_t;
2662typedef atomic< int64_t> atomic_int64_t;
2663typedef atomic<uint64_t> atomic_uint64_t;
2664
Howard Hinnant96e4cd62010-12-07 23:24:41 +00002665typedef atomic<intptr_t> atomic_intptr_t;
2666typedef atomic<uintptr_t> atomic_uintptr_t;
2667typedef atomic<size_t> atomic_size_t;
2668typedef atomic<ptrdiff_t> atomic_ptrdiff_t;
2669typedef atomic<intmax_t> atomic_intmax_t;
2670typedef atomic<uintmax_t> atomic_uintmax_t;
2671
Olivier Giroux161e6e82020-02-18 09:58:34 -05002672// atomic_*_lock_free : prefer the contention type most highly, then the largest lock-free type
2673
2674#ifdef __cpp_lib_atomic_is_always_lock_free
2675# define _LIBCPP_CONTENTION_LOCK_FREE __atomic_always_lock_free(sizeof(__cxx_contention_t), 0)
2676#else
2677# define _LIBCPP_CONTENTION_LOCK_FREE false
2678#endif
2679
2680#if ATOMIC_LLONG_LOCK_FREE == 2
2681typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, long long>::type __libcpp_signed_lock_free;
2682typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned long long>::type __libcpp_unsigned_lock_free;
2683#elif ATOMIC_INT_LOCK_FREE == 2
2684typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, int>::type __libcpp_signed_lock_free;
2685typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned int>::type __libcpp_unsigned_lock_free;
2686#elif ATOMIC_SHORT_LOCK_FREE == 2
2687typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, short>::type __libcpp_signed_lock_free;
2688typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned short>::type __libcpp_unsigned_lock_free;
2689#elif ATOMIC_CHAR_LOCK_FREE == 2
2690typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, char>::type __libcpp_signed_lock_free;
2691typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned char>::type __libcpp_unsigned_lock_free;
2692#else
2693 // No signed/unsigned lock-free types
2694#endif
2695
2696typedef atomic<__libcpp_signed_lock_free> atomic_signed_lock_free;
2697typedef atomic<__libcpp_unsigned_lock_free> atomic_unsigned_lock_free;
2698
Howard Hinnantf1f066a2010-09-29 21:20:03 +00002699#define ATOMIC_FLAG_INIT {false}
Howard Hinnant953c31d2010-10-04 18:52:54 +00002700#define ATOMIC_VAR_INIT(__v) {__v}
2701
Howard Hinnant71be7292010-09-27 21:17:38 +00002702_LIBCPP_END_NAMESPACE_STD
2703
Louis Dionne2b1ceaa2021-04-20 12:03:32 -04002704#endif // _LIBCPP_ATOMIC