blob: 7fed8713e03a732e9658493a6aa84c826b23e6f4 [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>
Louis Dionnecaf26832022-01-10 09:43:29 -0500524#include <__thread/timed_backoff_policy.h>
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000525#include <cstddef>
526#include <cstdint>
Olivier Giroux161e6e82020-02-18 09:58:34 -0500527#include <cstring>
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000528#include <type_traits>
Marshall Clow0a1e7502018-09-12 19:41:40 +0000529#include <version>
Howard Hinnant71be7292010-09-27 21:17:38 +0000530
Louis Dionneaf2d2a82021-11-17 10:59:31 -0500531#ifndef _LIBCPP_HAS_NO_THREADS
532# include <__threading_support>
533#endif
534
Howard Hinnantaaaa52b2011-10-17 20:05:10 +0000535#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
Arthur O'Dwyer6eeaa002022-02-01 20:16:40 -0500536# pragma GCC system_header
Howard Hinnantaaaa52b2011-10-17 20:05:10 +0000537#endif
Howard Hinnant71be7292010-09-27 21:17:38 +0000538
Davide Italiano011f80a2019-03-05 18:40:49 +0000539#ifdef _LIBCPP_HAS_NO_ATOMIC_HEADER
540# error <atomic> is not implemented
Eric Fiselier8020b6c2015-08-19 17:21:46 +0000541#endif
Volodymyr Sapsaif3ed1fd2018-05-15 22:38:31 +0000542#ifdef kill_dependency
Davide Italiano011f80a2019-03-05 18:40:49 +0000543# error C++ standard library is incompatible with <stdatomic.h>
Volodymyr Sapsaif3ed1fd2018-05-15 22:38:31 +0000544#endif
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000545
Eric Fiselierb5ab51d2017-01-13 23:45:39 +0000546#define _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) \
547 _LIBCPP_DIAGNOSE_WARNING(__m == memory_order_consume || \
548 __m == memory_order_acquire || \
549 __m == memory_order_acq_rel, \
550 "memory order argument to atomic operation is invalid")
551
552#define _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) \
553 _LIBCPP_DIAGNOSE_WARNING(__m == memory_order_release || \
554 __m == memory_order_acq_rel, \
555 "memory order argument to atomic operation is invalid")
556
557#define _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__m, __f) \
558 _LIBCPP_DIAGNOSE_WARNING(__f == memory_order_release || \
559 __f == memory_order_acq_rel, \
560 "memory order argument to atomic operation is invalid")
561
Howard Hinnant71be7292010-09-27 21:17:38 +0000562_LIBCPP_BEGIN_NAMESPACE_STD
563
Eric Fiselierd4e3e5b2019-03-08 23:15:54 +0000564// Figure out what the underlying type for `memory_order` would be if it were
565// declared as an unscoped enum (accounting for -fshort-enums). Use this result
566// to pin the underlying type in C++20.
567enum __legacy_memory_order {
568 __mo_relaxed,
569 __mo_consume,
570 __mo_acquire,
571 __mo_release,
572 __mo_acq_rel,
573 __mo_seq_cst
574};
575
576typedef underlying_type<__legacy_memory_order>::type __memory_order_underlying_t;
577
Davide Italiano011f80a2019-03-05 18:40:49 +0000578#if _LIBCPP_STD_VER > 17
579
Eric Fiselierd4e3e5b2019-03-08 23:15:54 +0000580enum class memory_order : __memory_order_underlying_t {
581 relaxed = __mo_relaxed,
582 consume = __mo_consume,
583 acquire = __mo_acquire,
584 release = __mo_release,
585 acq_rel = __mo_acq_rel,
586 seq_cst = __mo_seq_cst
Davide Italiano011f80a2019-03-05 18:40:49 +0000587};
588
589inline constexpr auto memory_order_relaxed = memory_order::relaxed;
590inline constexpr auto memory_order_consume = memory_order::consume;
591inline constexpr auto memory_order_acquire = memory_order::acquire;
592inline constexpr auto memory_order_release = memory_order::release;
593inline constexpr auto memory_order_acq_rel = memory_order::acq_rel;
594inline constexpr auto memory_order_seq_cst = memory_order::seq_cst;
595
Davide Italiano011f80a2019-03-05 18:40:49 +0000596#else
597
598typedef enum memory_order {
Eric Fiselierd4e3e5b2019-03-08 23:15:54 +0000599 memory_order_relaxed = __mo_relaxed,
600 memory_order_consume = __mo_consume,
601 memory_order_acquire = __mo_acquire,
602 memory_order_release = __mo_release,
603 memory_order_acq_rel = __mo_acq_rel,
604 memory_order_seq_cst = __mo_seq_cst,
Howard Hinnantdca6e712010-09-28 17:13:38 +0000605} memory_order;
606
Davide Italiano011f80a2019-03-05 18:40:49 +0000607#endif // _LIBCPP_STD_VER > 17
608
Olivier Giroux161e6e82020-02-18 09:58:34 -0500609template <typename _Tp> _LIBCPP_INLINE_VISIBILITY
610bool __cxx_nonatomic_compare_equal(_Tp const& __lhs, _Tp const& __rhs) {
Arthur O'Dwyer22236632020-12-07 21:50:15 -0500611 return _VSTD::memcmp(&__lhs, &__rhs, sizeof(_Tp)) == 0;
Olivier Giroux161e6e82020-02-18 09:58:34 -0500612}
613
Eric Fiselier51525172019-03-08 23:30:26 +0000614static_assert((is_same<underlying_type<memory_order>::type, __memory_order_underlying_t>::value),
Eric Fiselierd4e3e5b2019-03-08 23:15:54 +0000615 "unexpected underlying type for std::memory_order");
Davide Italiano011f80a2019-03-05 18:40:49 +0000616
617#if defined(_LIBCPP_HAS_GCC_ATOMIC_IMP) || \
Arthur O'Dwyer2fc9b5d2021-04-17 17:03:20 -0400618 defined(_LIBCPP_ATOMIC_ONLY_USE_BUILTINS)
Davide Italiano011f80a2019-03-05 18:40:49 +0000619
620// [atomics.types.generic]p1 guarantees _Tp is trivially copyable. Because
621// the default operator= in an object is not volatile, a byte-by-byte copy
622// is required.
623template <typename _Tp, typename _Tv> _LIBCPP_INLINE_VISIBILITY
624typename enable_if<is_assignable<_Tp&, _Tv>::value>::type
625__cxx_atomic_assign_volatile(_Tp& __a_value, _Tv const& __val) {
626 __a_value = __val;
627}
628template <typename _Tp, typename _Tv> _LIBCPP_INLINE_VISIBILITY
629typename enable_if<is_assignable<_Tp&, _Tv>::value>::type
630__cxx_atomic_assign_volatile(_Tp volatile& __a_value, _Tv volatile const& __val) {
631 volatile char* __to = reinterpret_cast<volatile char*>(&__a_value);
632 volatile char* __end = __to + sizeof(_Tp);
633 volatile const char* __from = reinterpret_cast<volatile const char*>(&__val);
634 while (__to != __end)
635 *__to++ = *__from++;
636}
637
Davide Italiano31f218a2019-03-05 17:38:33 +0000638#endif
Louis Dionnea1ae0032019-03-04 15:26:27 +0000639
Davide Italiano011f80a2019-03-05 18:40:49 +0000640#if defined(_LIBCPP_HAS_GCC_ATOMIC_IMP)
641
642template <typename _Tp>
643struct __cxx_atomic_base_impl {
644
Eric Fiselier684aaca2015-10-14 08:36:22 +0000645 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier07b2b552016-11-18 06:42:17 +0000646#ifndef _LIBCPP_CXX03_LANG
Davide Italiano011f80a2019-03-05 18:40:49 +0000647 __cxx_atomic_base_impl() _NOEXCEPT = default;
Eric Fiselier684aaca2015-10-14 08:36:22 +0000648#else
Davide Italiano011f80a2019-03-05 18:40:49 +0000649 __cxx_atomic_base_impl() _NOEXCEPT : __a_value() {}
Eric Fiselier07b2b552016-11-18 06:42:17 +0000650#endif // _LIBCPP_CXX03_LANG
Davide Italiano011f80a2019-03-05 18:40:49 +0000651 _LIBCPP_CONSTEXPR explicit __cxx_atomic_base_impl(_Tp value) _NOEXCEPT
Eric Fiselier719e0442015-07-14 17:50:27 +0000652 : __a_value(value) {}
Marshall Clow290eb3f2015-01-11 06:15:59 +0000653 _Tp __a_value;
Dan Albert7b65ace2014-08-09 23:51:51 +0000654};
Dan Albert7b65ace2014-08-09 23:51:51 +0000655
Davide Italiano011f80a2019-03-05 18:40:49 +0000656_LIBCPP_INLINE_VISIBILITY inline _LIBCPP_CONSTEXPR int __to_gcc_order(memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000657 // Avoid switch statement to make this a constexpr.
658 return __order == memory_order_relaxed ? __ATOMIC_RELAXED:
659 (__order == memory_order_acquire ? __ATOMIC_ACQUIRE:
660 (__order == memory_order_release ? __ATOMIC_RELEASE:
661 (__order == memory_order_seq_cst ? __ATOMIC_SEQ_CST:
662 (__order == memory_order_acq_rel ? __ATOMIC_ACQ_REL:
663 __ATOMIC_CONSUME))));
664}
665
Davide Italiano011f80a2019-03-05 18:40:49 +0000666_LIBCPP_INLINE_VISIBILITY inline _LIBCPP_CONSTEXPR int __to_gcc_failure_order(memory_order __order) {
Dan Albert48815f22015-01-06 18:39:37 +0000667 // Avoid switch statement to make this a constexpr.
668 return __order == memory_order_relaxed ? __ATOMIC_RELAXED:
669 (__order == memory_order_acquire ? __ATOMIC_ACQUIRE:
670 (__order == memory_order_release ? __ATOMIC_RELAXED:
671 (__order == memory_order_seq_cst ? __ATOMIC_SEQ_CST:
672 (__order == memory_order_acq_rel ? __ATOMIC_ACQUIRE:
673 __ATOMIC_CONSUME))));
674}
675
Davide Italiano011f80a2019-03-05 18:40:49 +0000676template <typename _Tp>
677_LIBCPP_INLINE_VISIBILITY
678void __cxx_atomic_init(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __val) {
679 __cxx_atomic_assign_volatile(__a->__a_value, __val);
680}
Dan Albert7b65ace2014-08-09 23:51:51 +0000681
682template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000683_LIBCPP_INLINE_VISIBILITY
684void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp>* __a, _Tp __val) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000685 __a->__a_value = __val;
686}
687
Davide Italiano011f80a2019-03-05 18:40:49 +0000688_LIBCPP_INLINE_VISIBILITY inline
689void __cxx_atomic_thread_fence(memory_order __order) {
690 __atomic_thread_fence(__to_gcc_order(__order));
691}
692
693_LIBCPP_INLINE_VISIBILITY inline
694void __cxx_atomic_signal_fence(memory_order __order) {
695 __atomic_signal_fence(__to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000696}
697
698template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000699_LIBCPP_INLINE_VISIBILITY
700void __cxx_atomic_store(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __val,
701 memory_order __order) {
Dan Albert48815f22015-01-06 18:39:37 +0000702 __atomic_store(&__a->__a_value, &__val,
Davide Italiano011f80a2019-03-05 18:40:49 +0000703 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000704}
705
706template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000707_LIBCPP_INLINE_VISIBILITY
708void __cxx_atomic_store(__cxx_atomic_base_impl<_Tp>* __a, _Tp __val,
709 memory_order __order) {
710 __atomic_store(&__a->__a_value, &__val,
711 __to_gcc_order(__order));
712}
713
714template <typename _Tp>
715_LIBCPP_INLINE_VISIBILITY
716_Tp __cxx_atomic_load(const volatile __cxx_atomic_base_impl<_Tp>* __a,
717 memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000718 _Tp __ret;
719 __atomic_load(&__a->__a_value, &__ret,
Davide Italiano011f80a2019-03-05 18:40:49 +0000720 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000721 return __ret;
722}
723
724template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000725_LIBCPP_INLINE_VISIBILITY
726_Tp __cxx_atomic_load(const __cxx_atomic_base_impl<_Tp>* __a, memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000727 _Tp __ret;
728 __atomic_load(&__a->__a_value, &__ret,
Davide Italiano011f80a2019-03-05 18:40:49 +0000729 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000730 return __ret;
731}
732
733template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000734_LIBCPP_INLINE_VISIBILITY
735_Tp __cxx_atomic_exchange(volatile __cxx_atomic_base_impl<_Tp>* __a,
736 _Tp __value, memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000737 _Tp __ret;
738 __atomic_exchange(&__a->__a_value, &__value, &__ret,
Davide Italiano011f80a2019-03-05 18:40:49 +0000739 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000740 return __ret;
741}
742
743template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000744_LIBCPP_INLINE_VISIBILITY
745_Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp>* __a, _Tp __value,
746 memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000747 _Tp __ret;
748 __atomic_exchange(&__a->__a_value, &__value, &__ret,
Davide Italiano011f80a2019-03-05 18:40:49 +0000749 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000750 return __ret;
751}
752
753template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000754_LIBCPP_INLINE_VISIBILITY
755bool __cxx_atomic_compare_exchange_strong(
756 volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value,
JF Bastien6e412d92018-05-26 19:44:45 +0000757 memory_order __success, memory_order __failure) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000758 return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
759 false,
Davide Italiano011f80a2019-03-05 18:40:49 +0000760 __to_gcc_order(__success),
761 __to_gcc_failure_order(__failure));
Dan Albert7b65ace2014-08-09 23:51:51 +0000762}
763
764template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000765_LIBCPP_INLINE_VISIBILITY
766bool __cxx_atomic_compare_exchange_strong(
767 __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success,
JF Bastien6e412d92018-05-26 19:44:45 +0000768 memory_order __failure) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000769 return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
770 false,
Davide Italiano011f80a2019-03-05 18:40:49 +0000771 __to_gcc_order(__success),
772 __to_gcc_failure_order(__failure));
Dan Albert7b65ace2014-08-09 23:51:51 +0000773}
774
775template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000776_LIBCPP_INLINE_VISIBILITY
777bool __cxx_atomic_compare_exchange_weak(
778 volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value,
JF Bastien6e412d92018-05-26 19:44:45 +0000779 memory_order __success, memory_order __failure) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000780 return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
781 true,
Davide Italiano011f80a2019-03-05 18:40:49 +0000782 __to_gcc_order(__success),
783 __to_gcc_failure_order(__failure));
Dan Albert7b65ace2014-08-09 23:51:51 +0000784}
785
786template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000787_LIBCPP_INLINE_VISIBILITY
788bool __cxx_atomic_compare_exchange_weak(
789 __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success,
JF Bastien6e412d92018-05-26 19:44:45 +0000790 memory_order __failure) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000791 return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
792 true,
Davide Italiano011f80a2019-03-05 18:40:49 +0000793 __to_gcc_order(__success),
794 __to_gcc_failure_order(__failure));
Dan Albert7b65ace2014-08-09 23:51:51 +0000795}
796
797template <typename _Tp>
798struct __skip_amt { enum {value = 1}; };
799
800template <typename _Tp>
801struct __skip_amt<_Tp*> { enum {value = sizeof(_Tp)}; };
802
803// FIXME: Haven't figured out what the spec says about using arrays with
804// atomic_fetch_add. Force a failure rather than creating bad behavior.
805template <typename _Tp>
806struct __skip_amt<_Tp[]> { };
807template <typename _Tp, int n>
808struct __skip_amt<_Tp[n]> { };
809
810template <typename _Tp, typename _Td>
Davide Italiano011f80a2019-03-05 18:40:49 +0000811_LIBCPP_INLINE_VISIBILITY
812_Tp __cxx_atomic_fetch_add(volatile __cxx_atomic_base_impl<_Tp>* __a,
813 _Td __delta, memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000814 return __atomic_fetch_add(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
Davide Italiano011f80a2019-03-05 18:40:49 +0000815 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000816}
817
818template <typename _Tp, typename _Td>
Davide Italiano011f80a2019-03-05 18:40:49 +0000819_LIBCPP_INLINE_VISIBILITY
820_Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp>* __a, _Td __delta,
821 memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000822 return __atomic_fetch_add(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
Davide Italiano011f80a2019-03-05 18:40:49 +0000823 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000824}
825
826template <typename _Tp, typename _Td>
Davide Italiano011f80a2019-03-05 18:40:49 +0000827_LIBCPP_INLINE_VISIBILITY
828_Tp __cxx_atomic_fetch_sub(volatile __cxx_atomic_base_impl<_Tp>* __a,
829 _Td __delta, memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000830 return __atomic_fetch_sub(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
Davide Italiano011f80a2019-03-05 18:40:49 +0000831 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000832}
833
834template <typename _Tp, typename _Td>
Davide Italiano011f80a2019-03-05 18:40:49 +0000835_LIBCPP_INLINE_VISIBILITY
836_Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp>* __a, _Td __delta,
837 memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000838 return __atomic_fetch_sub(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
Davide Italiano011f80a2019-03-05 18:40:49 +0000839 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000840}
841
842template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000843_LIBCPP_INLINE_VISIBILITY
844_Tp __cxx_atomic_fetch_and(volatile __cxx_atomic_base_impl<_Tp>* __a,
845 _Tp __pattern, memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000846 return __atomic_fetch_and(&__a->__a_value, __pattern,
Davide Italiano011f80a2019-03-05 18:40:49 +0000847 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000848}
849
850template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000851_LIBCPP_INLINE_VISIBILITY
852_Tp __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp>* __a,
853 _Tp __pattern, memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000854 return __atomic_fetch_and(&__a->__a_value, __pattern,
Davide Italiano011f80a2019-03-05 18:40:49 +0000855 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000856}
857
858template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000859_LIBCPP_INLINE_VISIBILITY
860_Tp __cxx_atomic_fetch_or(volatile __cxx_atomic_base_impl<_Tp>* __a,
861 _Tp __pattern, memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000862 return __atomic_fetch_or(&__a->__a_value, __pattern,
Davide Italiano011f80a2019-03-05 18:40:49 +0000863 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000864}
865
866template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000867_LIBCPP_INLINE_VISIBILITY
868_Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern,
869 memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000870 return __atomic_fetch_or(&__a->__a_value, __pattern,
Davide Italiano011f80a2019-03-05 18:40:49 +0000871 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000872}
873
874template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000875_LIBCPP_INLINE_VISIBILITY
876_Tp __cxx_atomic_fetch_xor(volatile __cxx_atomic_base_impl<_Tp>* __a,
877 _Tp __pattern, memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000878 return __atomic_fetch_xor(&__a->__a_value, __pattern,
Davide Italiano011f80a2019-03-05 18:40:49 +0000879 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000880}
881
882template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000883_LIBCPP_INLINE_VISIBILITY
884_Tp __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern,
885 memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000886 return __atomic_fetch_xor(&__a->__a_value, __pattern,
Davide Italiano011f80a2019-03-05 18:40:49 +0000887 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000888}
Davide Italiano011f80a2019-03-05 18:40:49 +0000889
890#define __cxx_atomic_is_lock_free(__s) __atomic_is_lock_free(__s, 0)
891
892#elif defined(_LIBCPP_HAS_C_ATOMIC_IMP)
893
894template <typename _Tp>
895struct __cxx_atomic_base_impl {
896
897 _LIBCPP_INLINE_VISIBILITY
898#ifndef _LIBCPP_CXX03_LANG
899 __cxx_atomic_base_impl() _NOEXCEPT = default;
900#else
901 __cxx_atomic_base_impl() _NOEXCEPT : __a_value() {}
902#endif // _LIBCPP_CXX03_LANG
903 _LIBCPP_CONSTEXPR explicit __cxx_atomic_base_impl(_Tp value) _NOEXCEPT
904 : __a_value(value) {}
Louis Dionnefaa17452019-09-04 12:44:19 +0000905 _LIBCPP_DISABLE_EXTENSION_WARNING _Atomic(_Tp) __a_value;
Davide Italiano011f80a2019-03-05 18:40:49 +0000906};
907
908#define __cxx_atomic_is_lock_free(__s) __c11_atomic_is_lock_free(__s)
909
910_LIBCPP_INLINE_VISIBILITY inline
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000911void __cxx_atomic_thread_fence(memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +0000912 __c11_atomic_thread_fence(static_cast<__memory_order_underlying_t>(__order));
913}
914
915_LIBCPP_INLINE_VISIBILITY inline
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000916void __cxx_atomic_signal_fence(memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +0000917 __c11_atomic_signal_fence(static_cast<__memory_order_underlying_t>(__order));
918}
919
920template<class _Tp>
921_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000922void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __val) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +0000923 __c11_atomic_init(&__a->__a_value, __val);
924}
925template<class _Tp>
926_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000927void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp> * __a, _Tp __val) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +0000928 __c11_atomic_init(&__a->__a_value, __val);
929}
930
931template<class _Tp>
932_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000933void __cxx_atomic_store(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __val, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +0000934 __c11_atomic_store(&__a->__a_value, __val, static_cast<__memory_order_underlying_t>(__order));
935}
936template<class _Tp>
937_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000938void __cxx_atomic_store(__cxx_atomic_base_impl<_Tp> * __a, _Tp __val, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +0000939 __c11_atomic_store(&__a->__a_value, __val, static_cast<__memory_order_underlying_t>(__order));
940}
941
942template<class _Tp>
943_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000944_Tp __cxx_atomic_load(__cxx_atomic_base_impl<_Tp> const volatile* __a, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +0000945 using __ptr_type = typename remove_const<decltype(__a->__a_value)>::type*;
946 return __c11_atomic_load(const_cast<__ptr_type>(&__a->__a_value), static_cast<__memory_order_underlying_t>(__order));
947}
948template<class _Tp>
949_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000950_Tp __cxx_atomic_load(__cxx_atomic_base_impl<_Tp> const* __a, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +0000951 using __ptr_type = typename remove_const<decltype(__a->__a_value)>::type*;
952 return __c11_atomic_load(const_cast<__ptr_type>(&__a->__a_value), static_cast<__memory_order_underlying_t>(__order));
953}
954
955template<class _Tp>
956_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000957_Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __value, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +0000958 return __c11_atomic_exchange(&__a->__a_value, __value, static_cast<__memory_order_underlying_t>(__order));
959}
960template<class _Tp>
961_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000962_Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp> * __a, _Tp __value, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +0000963 return __c11_atomic_exchange(&__a->__a_value, __value, static_cast<__memory_order_underlying_t>(__order));
964}
965
Jordan Rupprechtd2e31a82021-06-15 07:55:23 -0700966_LIBCPP_INLINE_VISIBILITY inline _LIBCPP_CONSTEXPR memory_order __to_failure_order(memory_order __order) {
967 // Avoid switch statement to make this a constexpr.
968 return __order == memory_order_release ? memory_order_relaxed:
969 (__order == memory_order_acq_rel ? memory_order_acquire:
970 __order);
971}
972
Davide Italiano011f80a2019-03-05 18:40:49 +0000973template<class _Tp>
974_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000975bool __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 -0700976 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 +0000977}
978template<class _Tp>
979_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000980bool __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 -0700981 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 +0000982}
983
984template<class _Tp>
985_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000986bool __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 -0700987 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 +0000988}
989template<class _Tp>
990_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000991bool __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 -0700992 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 +0000993}
994
995template<class _Tp>
996_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000997_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 +0000998 return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
999}
1000template<class _Tp>
1001_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001002_Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp> * __a, _Tp __delta, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +00001003 return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
1004}
1005
1006template<class _Tp>
1007_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001008_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 +00001009 return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
1010}
1011template<class _Tp>
1012_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001013_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 +00001014 return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
1015}
1016
1017template<class _Tp>
1018_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001019_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 +00001020 return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
1021}
1022template<class _Tp>
1023_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001024_Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp> * __a, _Tp __delta, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +00001025 return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
1026}
1027template<class _Tp>
1028_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001029_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 +00001030 return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
1031}
1032template<class _Tp>
1033_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001034_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 +00001035 return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
1036}
1037
1038template<class _Tp>
1039_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001040_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 +00001041 return __c11_atomic_fetch_and(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
1042}
1043template<class _Tp>
1044_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001045_Tp __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +00001046 return __c11_atomic_fetch_and(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
1047}
1048
1049template<class _Tp>
1050_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001051_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 +00001052 return __c11_atomic_fetch_or(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
1053}
1054template<class _Tp>
1055_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001056_Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +00001057 return __c11_atomic_fetch_or(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
1058}
1059
1060template<class _Tp>
1061_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001062_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 +00001063 return __c11_atomic_fetch_xor(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
1064}
1065template<class _Tp>
1066_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001067_Tp __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +00001068 return __c11_atomic_fetch_xor(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
1069}
1070
1071#endif // _LIBCPP_HAS_GCC_ATOMIC_IMP, _LIBCPP_HAS_C_ATOMIC_IMP
Dan Albert7b65ace2014-08-09 23:51:51 +00001072
Howard Hinnantdca6e712010-09-28 17:13:38 +00001073template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001074_LIBCPP_INLINE_VISIBILITY
1075_Tp kill_dependency(_Tp __y) _NOEXCEPT
Howard Hinnantdca6e712010-09-28 17:13:38 +00001076{
1077 return __y;
1078}
Howard Hinnant71be7292010-09-27 21:17:38 +00001079
Eric Fiselierbed42df2017-04-20 23:22:46 +00001080#if defined(__CLANG_ATOMIC_BOOL_LOCK_FREE)
1081# define ATOMIC_BOOL_LOCK_FREE __CLANG_ATOMIC_BOOL_LOCK_FREE
1082# define ATOMIC_CHAR_LOCK_FREE __CLANG_ATOMIC_CHAR_LOCK_FREE
Arthur O'Dwyerafa5d5f2021-04-18 21:47:08 -04001083#ifndef _LIBCPP_HAS_NO_CHAR8_T
Marek Kurdej91bebaa2020-11-24 21:07:06 +01001084# define ATOMIC_CHAR8_T_LOCK_FREE __CLANG_ATOMIC_CHAR8_T_LOCK_FREE
1085#endif
Eric Fiselierbed42df2017-04-20 23:22:46 +00001086# define ATOMIC_CHAR16_T_LOCK_FREE __CLANG_ATOMIC_CHAR16_T_LOCK_FREE
1087# define ATOMIC_CHAR32_T_LOCK_FREE __CLANG_ATOMIC_CHAR32_T_LOCK_FREE
1088# define ATOMIC_WCHAR_T_LOCK_FREE __CLANG_ATOMIC_WCHAR_T_LOCK_FREE
1089# define ATOMIC_SHORT_LOCK_FREE __CLANG_ATOMIC_SHORT_LOCK_FREE
1090# define ATOMIC_INT_LOCK_FREE __CLANG_ATOMIC_INT_LOCK_FREE
1091# define ATOMIC_LONG_LOCK_FREE __CLANG_ATOMIC_LONG_LOCK_FREE
1092# define ATOMIC_LLONG_LOCK_FREE __CLANG_ATOMIC_LLONG_LOCK_FREE
1093# define ATOMIC_POINTER_LOCK_FREE __CLANG_ATOMIC_POINTER_LOCK_FREE
Davide Italiano011f80a2019-03-05 18:40:49 +00001094#elif defined(__GCC_ATOMIC_BOOL_LOCK_FREE)
Eric Fiselierbed42df2017-04-20 23:22:46 +00001095# define ATOMIC_BOOL_LOCK_FREE __GCC_ATOMIC_BOOL_LOCK_FREE
1096# define ATOMIC_CHAR_LOCK_FREE __GCC_ATOMIC_CHAR_LOCK_FREE
Arthur O'Dwyerafa5d5f2021-04-18 21:47:08 -04001097#ifndef _LIBCPP_HAS_NO_CHAR8_T
Marek Kurdej91bebaa2020-11-24 21:07:06 +01001098# define ATOMIC_CHAR8_T_LOCK_FREE __GCC_ATOMIC_CHAR8_T_LOCK_FREE
1099#endif
Eric Fiselierbed42df2017-04-20 23:22:46 +00001100# define ATOMIC_CHAR16_T_LOCK_FREE __GCC_ATOMIC_CHAR16_T_LOCK_FREE
1101# define ATOMIC_CHAR32_T_LOCK_FREE __GCC_ATOMIC_CHAR32_T_LOCK_FREE
1102# define ATOMIC_WCHAR_T_LOCK_FREE __GCC_ATOMIC_WCHAR_T_LOCK_FREE
1103# define ATOMIC_SHORT_LOCK_FREE __GCC_ATOMIC_SHORT_LOCK_FREE
1104# define ATOMIC_INT_LOCK_FREE __GCC_ATOMIC_INT_LOCK_FREE
1105# define ATOMIC_LONG_LOCK_FREE __GCC_ATOMIC_LONG_LOCK_FREE
1106# define ATOMIC_LLONG_LOCK_FREE __GCC_ATOMIC_LLONG_LOCK_FREE
1107# define ATOMIC_POINTER_LOCK_FREE __GCC_ATOMIC_POINTER_LOCK_FREE
1108#endif
JF Bastienfdb42c22016-03-25 15:48:21 +00001109
Davide Italiano011f80a2019-03-05 18:40:49 +00001110#ifdef _LIBCPP_ATOMIC_ONLY_USE_BUILTINS
1111
1112template<typename _Tp>
1113struct __cxx_atomic_lock_impl {
1114
1115 _LIBCPP_INLINE_VISIBILITY
1116 __cxx_atomic_lock_impl() _NOEXCEPT
1117 : __a_value(), __a_lock(0) {}
1118 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR explicit
1119 __cxx_atomic_lock_impl(_Tp value) _NOEXCEPT
1120 : __a_value(value), __a_lock(0) {}
1121
1122 _Tp __a_value;
1123 mutable __cxx_atomic_base_impl<_LIBCPP_ATOMIC_FLAG_TYPE> __a_lock;
1124
1125 _LIBCPP_INLINE_VISIBILITY void __lock() const volatile {
1126 while(1 == __cxx_atomic_exchange(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(true), memory_order_acquire))
1127 /*spin*/;
1128 }
1129 _LIBCPP_INLINE_VISIBILITY void __lock() const {
1130 while(1 == __cxx_atomic_exchange(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(true), memory_order_acquire))
1131 /*spin*/;
1132 }
1133 _LIBCPP_INLINE_VISIBILITY void __unlock() const volatile {
1134 __cxx_atomic_store(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(false), memory_order_release);
1135 }
1136 _LIBCPP_INLINE_VISIBILITY void __unlock() const {
1137 __cxx_atomic_store(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(false), memory_order_release);
1138 }
1139 _LIBCPP_INLINE_VISIBILITY _Tp __read() const volatile {
1140 __lock();
1141 _Tp __old;
1142 __cxx_atomic_assign_volatile(__old, __a_value);
1143 __unlock();
1144 return __old;
1145 }
1146 _LIBCPP_INLINE_VISIBILITY _Tp __read() const {
1147 __lock();
1148 _Tp __old = __a_value;
1149 __unlock();
1150 return __old;
1151 }
1152};
1153
1154template <typename _Tp>
1155_LIBCPP_INLINE_VISIBILITY
1156void __cxx_atomic_init(volatile __cxx_atomic_lock_impl<_Tp>* __a, _Tp __val) {
1157 __cxx_atomic_assign_volatile(__a->__a_value, __val);
1158}
1159template <typename _Tp>
1160_LIBCPP_INLINE_VISIBILITY
1161void __cxx_atomic_init(__cxx_atomic_lock_impl<_Tp>* __a, _Tp __val) {
1162 __a->__a_value = __val;
1163}
1164
1165template <typename _Tp>
1166_LIBCPP_INLINE_VISIBILITY
1167void __cxx_atomic_store(volatile __cxx_atomic_lock_impl<_Tp>* __a, _Tp __val, memory_order) {
1168 __a->__lock();
1169 __cxx_atomic_assign_volatile(__a->__a_value, __val);
1170 __a->__unlock();
1171}
1172template <typename _Tp>
1173_LIBCPP_INLINE_VISIBILITY
1174void __cxx_atomic_store(__cxx_atomic_lock_impl<_Tp>* __a, _Tp __val, memory_order) {
1175 __a->__lock();
1176 __a->__a_value = __val;
1177 __a->__unlock();
1178}
1179
1180template <typename _Tp>
1181_LIBCPP_INLINE_VISIBILITY
1182_Tp __cxx_atomic_load(const volatile __cxx_atomic_lock_impl<_Tp>* __a, memory_order) {
1183 return __a->__read();
1184}
1185template <typename _Tp>
1186_LIBCPP_INLINE_VISIBILITY
1187_Tp __cxx_atomic_load(const __cxx_atomic_lock_impl<_Tp>* __a, memory_order) {
1188 return __a->__read();
1189}
1190
1191template <typename _Tp>
1192_LIBCPP_INLINE_VISIBILITY
1193_Tp __cxx_atomic_exchange(volatile __cxx_atomic_lock_impl<_Tp>* __a, _Tp __value, memory_order) {
1194 __a->__lock();
1195 _Tp __old;
1196 __cxx_atomic_assign_volatile(__old, __a->__a_value);
1197 __cxx_atomic_assign_volatile(__a->__a_value, __value);
1198 __a->__unlock();
1199 return __old;
1200}
1201template <typename _Tp>
1202_LIBCPP_INLINE_VISIBILITY
1203_Tp __cxx_atomic_exchange(__cxx_atomic_lock_impl<_Tp>* __a, _Tp __value, memory_order) {
1204 __a->__lock();
1205 _Tp __old = __a->__a_value;
1206 __a->__a_value = __value;
1207 __a->__unlock();
1208 return __old;
1209}
1210
1211template <typename _Tp>
1212_LIBCPP_INLINE_VISIBILITY
1213bool __cxx_atomic_compare_exchange_strong(volatile __cxx_atomic_lock_impl<_Tp>* __a,
1214 _Tp* __expected, _Tp __value, memory_order, memory_order) {
Olivier Giroux161e6e82020-02-18 09:58:34 -05001215 _Tp __temp;
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07001216 __a->__lock();
Olivier Giroux161e6e82020-02-18 09:58:34 -05001217 __cxx_atomic_assign_volatile(__temp, __a->__a_value);
Arthur O'Dwyer22236632020-12-07 21:50:15 -05001218 bool __ret = (_VSTD::memcmp(&__temp, __expected, sizeof(_Tp)) == 0);
Davide Italiano011f80a2019-03-05 18:40:49 +00001219 if(__ret)
1220 __cxx_atomic_assign_volatile(__a->__a_value, __value);
1221 else
1222 __cxx_atomic_assign_volatile(*__expected, __a->__a_value);
1223 __a->__unlock();
1224 return __ret;
1225}
1226template <typename _Tp>
1227_LIBCPP_INLINE_VISIBILITY
1228bool __cxx_atomic_compare_exchange_strong(__cxx_atomic_lock_impl<_Tp>* __a,
1229 _Tp* __expected, _Tp __value, memory_order, memory_order) {
1230 __a->__lock();
Arthur O'Dwyer22236632020-12-07 21:50:15 -05001231 bool __ret = (_VSTD::memcmp(&__a->__a_value, __expected, sizeof(_Tp)) == 0);
Davide Italiano011f80a2019-03-05 18:40:49 +00001232 if(__ret)
Arthur O'Dwyer22236632020-12-07 21:50:15 -05001233 _VSTD::memcpy(&__a->__a_value, &__value, sizeof(_Tp));
Davide Italiano011f80a2019-03-05 18:40:49 +00001234 else
Arthur O'Dwyer22236632020-12-07 21:50:15 -05001235 _VSTD::memcpy(__expected, &__a->__a_value, sizeof(_Tp));
Davide Italiano011f80a2019-03-05 18:40:49 +00001236 __a->__unlock();
1237 return __ret;
1238}
1239
1240template <typename _Tp>
1241_LIBCPP_INLINE_VISIBILITY
1242bool __cxx_atomic_compare_exchange_weak(volatile __cxx_atomic_lock_impl<_Tp>* __a,
1243 _Tp* __expected, _Tp __value, memory_order, memory_order) {
Olivier Giroux161e6e82020-02-18 09:58:34 -05001244 _Tp __temp;
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07001245 __a->__lock();
Olivier Giroux161e6e82020-02-18 09:58:34 -05001246 __cxx_atomic_assign_volatile(__temp, __a->__a_value);
Arthur O'Dwyer22236632020-12-07 21:50:15 -05001247 bool __ret = (_VSTD::memcmp(&__temp, __expected, sizeof(_Tp)) == 0);
Davide Italiano011f80a2019-03-05 18:40:49 +00001248 if(__ret)
1249 __cxx_atomic_assign_volatile(__a->__a_value, __value);
1250 else
1251 __cxx_atomic_assign_volatile(*__expected, __a->__a_value);
1252 __a->__unlock();
1253 return __ret;
1254}
1255template <typename _Tp>
1256_LIBCPP_INLINE_VISIBILITY
1257bool __cxx_atomic_compare_exchange_weak(__cxx_atomic_lock_impl<_Tp>* __a,
1258 _Tp* __expected, _Tp __value, memory_order, memory_order) {
1259 __a->__lock();
Arthur O'Dwyer22236632020-12-07 21:50:15 -05001260 bool __ret = (_VSTD::memcmp(&__a->__a_value, __expected, sizeof(_Tp)) == 0);
Davide Italiano011f80a2019-03-05 18:40:49 +00001261 if(__ret)
Arthur O'Dwyer22236632020-12-07 21:50:15 -05001262 _VSTD::memcpy(&__a->__a_value, &__value, sizeof(_Tp));
Davide Italiano011f80a2019-03-05 18:40:49 +00001263 else
Arthur O'Dwyer22236632020-12-07 21:50:15 -05001264 _VSTD::memcpy(__expected, &__a->__a_value, sizeof(_Tp));
Davide Italiano011f80a2019-03-05 18:40:49 +00001265 __a->__unlock();
1266 return __ret;
1267}
1268
1269template <typename _Tp, typename _Td>
1270_LIBCPP_INLINE_VISIBILITY
1271_Tp __cxx_atomic_fetch_add(volatile __cxx_atomic_lock_impl<_Tp>* __a,
1272 _Td __delta, memory_order) {
1273 __a->__lock();
1274 _Tp __old;
1275 __cxx_atomic_assign_volatile(__old, __a->__a_value);
1276 __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old + __delta));
1277 __a->__unlock();
1278 return __old;
1279}
1280template <typename _Tp, typename _Td>
1281_LIBCPP_INLINE_VISIBILITY
1282_Tp __cxx_atomic_fetch_add(__cxx_atomic_lock_impl<_Tp>* __a,
1283 _Td __delta, memory_order) {
1284 __a->__lock();
1285 _Tp __old = __a->__a_value;
1286 __a->__a_value += __delta;
1287 __a->__unlock();
1288 return __old;
1289}
1290
1291template <typename _Tp, typename _Td>
1292_LIBCPP_INLINE_VISIBILITY
1293_Tp* __cxx_atomic_fetch_add(volatile __cxx_atomic_lock_impl<_Tp*>* __a,
1294 ptrdiff_t __delta, memory_order) {
1295 __a->__lock();
1296 _Tp* __old;
1297 __cxx_atomic_assign_volatile(__old, __a->__a_value);
1298 __cxx_atomic_assign_volatile(__a->__a_value, __old + __delta);
1299 __a->__unlock();
1300 return __old;
1301}
1302template <typename _Tp, typename _Td>
1303_LIBCPP_INLINE_VISIBILITY
1304_Tp* __cxx_atomic_fetch_add(__cxx_atomic_lock_impl<_Tp*>* __a,
1305 ptrdiff_t __delta, memory_order) {
1306 __a->__lock();
1307 _Tp* __old = __a->__a_value;
1308 __a->__a_value += __delta;
1309 __a->__unlock();
1310 return __old;
1311}
1312
1313template <typename _Tp, typename _Td>
1314_LIBCPP_INLINE_VISIBILITY
1315_Tp __cxx_atomic_fetch_sub(volatile __cxx_atomic_lock_impl<_Tp>* __a,
1316 _Td __delta, memory_order) {
1317 __a->__lock();
1318 _Tp __old;
1319 __cxx_atomic_assign_volatile(__old, __a->__a_value);
1320 __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old - __delta));
1321 __a->__unlock();
1322 return __old;
1323}
1324template <typename _Tp, typename _Td>
1325_LIBCPP_INLINE_VISIBILITY
1326_Tp __cxx_atomic_fetch_sub(__cxx_atomic_lock_impl<_Tp>* __a,
1327 _Td __delta, memory_order) {
1328 __a->__lock();
1329 _Tp __old = __a->__a_value;
1330 __a->__a_value -= __delta;
1331 __a->__unlock();
1332 return __old;
1333}
1334
1335template <typename _Tp>
1336_LIBCPP_INLINE_VISIBILITY
1337_Tp __cxx_atomic_fetch_and(volatile __cxx_atomic_lock_impl<_Tp>* __a,
1338 _Tp __pattern, memory_order) {
1339 __a->__lock();
1340 _Tp __old;
1341 __cxx_atomic_assign_volatile(__old, __a->__a_value);
1342 __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old & __pattern));
1343 __a->__unlock();
1344 return __old;
1345}
1346template <typename _Tp>
1347_LIBCPP_INLINE_VISIBILITY
1348_Tp __cxx_atomic_fetch_and(__cxx_atomic_lock_impl<_Tp>* __a,
1349 _Tp __pattern, memory_order) {
1350 __a->__lock();
1351 _Tp __old = __a->__a_value;
1352 __a->__a_value &= __pattern;
1353 __a->__unlock();
1354 return __old;
1355}
1356
1357template <typename _Tp>
1358_LIBCPP_INLINE_VISIBILITY
1359_Tp __cxx_atomic_fetch_or(volatile __cxx_atomic_lock_impl<_Tp>* __a,
1360 _Tp __pattern, memory_order) {
1361 __a->__lock();
1362 _Tp __old;
1363 __cxx_atomic_assign_volatile(__old, __a->__a_value);
1364 __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old | __pattern));
1365 __a->__unlock();
1366 return __old;
1367}
1368template <typename _Tp>
1369_LIBCPP_INLINE_VISIBILITY
1370_Tp __cxx_atomic_fetch_or(__cxx_atomic_lock_impl<_Tp>* __a,
1371 _Tp __pattern, memory_order) {
1372 __a->__lock();
1373 _Tp __old = __a->__a_value;
1374 __a->__a_value |= __pattern;
1375 __a->__unlock();
1376 return __old;
1377}
1378
1379template <typename _Tp>
1380_LIBCPP_INLINE_VISIBILITY
1381_Tp __cxx_atomic_fetch_xor(volatile __cxx_atomic_lock_impl<_Tp>* __a,
1382 _Tp __pattern, memory_order) {
1383 __a->__lock();
1384 _Tp __old;
1385 __cxx_atomic_assign_volatile(__old, __a->__a_value);
1386 __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old ^ __pattern));
1387 __a->__unlock();
1388 return __old;
1389}
1390template <typename _Tp>
1391_LIBCPP_INLINE_VISIBILITY
1392_Tp __cxx_atomic_fetch_xor(__cxx_atomic_lock_impl<_Tp>* __a,
1393 _Tp __pattern, memory_order) {
1394 __a->__lock();
1395 _Tp __old = __a->__a_value;
1396 __a->__a_value ^= __pattern;
1397 __a->__unlock();
1398 return __old;
1399}
1400
1401#ifdef __cpp_lib_atomic_is_always_lock_free
1402
1403template<typename _Tp> struct __cxx_is_always_lock_free {
1404 enum { __value = __atomic_always_lock_free(sizeof(_Tp), 0) }; };
1405
1406#else
1407
1408template<typename _Tp> struct __cxx_is_always_lock_free { enum { __value = false }; };
1409// Implementations must match the C ATOMIC_*_LOCK_FREE macro values.
1410template<> struct __cxx_is_always_lock_free<bool> { enum { __value = 2 == ATOMIC_BOOL_LOCK_FREE }; };
1411template<> struct __cxx_is_always_lock_free<char> { enum { __value = 2 == ATOMIC_CHAR_LOCK_FREE }; };
1412template<> struct __cxx_is_always_lock_free<signed char> { enum { __value = 2 == ATOMIC_CHAR_LOCK_FREE }; };
1413template<> struct __cxx_is_always_lock_free<unsigned char> { enum { __value = 2 == ATOMIC_CHAR_LOCK_FREE }; };
Arthur O'Dwyerafa5d5f2021-04-18 21:47:08 -04001414#ifndef _LIBCPP_HAS_NO_CHAR8_T
Marek Kurdej91bebaa2020-11-24 21:07:06 +01001415template<> struct __cxx_is_always_lock_free<char8_t> { enum { __value = 2 == ATOMIC_CHAR8_T_LOCK_FREE }; };
1416#endif
Davide Italiano011f80a2019-03-05 18:40:49 +00001417template<> struct __cxx_is_always_lock_free<char16_t> { enum { __value = 2 == ATOMIC_CHAR16_T_LOCK_FREE }; };
1418template<> struct __cxx_is_always_lock_free<char32_t> { enum { __value = 2 == ATOMIC_CHAR32_T_LOCK_FREE }; };
Louis Dionne89258142021-08-23 15:32:36 -04001419#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Davide Italiano011f80a2019-03-05 18:40:49 +00001420template<> struct __cxx_is_always_lock_free<wchar_t> { enum { __value = 2 == ATOMIC_WCHAR_T_LOCK_FREE }; };
Louis Dionne89258142021-08-23 15:32:36 -04001421#endif
Davide Italiano011f80a2019-03-05 18:40:49 +00001422template<> struct __cxx_is_always_lock_free<short> { enum { __value = 2 == ATOMIC_SHORT_LOCK_FREE }; };
1423template<> struct __cxx_is_always_lock_free<unsigned short> { enum { __value = 2 == ATOMIC_SHORT_LOCK_FREE }; };
1424template<> struct __cxx_is_always_lock_free<int> { enum { __value = 2 == ATOMIC_INT_LOCK_FREE }; };
1425template<> struct __cxx_is_always_lock_free<unsigned int> { enum { __value = 2 == ATOMIC_INT_LOCK_FREE }; };
1426template<> struct __cxx_is_always_lock_free<long> { enum { __value = 2 == ATOMIC_LONG_LOCK_FREE }; };
1427template<> struct __cxx_is_always_lock_free<unsigned long> { enum { __value = 2 == ATOMIC_LONG_LOCK_FREE }; };
1428template<> struct __cxx_is_always_lock_free<long long> { enum { __value = 2 == ATOMIC_LLONG_LOCK_FREE }; };
1429template<> struct __cxx_is_always_lock_free<unsigned long long> { enum { __value = 2 == ATOMIC_LLONG_LOCK_FREE }; };
1430template<typename _Tp> struct __cxx_is_always_lock_free<_Tp*> { enum { __value = 2 == ATOMIC_POINTER_LOCK_FREE }; };
1431template<> struct __cxx_is_always_lock_free<std::nullptr_t> { enum { __value = 2 == ATOMIC_POINTER_LOCK_FREE }; };
1432
1433#endif //__cpp_lib_atomic_is_always_lock_free
1434
1435template <typename _Tp,
1436 typename _Base = typename conditional<__cxx_is_always_lock_free<_Tp>::__value,
1437 __cxx_atomic_base_impl<_Tp>,
1438 __cxx_atomic_lock_impl<_Tp> >::type>
1439#else
1440template <typename _Tp,
1441 typename _Base = __cxx_atomic_base_impl<_Tp> >
1442#endif //_LIBCPP_ATOMIC_ONLY_USE_BUILTINS
1443struct __cxx_atomic_impl : public _Base {
Davide Italiano011f80a2019-03-05 18:40:49 +00001444 static_assert(is_trivially_copyable<_Tp>::value,
Louis Dionne2f766432021-11-17 11:09:55 -05001445 "std::atomic<T> requires that 'T' be a trivially copyable type");
Davide Italiano011f80a2019-03-05 18:40:49 +00001446
Nikolas Klauser6766be32021-12-07 20:29:35 +01001447 _LIBCPP_INLINE_VISIBILITY __cxx_atomic_impl() _NOEXCEPT = default;
Davide Italiano011f80a2019-03-05 18:40:49 +00001448 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR explicit __cxx_atomic_impl(_Tp value) _NOEXCEPT
1449 : _Base(value) {}
1450};
1451
Olivier Giroux161e6e82020-02-18 09:58:34 -05001452#ifdef __linux__
1453 using __cxx_contention_t = int32_t;
1454#else
1455 using __cxx_contention_t = int64_t;
1456#endif //__linux__
1457
Olivier Giroux161e6e82020-02-18 09:58:34 -05001458using __cxx_atomic_contention_t = __cxx_atomic_impl<__cxx_contention_t>;
1459
Louis Dionneaf2d2a82021-11-17 10:59:31 -05001460#if defined(_LIBCPP_HAS_NO_THREADS)
1461# define _LIBCPP_HAS_NO_PLATFORM_WAIT
1462#endif
1463
1464// TODO:
1465// _LIBCPP_HAS_NO_PLATFORM_WAIT is currently a "dead" macro, in the sense that
1466// it is not tied anywhere into the build system or even documented. We should
1467// clean it up because it is technically never defined except when threads are
1468// disabled. We should clean it up in its own changeset in case we break "bad"
1469// users.
Olivier Giroux161e6e82020-02-18 09:58:34 -05001470#ifndef _LIBCPP_HAS_NO_PLATFORM_WAIT
1471
Louis Dionne48a828b2020-02-24 10:08:41 -05001472_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_one(void const volatile*);
1473_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_all(void const volatile*);
1474_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t __libcpp_atomic_monitor(void const volatile*);
1475_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __libcpp_atomic_wait(void const volatile*, __cxx_contention_t);
Olivier Giroux161e6e82020-02-18 09:58:34 -05001476
Louis Dionne48a828b2020-02-24 10:08:41 -05001477_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_one(__cxx_atomic_contention_t const volatile*);
1478_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_all(__cxx_atomic_contention_t const volatile*);
1479_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t __libcpp_atomic_monitor(__cxx_atomic_contention_t const volatile*);
1480_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 -05001481
1482template <class _Atp, class _Fn>
Louis Dionne08cd5cb2020-02-24 11:39:48 -05001483struct __libcpp_atomic_wait_backoff_impl {
1484 _Atp* __a;
1485 _Fn __test_fn;
Louis Dionne3dde4ab2020-02-24 10:09:29 -05001486 _LIBCPP_AVAILABILITY_SYNC
Louis Dionne08cd5cb2020-02-24 11:39:48 -05001487 _LIBCPP_INLINE_VISIBILITY bool operator()(chrono::nanoseconds __elapsed) const
1488 {
Olivier Giroux161e6e82020-02-18 09:58:34 -05001489 if(__elapsed > chrono::microseconds(64))
1490 {
1491 auto const __monitor = __libcpp_atomic_monitor(__a);
1492 if(__test_fn())
1493 return true;
1494 __libcpp_atomic_wait(__a, __monitor);
1495 }
1496 else if(__elapsed > chrono::microseconds(4))
1497 __libcpp_thread_yield();
1498 else
Marek Kurdejc79652f2020-11-15 16:17:52 +01001499 {} // poll
Olivier Giroux161e6e82020-02-18 09:58:34 -05001500 return false;
Louis Dionne08cd5cb2020-02-24 11:39:48 -05001501 }
1502};
1503
1504template <class _Atp, class _Fn>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05001505_LIBCPP_AVAILABILITY_SYNC
Louis Dionne08cd5cb2020-02-24 11:39:48 -05001506_LIBCPP_INLINE_VISIBILITY bool __cxx_atomic_wait(_Atp* __a, _Fn && __test_fn)
1507{
1508 __libcpp_atomic_wait_backoff_impl<_Atp, typename decay<_Fn>::type> __backoff_fn = {__a, __test_fn};
1509 return __libcpp_thread_poll_with_backoff(__test_fn, __backoff_fn);
Olivier Giroux161e6e82020-02-18 09:58:34 -05001510}
1511
1512#else // _LIBCPP_HAS_NO_PLATFORM_WAIT
1513
1514template <class _Tp>
1515_LIBCPP_INLINE_VISIBILITY void __cxx_atomic_notify_all(__cxx_atomic_impl<_Tp> const volatile*) { }
1516template <class _Tp>
1517_LIBCPP_INLINE_VISIBILITY void __cxx_atomic_notify_one(__cxx_atomic_impl<_Tp> const volatile*) { }
1518template <class _Atp, class _Fn>
1519_LIBCPP_INLINE_VISIBILITY bool __cxx_atomic_wait(_Atp*, _Fn && __test_fn)
1520{
Louis Dionneaf2d2a82021-11-17 10:59:31 -05001521#if defined(_LIBCPP_HAS_NO_THREADS)
1522 using _Policy = __spinning_backoff_policy;
1523#else
1524 using _Policy = __libcpp_timed_backoff_policy;
1525#endif
1526 return __libcpp_thread_poll_with_backoff(__test_fn, _Policy());
Olivier Giroux161e6e82020-02-18 09:58:34 -05001527}
1528
1529#endif // _LIBCPP_HAS_NO_PLATFORM_WAIT
1530
1531template <class _Atp, class _Tp>
Louis Dionne08cd5cb2020-02-24 11:39:48 -05001532struct __cxx_atomic_wait_test_fn_impl {
1533 _Atp* __a;
1534 _Tp __val;
1535 memory_order __order;
1536 _LIBCPP_INLINE_VISIBILITY bool operator()() const
1537 {
1538 return !__cxx_nonatomic_compare_equal(__cxx_atomic_load(__a, __order), __val);
1539 }
1540};
1541
1542template <class _Atp, class _Tp>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05001543_LIBCPP_AVAILABILITY_SYNC
Olivier Giroux161e6e82020-02-18 09:58:34 -05001544_LIBCPP_INLINE_VISIBILITY bool __cxx_atomic_wait(_Atp* __a, _Tp const __val, memory_order __order)
1545{
Louis Dionne08cd5cb2020-02-24 11:39:48 -05001546 __cxx_atomic_wait_test_fn_impl<_Atp, _Tp> __test_fn = {__a, __val, __order};
Olivier Giroux161e6e82020-02-18 09:58:34 -05001547 return __cxx_atomic_wait(__a, __test_fn);
1548}
1549
Howard Hinnant138f5922010-12-07 20:46:14 +00001550// general atomic<T>
1551
1552template <class _Tp, bool = is_integral<_Tp>::value && !is_same<_Tp, bool>::value>
1553struct __atomic_base // false
1554{
Davide Italiano011f80a2019-03-05 18:40:49 +00001555 mutable __cxx_atomic_impl<_Tp> __a_;
Howard Hinnant138f5922010-12-07 20:46:14 +00001556
JF Bastienfdb42c22016-03-25 15:48:21 +00001557#if defined(__cpp_lib_atomic_is_always_lock_free)
1558 static _LIBCPP_CONSTEXPR bool is_always_lock_free = __atomic_always_lock_free(sizeof(__a_), 0);
1559#endif
1560
Howard Hinnant138f5922010-12-07 20:46:14 +00001561 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001562 bool is_lock_free() const volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001563 {return __cxx_atomic_is_lock_free(sizeof(_Tp));}
Howard Hinnant138f5922010-12-07 20:46:14 +00001564 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001565 bool is_lock_free() const _NOEXCEPT
Eric Fiselier3fd22c22015-06-13 00:23:07 +00001566 {return static_cast<__atomic_base const volatile*>(this)->is_lock_free();}
Howard Hinnant138f5922010-12-07 20:46:14 +00001567 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001568 void store(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001569 _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
Davide Italiano011f80a2019-03-05 18:40:49 +00001570 {__cxx_atomic_store(&__a_, __d, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001571 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001572 void store(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001573 _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
Davide Italiano011f80a2019-03-05 18:40:49 +00001574 {__cxx_atomic_store(&__a_, __d, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001575 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001576 _Tp load(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001577 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
Davide Italiano011f80a2019-03-05 18:40:49 +00001578 {return __cxx_atomic_load(&__a_, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001579 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001580 _Tp load(memory_order __m = memory_order_seq_cst) const _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001581 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
Davide Italiano011f80a2019-03-05 18:40:49 +00001582 {return __cxx_atomic_load(&__a_, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001583 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001584 operator _Tp() const volatile _NOEXCEPT {return load();}
Howard Hinnant138f5922010-12-07 20:46:14 +00001585 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001586 operator _Tp() const _NOEXCEPT {return load();}
Howard Hinnant138f5922010-12-07 20:46:14 +00001587 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001588 _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001589 {return __cxx_atomic_exchange(&__a_, __d, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001590 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001591 _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001592 {return __cxx_atomic_exchange(&__a_, __d, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001593 _LIBCPP_INLINE_VISIBILITY
1594 bool compare_exchange_weak(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001595 memory_order __s, memory_order __f) volatile _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001596 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Davide Italiano011f80a2019-03-05 18:40:49 +00001597 {return __cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001598 _LIBCPP_INLINE_VISIBILITY
1599 bool compare_exchange_weak(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001600 memory_order __s, memory_order __f) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001601 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Davide Italiano011f80a2019-03-05 18:40:49 +00001602 {return __cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001603 _LIBCPP_INLINE_VISIBILITY
1604 bool compare_exchange_strong(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001605 memory_order __s, memory_order __f) volatile _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001606 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Davide Italiano011f80a2019-03-05 18:40:49 +00001607 {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001608 _LIBCPP_INLINE_VISIBILITY
1609 bool compare_exchange_strong(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001610 memory_order __s, memory_order __f) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001611 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Davide Italiano011f80a2019-03-05 18:40:49 +00001612 {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001613 _LIBCPP_INLINE_VISIBILITY
1614 bool compare_exchange_weak(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001615 memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001616 {return __cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001617 _LIBCPP_INLINE_VISIBILITY
1618 bool compare_exchange_weak(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001619 memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001620 {return __cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001621 _LIBCPP_INLINE_VISIBILITY
1622 bool compare_exchange_strong(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001623 memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001624 {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001625 _LIBCPP_INLINE_VISIBILITY
1626 bool compare_exchange_strong(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001627 memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001628 {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001629
Louis Dionne3dde4ab2020-02-24 10:09:29 -05001630 _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 -05001631 {__cxx_atomic_wait(&__a_, __v, __m);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05001632 _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 -05001633 {__cxx_atomic_wait(&__a_, __v, __m);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05001634 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_one() volatile _NOEXCEPT
Olivier Giroux161e6e82020-02-18 09:58:34 -05001635 {__cxx_atomic_notify_one(&__a_);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05001636 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_one() _NOEXCEPT
Olivier Giroux161e6e82020-02-18 09:58:34 -05001637 {__cxx_atomic_notify_one(&__a_);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05001638 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_all() volatile _NOEXCEPT
Olivier Giroux161e6e82020-02-18 09:58:34 -05001639 {__cxx_atomic_notify_all(&__a_);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05001640 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_all() _NOEXCEPT
Olivier Giroux161e6e82020-02-18 09:58:34 -05001641 {__cxx_atomic_notify_all(&__a_);}
1642
Raul Tambre4e0e88f2021-06-06 19:02:20 +03001643#if _LIBCPP_STD_VER > 17
1644 _LIBCPP_INLINE_VISIBILITY constexpr
1645 __atomic_base() noexcept(is_nothrow_default_constructible_v<_Tp>) : __a_(_Tp()) {}
1646#else
Howard Hinnant138f5922010-12-07 20:46:14 +00001647 _LIBCPP_INLINE_VISIBILITY
Nikolas Klauser6766be32021-12-07 20:29:35 +01001648 __atomic_base() _NOEXCEPT = default;
Raul Tambre4e0e88f2021-06-06 19:02:20 +03001649#endif
Howard Hinnant3d284222013-05-02 20:18:43 +00001650
Davide Italiano011f80a2019-03-05 18:40:49 +00001651 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
1652 __atomic_base(_Tp __d) _NOEXCEPT : __a_(__d) {}
1653
Eric Fiselier2d8515f2017-01-06 20:58:25 +00001654#ifndef _LIBCPP_CXX03_LANG
Howard Hinnant138f5922010-12-07 20:46:14 +00001655 __atomic_base(const __atomic_base&) = delete;
Eric Fiselier2d8515f2017-01-06 20:58:25 +00001656#else
Howard Hinnant6ac60f82010-12-08 17:20:28 +00001657private:
Olivier Giroux161e6e82020-02-18 09:58:34 -05001658 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant6ac60f82010-12-08 17:20:28 +00001659 __atomic_base(const __atomic_base&);
Eric Fiselier2d8515f2017-01-06 20:58:25 +00001660#endif
Howard Hinnant138f5922010-12-07 20:46:14 +00001661};
1662
JF Bastienfdb42c22016-03-25 15:48:21 +00001663#if defined(__cpp_lib_atomic_is_always_lock_free)
1664template <class _Tp, bool __b>
1665_LIBCPP_CONSTEXPR bool __atomic_base<_Tp, __b>::is_always_lock_free;
1666#endif
1667
Howard Hinnant138f5922010-12-07 20:46:14 +00001668// atomic<Integral>
1669
1670template <class _Tp>
1671struct __atomic_base<_Tp, true>
1672 : public __atomic_base<_Tp, false>
1673{
1674 typedef __atomic_base<_Tp, false> __base;
Raul Tambre4e0e88f2021-06-06 19:02:20 +03001675
1676 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
Nikolas Klauser6766be32021-12-07 20:29:35 +01001677 __atomic_base() _NOEXCEPT = default;
Raul Tambre4e0e88f2021-06-06 19:02:20 +03001678
Howard Hinnant138f5922010-12-07 20:46:14 +00001679 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001680 _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __base(__d) {}
Howard Hinnant138f5922010-12-07 20:46:14 +00001681
1682 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001683 _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001684 {return __cxx_atomic_fetch_add(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001685 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001686 _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001687 {return __cxx_atomic_fetch_add(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001688 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001689 _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001690 {return __cxx_atomic_fetch_sub(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001691 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001692 _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001693 {return __cxx_atomic_fetch_sub(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001694 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001695 _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001696 {return __cxx_atomic_fetch_and(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001697 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001698 _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001699 {return __cxx_atomic_fetch_and(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001700 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001701 _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001702 {return __cxx_atomic_fetch_or(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001703 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001704 _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001705 {return __cxx_atomic_fetch_or(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001706 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001707 _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001708 {return __cxx_atomic_fetch_xor(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001709 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001710 _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001711 {return __cxx_atomic_fetch_xor(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001712
1713 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001714 _Tp operator++(int) volatile _NOEXCEPT {return fetch_add(_Tp(1));}
Howard Hinnant138f5922010-12-07 20:46:14 +00001715 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001716 _Tp operator++(int) _NOEXCEPT {return fetch_add(_Tp(1));}
Howard Hinnant138f5922010-12-07 20:46:14 +00001717 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001718 _Tp operator--(int) volatile _NOEXCEPT {return fetch_sub(_Tp(1));}
Howard Hinnant138f5922010-12-07 20:46:14 +00001719 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001720 _Tp operator--(int) _NOEXCEPT {return fetch_sub(_Tp(1));}
Howard Hinnant138f5922010-12-07 20:46:14 +00001721 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001722 _Tp operator++() volatile _NOEXCEPT {return fetch_add(_Tp(1)) + _Tp(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001723 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001724 _Tp operator++() _NOEXCEPT {return fetch_add(_Tp(1)) + _Tp(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001725 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001726 _Tp operator--() volatile _NOEXCEPT {return fetch_sub(_Tp(1)) - _Tp(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001727 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001728 _Tp operator--() _NOEXCEPT {return fetch_sub(_Tp(1)) - _Tp(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001729 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001730 _Tp operator+=(_Tp __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001731 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001732 _Tp operator+=(_Tp __op) _NOEXCEPT {return fetch_add(__op) + __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001733 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001734 _Tp operator-=(_Tp __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001735 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001736 _Tp operator-=(_Tp __op) _NOEXCEPT {return fetch_sub(__op) - __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001737 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001738 _Tp operator&=(_Tp __op) volatile _NOEXCEPT {return fetch_and(__op) & __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001739 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001740 _Tp operator&=(_Tp __op) _NOEXCEPT {return fetch_and(__op) & __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001741 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001742 _Tp operator|=(_Tp __op) volatile _NOEXCEPT {return fetch_or(__op) | __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001743 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001744 _Tp operator|=(_Tp __op) _NOEXCEPT {return fetch_or(__op) | __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001745 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001746 _Tp operator^=(_Tp __op) volatile _NOEXCEPT {return fetch_xor(__op) ^ __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001747 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001748 _Tp operator^=(_Tp __op) _NOEXCEPT {return fetch_xor(__op) ^ __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001749};
1750
1751// atomic<T>
1752
1753template <class _Tp>
1754struct atomic
1755 : public __atomic_base<_Tp>
1756{
1757 typedef __atomic_base<_Tp> __base;
Olivier Giroux161e6e82020-02-18 09:58:34 -05001758 typedef _Tp value_type;
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07001759 typedef value_type difference_type;
Raul Tambre4e0e88f2021-06-06 19:02:20 +03001760
1761#if _LIBCPP_STD_VER > 17
1762 _LIBCPP_INLINE_VISIBILITY
1763 atomic() = default;
1764#else
Howard Hinnant138f5922010-12-07 20:46:14 +00001765 _LIBCPP_INLINE_VISIBILITY
Nikolas Klauser6766be32021-12-07 20:29:35 +01001766 atomic() _NOEXCEPT = default;
Raul Tambre4e0e88f2021-06-06 19:02:20 +03001767#endif
1768
Howard Hinnant138f5922010-12-07 20:46:14 +00001769 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001770 _LIBCPP_CONSTEXPR atomic(_Tp __d) _NOEXCEPT : __base(__d) {}
Howard Hinnant96e4cd62010-12-07 23:24:41 +00001771
1772 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001773 _Tp operator=(_Tp __d) volatile _NOEXCEPT
Howard Hinnant96e4cd62010-12-07 23:24:41 +00001774 {__base::store(__d); return __d;}
1775 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001776 _Tp operator=(_Tp __d) _NOEXCEPT
Howard Hinnant96e4cd62010-12-07 23:24:41 +00001777 {__base::store(__d); return __d;}
Ruslan Arutyunyan033093f2021-02-01 10:12:09 -05001778
1779 atomic& operator=(const atomic&) = delete;
1780 atomic& operator=(const atomic&) volatile = delete;
Howard Hinnant138f5922010-12-07 20:46:14 +00001781};
1782
1783// atomic<T*>
1784
1785template <class _Tp>
1786struct atomic<_Tp*>
1787 : public __atomic_base<_Tp*>
1788{
Howard Hinnant96e4cd62010-12-07 23:24:41 +00001789 typedef __atomic_base<_Tp*> __base;
Olivier Giroux161e6e82020-02-18 09:58:34 -05001790 typedef _Tp* value_type;
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07001791 typedef ptrdiff_t difference_type;
Raul Tambre4e0e88f2021-06-06 19:02:20 +03001792
Howard Hinnant138f5922010-12-07 20:46:14 +00001793 _LIBCPP_INLINE_VISIBILITY
Nikolas Klauser6766be32021-12-07 20:29:35 +01001794 atomic() _NOEXCEPT = default;
Raul Tambre4e0e88f2021-06-06 19:02:20 +03001795
Howard Hinnant138f5922010-12-07 20:46:14 +00001796 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001797 _LIBCPP_CONSTEXPR atomic(_Tp* __d) _NOEXCEPT : __base(__d) {}
Howard Hinnant138f5922010-12-07 20:46:14 +00001798
1799 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001800 _Tp* operator=(_Tp* __d) volatile _NOEXCEPT
Howard Hinnant96e4cd62010-12-07 23:24:41 +00001801 {__base::store(__d); return __d;}
1802 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001803 _Tp* operator=(_Tp* __d) _NOEXCEPT
Howard Hinnant96e4cd62010-12-07 23:24:41 +00001804 {__base::store(__d); return __d;}
1805
1806 _LIBCPP_INLINE_VISIBILITY
Mark de Wever494905b2021-06-09 20:26:34 +02001807 _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
1808 // __atomic_fetch_add accepts function pointers, guard against them.
1809 static_assert(!is_function<typename remove_pointer<_Tp>::type>::value, "Pointer to function isn't allowed");
1810 return __cxx_atomic_fetch_add(&this->__a_, __op, __m);
1811 }
1812
Howard Hinnant138f5922010-12-07 20:46:14 +00001813 _LIBCPP_INLINE_VISIBILITY
Mark de Wever494905b2021-06-09 20:26:34 +02001814 _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
1815 // __atomic_fetch_add accepts function pointers, guard against them.
1816 static_assert(!is_function<typename remove_pointer<_Tp>::type>::value, "Pointer to function isn't allowed");
1817 return __cxx_atomic_fetch_add(&this->__a_, __op, __m);
1818 }
1819
Howard Hinnant138f5922010-12-07 20:46:14 +00001820 _LIBCPP_INLINE_VISIBILITY
Mark de Wever494905b2021-06-09 20:26:34 +02001821 _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
1822 // __atomic_fetch_add accepts function pointers, guard against them.
1823 static_assert(!is_function<typename remove_pointer<_Tp>::type>::value, "Pointer to function isn't allowed");
1824 return __cxx_atomic_fetch_sub(&this->__a_, __op, __m);
1825 }
1826
Howard Hinnant138f5922010-12-07 20:46:14 +00001827 _LIBCPP_INLINE_VISIBILITY
Mark de Wever494905b2021-06-09 20:26:34 +02001828 _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
1829 // __atomic_fetch_add accepts function pointers, guard against them.
1830 static_assert(!is_function<typename remove_pointer<_Tp>::type>::value, "Pointer to function isn't allowed");
1831 return __cxx_atomic_fetch_sub(&this->__a_, __op, __m);
1832 }
Howard Hinnant138f5922010-12-07 20:46:14 +00001833
1834 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001835 _Tp* operator++(int) volatile _NOEXCEPT {return fetch_add(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001836 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001837 _Tp* operator++(int) _NOEXCEPT {return fetch_add(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001838 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001839 _Tp* operator--(int) volatile _NOEXCEPT {return fetch_sub(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001840 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001841 _Tp* operator--(int) _NOEXCEPT {return fetch_sub(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001842 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001843 _Tp* operator++() volatile _NOEXCEPT {return fetch_add(1) + 1;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001844 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001845 _Tp* operator++() _NOEXCEPT {return fetch_add(1) + 1;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001846 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001847 _Tp* operator--() volatile _NOEXCEPT {return fetch_sub(1) - 1;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001848 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001849 _Tp* operator--() _NOEXCEPT {return fetch_sub(1) - 1;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001850 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001851 _Tp* operator+=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001852 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001853 _Tp* operator+=(ptrdiff_t __op) _NOEXCEPT {return fetch_add(__op) + __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001854 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001855 _Tp* operator-=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001856 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001857 _Tp* operator-=(ptrdiff_t __op) _NOEXCEPT {return fetch_sub(__op) - __op;}
Ruslan Arutyunyan033093f2021-02-01 10:12:09 -05001858
1859 atomic& operator=(const atomic&) = delete;
1860 atomic& operator=(const atomic&) volatile = delete;
Howard Hinnant138f5922010-12-07 20:46:14 +00001861};
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001862
1863// atomic_is_lock_free
1864
1865template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001866_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001867bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00001868atomic_is_lock_free(const volatile atomic<_Tp>* __o) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001869{
Howard Hinnant138f5922010-12-07 20:46:14 +00001870 return __o->is_lock_free();
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001871}
1872
1873template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001874_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001875bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00001876atomic_is_lock_free(const atomic<_Tp>* __o) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001877{
Howard Hinnant138f5922010-12-07 20:46:14 +00001878 return __o->is_lock_free();
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001879}
1880
1881// atomic_init
1882
1883template <class _Tp>
Raul Tambre4e0e88f2021-06-06 19:02:20 +03001884_LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001885void
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07001886atomic_init(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001887{
Davide Italiano011f80a2019-03-05 18:40:49 +00001888 __cxx_atomic_init(&__o->__a_, __d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001889}
1890
1891template <class _Tp>
Raul Tambre4e0e88f2021-06-06 19:02:20 +03001892_LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001893void
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07001894atomic_init(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001895{
Davide Italiano011f80a2019-03-05 18:40:49 +00001896 __cxx_atomic_init(&__o->__a_, __d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001897}
1898
1899// atomic_store
1900
1901template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001902_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001903void
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07001904atomic_store(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001905{
Howard Hinnant138f5922010-12-07 20:46:14 +00001906 __o->store(__d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001907}
1908
1909template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001910_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001911void
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07001912atomic_store(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001913{
Howard Hinnant138f5922010-12-07 20:46:14 +00001914 __o->store(__d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001915}
1916
1917// atomic_store_explicit
1918
1919template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001920_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001921void
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07001922atomic_store_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001923 _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001924{
Howard Hinnant138f5922010-12-07 20:46:14 +00001925 __o->store(__d, __m);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001926}
1927
1928template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001929_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001930void
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07001931atomic_store_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001932 _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001933{
Howard Hinnant138f5922010-12-07 20:46:14 +00001934 __o->store(__d, __m);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001935}
1936
1937// atomic_load
1938
1939template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001940_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001941_Tp
Howard Hinnanteee2c142012-04-11 20:14:21 +00001942atomic_load(const volatile atomic<_Tp>* __o) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001943{
Howard Hinnant138f5922010-12-07 20:46:14 +00001944 return __o->load();
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001945}
1946
1947template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001948_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001949_Tp
Howard Hinnanteee2c142012-04-11 20:14:21 +00001950atomic_load(const atomic<_Tp>* __o) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001951{
Howard Hinnant138f5922010-12-07 20:46:14 +00001952 return __o->load();
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001953}
1954
1955// atomic_load_explicit
1956
1957template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001958_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001959_Tp
Howard Hinnanteee2c142012-04-11 20:14:21 +00001960atomic_load_explicit(const volatile atomic<_Tp>* __o, memory_order __m) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001961 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001962{
Howard Hinnant138f5922010-12-07 20:46:14 +00001963 return __o->load(__m);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001964}
1965
1966template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001967_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001968_Tp
Howard Hinnanteee2c142012-04-11 20:14:21 +00001969atomic_load_explicit(const atomic<_Tp>* __o, memory_order __m) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001970 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001971{
Howard Hinnant138f5922010-12-07 20:46:14 +00001972 return __o->load(__m);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001973}
1974
1975// atomic_exchange
1976
1977template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001978_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001979_Tp
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07001980atomic_exchange(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001981{
Howard Hinnant138f5922010-12-07 20:46:14 +00001982 return __o->exchange(__d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001983}
1984
1985template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001986_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001987_Tp
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07001988atomic_exchange(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001989{
Howard Hinnant138f5922010-12-07 20:46:14 +00001990 return __o->exchange(__d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001991}
1992
1993// atomic_exchange_explicit
1994
1995template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001996_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001997_Tp
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07001998atomic_exchange_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001999{
Howard Hinnant138f5922010-12-07 20:46:14 +00002000 return __o->exchange(__d, __m);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002001}
2002
2003template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002004_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002005_Tp
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002006atomic_exchange_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002007{
Howard Hinnant138f5922010-12-07 20:46:14 +00002008 return __o->exchange(__d, __m);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002009}
2010
2011// atomic_compare_exchange_weak
2012
2013template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002014_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002015bool
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002016atomic_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 +00002017{
Howard Hinnant138f5922010-12-07 20:46:14 +00002018 return __o->compare_exchange_weak(*__e, __d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002019}
2020
2021template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002022_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002023bool
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002024atomic_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 +00002025{
Howard Hinnant138f5922010-12-07 20:46:14 +00002026 return __o->compare_exchange_weak(*__e, __d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002027}
2028
2029// atomic_compare_exchange_strong
2030
2031template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002032_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002033bool
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002034atomic_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 +00002035{
Howard Hinnant138f5922010-12-07 20:46:14 +00002036 return __o->compare_exchange_strong(*__e, __d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002037}
2038
2039template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002040_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002041bool
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002042atomic_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 +00002043{
Howard Hinnant138f5922010-12-07 20:46:14 +00002044 return __o->compare_exchange_strong(*__e, __d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002045}
2046
2047// atomic_compare_exchange_weak_explicit
2048
2049template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002050_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002051bool
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002052atomic_compare_exchange_weak_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e,
2053 typename atomic<_Tp>::value_type __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00002054 memory_order __s, memory_order __f) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00002055 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002056{
Howard Hinnant138f5922010-12-07 20:46:14 +00002057 return __o->compare_exchange_weak(*__e, __d, __s, __f);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002058}
2059
2060template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002061_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002062bool
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002063atomic_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 +00002064 memory_order __s, memory_order __f) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00002065 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002066{
Howard Hinnant138f5922010-12-07 20:46:14 +00002067 return __o->compare_exchange_weak(*__e, __d, __s, __f);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002068}
2069
2070// atomic_compare_exchange_strong_explicit
2071
2072template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002073_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002074bool
2075atomic_compare_exchange_strong_explicit(volatile atomic<_Tp>* __o,
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002076 typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00002077 memory_order __s, memory_order __f) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00002078 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002079{
Howard Hinnant138f5922010-12-07 20:46:14 +00002080 return __o->compare_exchange_strong(*__e, __d, __s, __f);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002081}
2082
2083template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002084_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002085bool
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002086atomic_compare_exchange_strong_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e,
2087 typename atomic<_Tp>::value_type __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00002088 memory_order __s, memory_order __f) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00002089 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002090{
Howard Hinnant138f5922010-12-07 20:46:14 +00002091 return __o->compare_exchange_strong(*__e, __d, __s, __f);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002092}
2093
Olivier Giroux161e6e82020-02-18 09:58:34 -05002094// atomic_wait
2095
2096template <class _Tp>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002097_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002098void atomic_wait(const volatile atomic<_Tp>* __o,
2099 typename atomic<_Tp>::value_type __v) _NOEXCEPT
2100{
2101 return __o->wait(__v);
2102}
2103
2104template <class _Tp>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002105_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002106void atomic_wait(const atomic<_Tp>* __o,
2107 typename atomic<_Tp>::value_type __v) _NOEXCEPT
2108{
2109 return __o->wait(__v);
2110}
2111
2112// atomic_wait_explicit
2113
2114template <class _Tp>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002115_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002116void atomic_wait_explicit(const volatile atomic<_Tp>* __o,
2117 typename atomic<_Tp>::value_type __v,
2118 memory_order __m) _NOEXCEPT
2119 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
2120{
2121 return __o->wait(__v, __m);
2122}
2123
2124template <class _Tp>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002125_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002126void atomic_wait_explicit(const atomic<_Tp>* __o,
2127 typename atomic<_Tp>::value_type __v,
2128 memory_order __m) _NOEXCEPT
2129 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
2130{
2131 return __o->wait(__v, __m);
2132}
2133
2134// atomic_notify_one
2135
2136template <class _Tp>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002137_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002138void atomic_notify_one(volatile atomic<_Tp>* __o) _NOEXCEPT
2139{
2140 __o->notify_one();
2141}
2142template <class _Tp>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002143_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002144void atomic_notify_one(atomic<_Tp>* __o) _NOEXCEPT
2145{
2146 __o->notify_one();
2147}
2148
2149// atomic_notify_one
2150
2151template <class _Tp>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002152_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002153void atomic_notify_all(volatile atomic<_Tp>* __o) _NOEXCEPT
2154{
2155 __o->notify_all();
2156}
2157template <class _Tp>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002158_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002159void atomic_notify_all(atomic<_Tp>* __o) _NOEXCEPT
2160{
2161 __o->notify_all();
2162}
2163
Howard Hinnant138f5922010-12-07 20:46:14 +00002164// atomic_fetch_add
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002165
2166template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002167_LIBCPP_INLINE_VISIBILITY
Mark de Wever494905b2021-06-09 20:26:34 +02002168_Tp
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002169atomic_fetch_add(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002170{
Howard Hinnant138f5922010-12-07 20:46:14 +00002171 return __o->fetch_add(__op);
2172}
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002173
Howard Hinnant138f5922010-12-07 20:46:14 +00002174template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002175_LIBCPP_INLINE_VISIBILITY
Mark de Wever494905b2021-06-09 20:26:34 +02002176_Tp
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002177atomic_fetch_add(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002178{
2179 return __o->fetch_add(__op);
2180}
2181
2182// atomic_fetch_add_explicit
2183
2184template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002185_LIBCPP_INLINE_VISIBILITY
Mark de Wever494905b2021-06-09 20:26:34 +02002186_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 +00002187{
2188 return __o->fetch_add(__op, __m);
2189}
2190
2191template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002192_LIBCPP_INLINE_VISIBILITY
Mark de Wever494905b2021-06-09 20:26:34 +02002193_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 -07002194{
2195 return __o->fetch_add(__op, __m);
2196}
2197
Howard Hinnant138f5922010-12-07 20:46:14 +00002198// atomic_fetch_sub
2199
2200template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002201_LIBCPP_INLINE_VISIBILITY
Mark de Wever494905b2021-06-09 20:26:34 +02002202_Tp atomic_fetch_sub(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002203{
2204 return __o->fetch_sub(__op);
2205}
2206
2207template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002208_LIBCPP_INLINE_VISIBILITY
Mark de Wever494905b2021-06-09 20:26:34 +02002209_Tp atomic_fetch_sub(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT
Olivier Girouxdf485172020-09-11 12:13:35 -07002210{
2211 return __o->fetch_sub(__op);
2212}
2213
Howard Hinnant138f5922010-12-07 20:46:14 +00002214// atomic_fetch_sub_explicit
2215
2216template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002217_LIBCPP_INLINE_VISIBILITY
Mark de Wever494905b2021-06-09 20:26:34 +02002218_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 +00002219{
2220 return __o->fetch_sub(__op, __m);
2221}
2222
2223template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002224_LIBCPP_INLINE_VISIBILITY
Mark de Wever494905b2021-06-09 20:26:34 +02002225_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 -07002226{
2227 return __o->fetch_sub(__op, __m);
2228}
2229
Howard Hinnant138f5922010-12-07 20:46:14 +00002230// atomic_fetch_and
2231
2232template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002233_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002234typename enable_if
2235<
2236 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2237 _Tp
2238>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002239atomic_fetch_and(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002240{
2241 return __o->fetch_and(__op);
2242}
2243
2244template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002245_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002246typename enable_if
2247<
2248 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2249 _Tp
2250>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002251atomic_fetch_and(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002252{
2253 return __o->fetch_and(__op);
2254}
2255
2256// atomic_fetch_and_explicit
2257
2258template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002259_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002260typename enable_if
2261<
2262 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2263 _Tp
2264>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002265atomic_fetch_and_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002266{
2267 return __o->fetch_and(__op, __m);
2268}
2269
2270template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002271_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002272typename enable_if
2273<
2274 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2275 _Tp
2276>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002277atomic_fetch_and_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002278{
2279 return __o->fetch_and(__op, __m);
2280}
2281
2282// atomic_fetch_or
2283
2284template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002285_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002286typename enable_if
2287<
2288 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2289 _Tp
2290>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002291atomic_fetch_or(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002292{
2293 return __o->fetch_or(__op);
2294}
2295
2296template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002297_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002298typename enable_if
2299<
2300 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2301 _Tp
2302>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002303atomic_fetch_or(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002304{
2305 return __o->fetch_or(__op);
2306}
2307
2308// atomic_fetch_or_explicit
2309
2310template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002311_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002312typename enable_if
2313<
2314 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2315 _Tp
2316>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002317atomic_fetch_or_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002318{
2319 return __o->fetch_or(__op, __m);
2320}
2321
2322template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002323_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002324typename enable_if
2325<
2326 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2327 _Tp
2328>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002329atomic_fetch_or_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002330{
2331 return __o->fetch_or(__op, __m);
2332}
2333
2334// atomic_fetch_xor
2335
2336template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002337_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002338typename enable_if
2339<
2340 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2341 _Tp
2342>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002343atomic_fetch_xor(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002344{
2345 return __o->fetch_xor(__op);
2346}
2347
2348template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002349_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002350typename enable_if
2351<
2352 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2353 _Tp
2354>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002355atomic_fetch_xor(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002356{
2357 return __o->fetch_xor(__op);
2358}
2359
2360// atomic_fetch_xor_explicit
2361
2362template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002363_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002364typename enable_if
2365<
2366 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2367 _Tp
2368>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002369atomic_fetch_xor_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002370{
2371 return __o->fetch_xor(__op, __m);
2372}
2373
2374template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002375_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002376typename enable_if
2377<
2378 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2379 _Tp
2380>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002381atomic_fetch_xor_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002382{
2383 return __o->fetch_xor(__op, __m);
2384}
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002385
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002386// flag type and operations
2387
2388typedef struct atomic_flag
2389{
Davide Italiano011f80a2019-03-05 18:40:49 +00002390 __cxx_atomic_impl<_LIBCPP_ATOMIC_FLAG_TYPE> __a_;
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002391
2392 _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002393 bool test(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
2394 {return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m);}
2395 _LIBCPP_INLINE_VISIBILITY
2396 bool test(memory_order __m = memory_order_seq_cst) const _NOEXCEPT
2397 {return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m);}
2398
2399 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00002400 bool test_and_set(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00002401 {return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);}
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002402 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00002403 bool test_and_set(memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00002404 {return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);}
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002405 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00002406 void clear(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00002407 {__cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);}
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002408 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00002409 void clear(memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00002410 {__cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);}
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002411
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002412 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002413 void wait(bool __v, memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
2414 {__cxx_atomic_wait(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002415 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002416 void wait(bool __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT
2417 {__cxx_atomic_wait(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002418 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002419 void notify_one() volatile _NOEXCEPT
2420 {__cxx_atomic_notify_one(&__a_);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002421 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002422 void notify_one() _NOEXCEPT
2423 {__cxx_atomic_notify_one(&__a_);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002424 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002425 void notify_all() volatile _NOEXCEPT
2426 {__cxx_atomic_notify_all(&__a_);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002427 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002428 void notify_all() _NOEXCEPT
2429 {__cxx_atomic_notify_all(&__a_);}
2430
Raul Tambre4e0e88f2021-06-06 19:02:20 +03002431#if _LIBCPP_STD_VER > 17
2432 _LIBCPP_INLINE_VISIBILITY constexpr
2433 atomic_flag() _NOEXCEPT : __a_(false) {}
2434#else
Olivier Giroux161e6e82020-02-18 09:58:34 -05002435 _LIBCPP_INLINE_VISIBILITY
Nikolas Klauser6766be32021-12-07 20:29:35 +01002436 atomic_flag() _NOEXCEPT = default;
Raul Tambre4e0e88f2021-06-06 19:02:20 +03002437#endif
Howard Hinnant3d284222013-05-02 20:18:43 +00002438
Marshall Clowcf990752018-04-25 14:27:29 +00002439 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
Eric Fiselierfec26a92016-05-03 02:12:26 +00002440 atomic_flag(bool __b) _NOEXCEPT : __a_(__b) {} // EXTENSION
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002441
Eric Fiselier2d8515f2017-01-06 20:58:25 +00002442#ifndef _LIBCPP_CXX03_LANG
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002443 atomic_flag(const atomic_flag&) = delete;
2444 atomic_flag& operator=(const atomic_flag&) = delete;
2445 atomic_flag& operator=(const atomic_flag&) volatile = delete;
Eric Fiselier2d8515f2017-01-06 20:58:25 +00002446#else
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002447private:
Olivier Giroux161e6e82020-02-18 09:58:34 -05002448 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002449 atomic_flag(const atomic_flag&);
Olivier Giroux161e6e82020-02-18 09:58:34 -05002450 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002451 atomic_flag& operator=(const atomic_flag&);
Olivier Giroux161e6e82020-02-18 09:58:34 -05002452 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002453 atomic_flag& operator=(const atomic_flag&) volatile;
Eric Fiselier2d8515f2017-01-06 20:58:25 +00002454#endif
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002455} atomic_flag;
2456
Olivier Giroux161e6e82020-02-18 09:58:34 -05002457
2458inline _LIBCPP_INLINE_VISIBILITY
2459bool
2460atomic_flag_test(const volatile atomic_flag* __o) _NOEXCEPT
2461{
2462 return __o->test();
2463}
2464
2465inline _LIBCPP_INLINE_VISIBILITY
2466bool
2467atomic_flag_test(const atomic_flag* __o) _NOEXCEPT
2468{
2469 return __o->test();
2470}
2471
2472inline _LIBCPP_INLINE_VISIBILITY
2473bool
2474atomic_flag_test_explicit(const volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
2475{
2476 return __o->test(__m);
2477}
2478
2479inline _LIBCPP_INLINE_VISIBILITY
2480bool
2481atomic_flag_test_explicit(const atomic_flag* __o, memory_order __m) _NOEXCEPT
2482{
2483 return __o->test(__m);
2484}
2485
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002486inline _LIBCPP_INLINE_VISIBILITY
2487bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00002488atomic_flag_test_and_set(volatile atomic_flag* __o) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002489{
2490 return __o->test_and_set();
2491}
2492
2493inline _LIBCPP_INLINE_VISIBILITY
2494bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00002495atomic_flag_test_and_set(atomic_flag* __o) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002496{
2497 return __o->test_and_set();
2498}
2499
2500inline _LIBCPP_INLINE_VISIBILITY
2501bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00002502atomic_flag_test_and_set_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002503{
2504 return __o->test_and_set(__m);
2505}
2506
2507inline _LIBCPP_INLINE_VISIBILITY
2508bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00002509atomic_flag_test_and_set_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002510{
2511 return __o->test_and_set(__m);
2512}
2513
2514inline _LIBCPP_INLINE_VISIBILITY
2515void
Howard Hinnanteee2c142012-04-11 20:14:21 +00002516atomic_flag_clear(volatile atomic_flag* __o) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002517{
2518 __o->clear();
2519}
2520
2521inline _LIBCPP_INLINE_VISIBILITY
2522void
Howard Hinnanteee2c142012-04-11 20:14:21 +00002523atomic_flag_clear(atomic_flag* __o) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002524{
2525 __o->clear();
2526}
2527
2528inline _LIBCPP_INLINE_VISIBILITY
2529void
Howard Hinnanteee2c142012-04-11 20:14:21 +00002530atomic_flag_clear_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002531{
2532 __o->clear(__m);
2533}
2534
2535inline _LIBCPP_INLINE_VISIBILITY
2536void
Howard Hinnanteee2c142012-04-11 20:14:21 +00002537atomic_flag_clear_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002538{
2539 __o->clear(__m);
2540}
2541
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002542inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
Olivier Giroux161e6e82020-02-18 09:58:34 -05002543void
2544atomic_flag_wait(const volatile atomic_flag* __o, bool __v) _NOEXCEPT
2545{
2546 __o->wait(__v);
2547}
2548
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002549inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
Olivier Giroux161e6e82020-02-18 09:58:34 -05002550void
2551atomic_flag_wait(const atomic_flag* __o, bool __v) _NOEXCEPT
2552{
2553 __o->wait(__v);
2554}
2555
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002556inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
Olivier Giroux161e6e82020-02-18 09:58:34 -05002557void
2558atomic_flag_wait_explicit(const volatile atomic_flag* __o,
2559 bool __v, memory_order __m) _NOEXCEPT
2560{
2561 __o->wait(__v, __m);
2562}
2563
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002564inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
Olivier Giroux161e6e82020-02-18 09:58:34 -05002565void
2566atomic_flag_wait_explicit(const atomic_flag* __o,
2567 bool __v, memory_order __m) _NOEXCEPT
2568{
2569 __o->wait(__v, __m);
2570}
2571
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002572inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
Olivier Giroux161e6e82020-02-18 09:58:34 -05002573void
2574atomic_flag_notify_one(volatile atomic_flag* __o) _NOEXCEPT
2575{
2576 __o->notify_one();
2577}
2578
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002579inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
Olivier Giroux161e6e82020-02-18 09:58:34 -05002580void
2581atomic_flag_notify_one(atomic_flag* __o) _NOEXCEPT
2582{
2583 __o->notify_one();
2584}
2585
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002586inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
Olivier Giroux161e6e82020-02-18 09:58:34 -05002587void
2588atomic_flag_notify_all(volatile atomic_flag* __o) _NOEXCEPT
2589{
2590 __o->notify_all();
2591}
2592
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002593inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
Olivier Giroux161e6e82020-02-18 09:58:34 -05002594void
2595atomic_flag_notify_all(atomic_flag* __o) _NOEXCEPT
2596{
2597 __o->notify_all();
2598}
2599
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002600// fences
2601
2602inline _LIBCPP_INLINE_VISIBILITY
2603void
Howard Hinnanteee2c142012-04-11 20:14:21 +00002604atomic_thread_fence(memory_order __m) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002605{
Davide Italiano011f80a2019-03-05 18:40:49 +00002606 __cxx_atomic_thread_fence(__m);
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002607}
2608
2609inline _LIBCPP_INLINE_VISIBILITY
2610void
Howard Hinnanteee2c142012-04-11 20:14:21 +00002611atomic_signal_fence(memory_order __m) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002612{
Davide Italiano011f80a2019-03-05 18:40:49 +00002613 __cxx_atomic_signal_fence(__m);
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002614}
2615
Howard Hinnant96e4cd62010-12-07 23:24:41 +00002616// Atomics for standard typedef types
2617
Howard Hinnantf0af8d92013-01-04 18:58:50 +00002618typedef atomic<bool> atomic_bool;
Howard Hinnant96e4cd62010-12-07 23:24:41 +00002619typedef atomic<char> atomic_char;
2620typedef atomic<signed char> atomic_schar;
2621typedef atomic<unsigned char> atomic_uchar;
2622typedef atomic<short> atomic_short;
2623typedef atomic<unsigned short> atomic_ushort;
2624typedef atomic<int> atomic_int;
2625typedef atomic<unsigned int> atomic_uint;
2626typedef atomic<long> atomic_long;
2627typedef atomic<unsigned long> atomic_ulong;
2628typedef atomic<long long> atomic_llong;
2629typedef atomic<unsigned long long> atomic_ullong;
Arthur O'Dwyerafa5d5f2021-04-18 21:47:08 -04002630#ifndef _LIBCPP_HAS_NO_CHAR8_T
Marek Kurdej91bebaa2020-11-24 21:07:06 +01002631typedef atomic<char8_t> atomic_char8_t;
2632#endif
Howard Hinnant96e4cd62010-12-07 23:24:41 +00002633typedef atomic<char16_t> atomic_char16_t;
2634typedef atomic<char32_t> atomic_char32_t;
Louis Dionne89258142021-08-23 15:32:36 -04002635#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnant96e4cd62010-12-07 23:24:41 +00002636typedef atomic<wchar_t> atomic_wchar_t;
Louis Dionne89258142021-08-23 15:32:36 -04002637#endif
Howard Hinnant96e4cd62010-12-07 23:24:41 +00002638
2639typedef atomic<int_least8_t> atomic_int_least8_t;
2640typedef atomic<uint_least8_t> atomic_uint_least8_t;
2641typedef atomic<int_least16_t> atomic_int_least16_t;
2642typedef atomic<uint_least16_t> atomic_uint_least16_t;
2643typedef atomic<int_least32_t> atomic_int_least32_t;
2644typedef atomic<uint_least32_t> atomic_uint_least32_t;
2645typedef atomic<int_least64_t> atomic_int_least64_t;
2646typedef atomic<uint_least64_t> atomic_uint_least64_t;
2647
2648typedef atomic<int_fast8_t> atomic_int_fast8_t;
2649typedef atomic<uint_fast8_t> atomic_uint_fast8_t;
2650typedef atomic<int_fast16_t> atomic_int_fast16_t;
2651typedef atomic<uint_fast16_t> atomic_uint_fast16_t;
2652typedef atomic<int_fast32_t> atomic_int_fast32_t;
2653typedef atomic<uint_fast32_t> atomic_uint_fast32_t;
2654typedef atomic<int_fast64_t> atomic_int_fast64_t;
2655typedef atomic<uint_fast64_t> atomic_uint_fast64_t;
2656
Marshall Clowf710afc2016-06-30 15:28:38 +00002657typedef atomic< int8_t> atomic_int8_t;
2658typedef atomic<uint8_t> atomic_uint8_t;
2659typedef atomic< int16_t> atomic_int16_t;
2660typedef atomic<uint16_t> atomic_uint16_t;
2661typedef atomic< int32_t> atomic_int32_t;
2662typedef atomic<uint32_t> atomic_uint32_t;
2663typedef atomic< int64_t> atomic_int64_t;
2664typedef atomic<uint64_t> atomic_uint64_t;
2665
Howard Hinnant96e4cd62010-12-07 23:24:41 +00002666typedef atomic<intptr_t> atomic_intptr_t;
2667typedef atomic<uintptr_t> atomic_uintptr_t;
2668typedef atomic<size_t> atomic_size_t;
2669typedef atomic<ptrdiff_t> atomic_ptrdiff_t;
2670typedef atomic<intmax_t> atomic_intmax_t;
2671typedef atomic<uintmax_t> atomic_uintmax_t;
2672
Olivier Giroux161e6e82020-02-18 09:58:34 -05002673// atomic_*_lock_free : prefer the contention type most highly, then the largest lock-free type
2674
2675#ifdef __cpp_lib_atomic_is_always_lock_free
2676# define _LIBCPP_CONTENTION_LOCK_FREE __atomic_always_lock_free(sizeof(__cxx_contention_t), 0)
2677#else
2678# define _LIBCPP_CONTENTION_LOCK_FREE false
2679#endif
2680
2681#if ATOMIC_LLONG_LOCK_FREE == 2
2682typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, long long>::type __libcpp_signed_lock_free;
2683typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned long long>::type __libcpp_unsigned_lock_free;
2684#elif ATOMIC_INT_LOCK_FREE == 2
2685typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, int>::type __libcpp_signed_lock_free;
2686typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned int>::type __libcpp_unsigned_lock_free;
2687#elif ATOMIC_SHORT_LOCK_FREE == 2
2688typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, short>::type __libcpp_signed_lock_free;
2689typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned short>::type __libcpp_unsigned_lock_free;
2690#elif ATOMIC_CHAR_LOCK_FREE == 2
2691typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, char>::type __libcpp_signed_lock_free;
2692typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned char>::type __libcpp_unsigned_lock_free;
2693#else
2694 // No signed/unsigned lock-free types
Brian Caine5bbe5b2022-01-27 08:09:11 -08002695#define _LIBCPP_NO_LOCK_FREE_TYPES
Olivier Giroux161e6e82020-02-18 09:58:34 -05002696#endif
2697
Brian Caine5bbe5b2022-01-27 08:09:11 -08002698#if !defined(_LIBCPP_NO_LOCK_FREE_TYPES)
Olivier Giroux161e6e82020-02-18 09:58:34 -05002699typedef atomic<__libcpp_signed_lock_free> atomic_signed_lock_free;
2700typedef atomic<__libcpp_unsigned_lock_free> atomic_unsigned_lock_free;
Brian Caine5bbe5b2022-01-27 08:09:11 -08002701#endif
Olivier Giroux161e6e82020-02-18 09:58:34 -05002702
Howard Hinnantf1f066a2010-09-29 21:20:03 +00002703#define ATOMIC_FLAG_INIT {false}
Howard Hinnant953c31d2010-10-04 18:52:54 +00002704#define ATOMIC_VAR_INIT(__v) {__v}
2705
Raul Tambree254e7d2021-12-18 22:19:37 +02002706#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_DISABLE_DEPRECATION_WARNINGS)
2707# if defined(_LIBCPP_CLANG_VER) && _LIBCPP_CLANG_VER >= 1400
2708# pragma clang deprecated(ATOMIC_FLAG_INIT)
2709# pragma clang deprecated(ATOMIC_VAR_INIT)
2710# endif
2711#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_DISABLE_DEPRECATION_WARNINGS)
2712
Howard Hinnant71be7292010-09-27 21:17:38 +00002713_LIBCPP_END_NAMESPACE_STD
2714
Louis Dionne2b1ceaa2021-04-20 12:03:32 -04002715#endif // _LIBCPP_ATOMIC