blob: 2e2ee63b676d09d05d2533cc3fdbc4e3e98061dc [file] [log] [blame]
Howard Hinnant71be7292010-09-27 21:17:38 +00001// -*- C++ -*-
2//===--------------------------- atomic -----------------------------------===//
3//
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>
Olivier Giroux161e6e82020-02-18 09:58:34 -0500523#include <__threading_support>
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000524#include <cstddef>
525#include <cstdint>
Olivier Giroux161e6e82020-02-18 09:58:34 -0500526#include <cstring>
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000527#include <type_traits>
Marshall Clow0a1e7502018-09-12 19:41:40 +0000528#include <version>
Howard Hinnant71be7292010-09-27 21:17:38 +0000529
Howard Hinnantaaaa52b2011-10-17 20:05:10 +0000530#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
Howard Hinnant71be7292010-09-27 21:17:38 +0000531#pragma GCC system_header
Howard Hinnantaaaa52b2011-10-17 20:05:10 +0000532#endif
Howard Hinnant71be7292010-09-27 21:17:38 +0000533
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000534#ifdef _LIBCPP_HAS_NO_THREADS
Davide Italiano011f80a2019-03-05 18:40:49 +0000535# error <atomic> is not supported on this single threaded system
Eric Fiselier8020b6c2015-08-19 17:21:46 +0000536#endif
Davide Italiano011f80a2019-03-05 18:40:49 +0000537#ifdef _LIBCPP_HAS_NO_ATOMIC_HEADER
538# error <atomic> is not implemented
Eric Fiselier8020b6c2015-08-19 17:21:46 +0000539#endif
Volodymyr Sapsaif3ed1fd2018-05-15 22:38:31 +0000540#ifdef kill_dependency
Davide Italiano011f80a2019-03-05 18:40:49 +0000541# error C++ standard library is incompatible with <stdatomic.h>
Volodymyr Sapsaif3ed1fd2018-05-15 22:38:31 +0000542#endif
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000543
Eric Fiselierb5ab51d2017-01-13 23:45:39 +0000544#define _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) \
545 _LIBCPP_DIAGNOSE_WARNING(__m == memory_order_consume || \
546 __m == memory_order_acquire || \
547 __m == memory_order_acq_rel, \
548 "memory order argument to atomic operation is invalid")
549
550#define _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) \
551 _LIBCPP_DIAGNOSE_WARNING(__m == memory_order_release || \
552 __m == memory_order_acq_rel, \
553 "memory order argument to atomic operation is invalid")
554
555#define _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__m, __f) \
556 _LIBCPP_DIAGNOSE_WARNING(__f == memory_order_release || \
557 __f == memory_order_acq_rel, \
558 "memory order argument to atomic operation is invalid")
559
Howard Hinnant71be7292010-09-27 21:17:38 +0000560_LIBCPP_BEGIN_NAMESPACE_STD
561
Eric Fiselierd4e3e5b2019-03-08 23:15:54 +0000562// Figure out what the underlying type for `memory_order` would be if it were
563// declared as an unscoped enum (accounting for -fshort-enums). Use this result
564// to pin the underlying type in C++20.
565enum __legacy_memory_order {
566 __mo_relaxed,
567 __mo_consume,
568 __mo_acquire,
569 __mo_release,
570 __mo_acq_rel,
571 __mo_seq_cst
572};
573
574typedef underlying_type<__legacy_memory_order>::type __memory_order_underlying_t;
575
Davide Italiano011f80a2019-03-05 18:40:49 +0000576#if _LIBCPP_STD_VER > 17
577
Eric Fiselierd4e3e5b2019-03-08 23:15:54 +0000578enum class memory_order : __memory_order_underlying_t {
579 relaxed = __mo_relaxed,
580 consume = __mo_consume,
581 acquire = __mo_acquire,
582 release = __mo_release,
583 acq_rel = __mo_acq_rel,
584 seq_cst = __mo_seq_cst
Davide Italiano011f80a2019-03-05 18:40:49 +0000585};
586
587inline constexpr auto memory_order_relaxed = memory_order::relaxed;
588inline constexpr auto memory_order_consume = memory_order::consume;
589inline constexpr auto memory_order_acquire = memory_order::acquire;
590inline constexpr auto memory_order_release = memory_order::release;
591inline constexpr auto memory_order_acq_rel = memory_order::acq_rel;
592inline constexpr auto memory_order_seq_cst = memory_order::seq_cst;
593
Davide Italiano011f80a2019-03-05 18:40:49 +0000594#else
595
596typedef enum memory_order {
Eric Fiselierd4e3e5b2019-03-08 23:15:54 +0000597 memory_order_relaxed = __mo_relaxed,
598 memory_order_consume = __mo_consume,
599 memory_order_acquire = __mo_acquire,
600 memory_order_release = __mo_release,
601 memory_order_acq_rel = __mo_acq_rel,
602 memory_order_seq_cst = __mo_seq_cst,
Howard Hinnantdca6e712010-09-28 17:13:38 +0000603} memory_order;
604
Davide Italiano011f80a2019-03-05 18:40:49 +0000605#endif // _LIBCPP_STD_VER > 17
606
Olivier Giroux161e6e82020-02-18 09:58:34 -0500607template <typename _Tp> _LIBCPP_INLINE_VISIBILITY
608bool __cxx_nonatomic_compare_equal(_Tp const& __lhs, _Tp const& __rhs) {
Arthur O'Dwyer22236632020-12-07 21:50:15 -0500609 return _VSTD::memcmp(&__lhs, &__rhs, sizeof(_Tp)) == 0;
Olivier Giroux161e6e82020-02-18 09:58:34 -0500610}
611
Eric Fiselier51525172019-03-08 23:30:26 +0000612static_assert((is_same<underlying_type<memory_order>::type, __memory_order_underlying_t>::value),
Eric Fiselierd4e3e5b2019-03-08 23:15:54 +0000613 "unexpected underlying type for std::memory_order");
Davide Italiano011f80a2019-03-05 18:40:49 +0000614
615#if defined(_LIBCPP_HAS_GCC_ATOMIC_IMP) || \
Arthur O'Dwyer2fc9b5d2021-04-17 17:03:20 -0400616 defined(_LIBCPP_ATOMIC_ONLY_USE_BUILTINS)
Davide Italiano011f80a2019-03-05 18:40:49 +0000617
618// [atomics.types.generic]p1 guarantees _Tp is trivially copyable. Because
619// the default operator= in an object is not volatile, a byte-by-byte copy
620// is required.
621template <typename _Tp, typename _Tv> _LIBCPP_INLINE_VISIBILITY
622typename enable_if<is_assignable<_Tp&, _Tv>::value>::type
623__cxx_atomic_assign_volatile(_Tp& __a_value, _Tv const& __val) {
624 __a_value = __val;
625}
626template <typename _Tp, typename _Tv> _LIBCPP_INLINE_VISIBILITY
627typename enable_if<is_assignable<_Tp&, _Tv>::value>::type
628__cxx_atomic_assign_volatile(_Tp volatile& __a_value, _Tv volatile const& __val) {
629 volatile char* __to = reinterpret_cast<volatile char*>(&__a_value);
630 volatile char* __end = __to + sizeof(_Tp);
631 volatile const char* __from = reinterpret_cast<volatile const char*>(&__val);
632 while (__to != __end)
633 *__to++ = *__from++;
634}
635
Davide Italiano31f218a2019-03-05 17:38:33 +0000636#endif
Louis Dionnea1ae0032019-03-04 15:26:27 +0000637
Davide Italiano011f80a2019-03-05 18:40:49 +0000638#if defined(_LIBCPP_HAS_GCC_ATOMIC_IMP)
639
640template <typename _Tp>
641struct __cxx_atomic_base_impl {
642
Eric Fiselier684aaca2015-10-14 08:36:22 +0000643 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier07b2b552016-11-18 06:42:17 +0000644#ifndef _LIBCPP_CXX03_LANG
Davide Italiano011f80a2019-03-05 18:40:49 +0000645 __cxx_atomic_base_impl() _NOEXCEPT = default;
Eric Fiselier684aaca2015-10-14 08:36:22 +0000646#else
Davide Italiano011f80a2019-03-05 18:40:49 +0000647 __cxx_atomic_base_impl() _NOEXCEPT : __a_value() {}
Eric Fiselier07b2b552016-11-18 06:42:17 +0000648#endif // _LIBCPP_CXX03_LANG
Davide Italiano011f80a2019-03-05 18:40:49 +0000649 _LIBCPP_CONSTEXPR explicit __cxx_atomic_base_impl(_Tp value) _NOEXCEPT
Eric Fiselier719e0442015-07-14 17:50:27 +0000650 : __a_value(value) {}
Marshall Clow290eb3f2015-01-11 06:15:59 +0000651 _Tp __a_value;
Dan Albert7b65ace2014-08-09 23:51:51 +0000652};
Dan Albert7b65ace2014-08-09 23:51:51 +0000653
Davide Italiano011f80a2019-03-05 18:40:49 +0000654_LIBCPP_INLINE_VISIBILITY inline _LIBCPP_CONSTEXPR int __to_gcc_order(memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000655 // Avoid switch statement to make this a constexpr.
656 return __order == memory_order_relaxed ? __ATOMIC_RELAXED:
657 (__order == memory_order_acquire ? __ATOMIC_ACQUIRE:
658 (__order == memory_order_release ? __ATOMIC_RELEASE:
659 (__order == memory_order_seq_cst ? __ATOMIC_SEQ_CST:
660 (__order == memory_order_acq_rel ? __ATOMIC_ACQ_REL:
661 __ATOMIC_CONSUME))));
662}
663
Davide Italiano011f80a2019-03-05 18:40:49 +0000664_LIBCPP_INLINE_VISIBILITY inline _LIBCPP_CONSTEXPR int __to_gcc_failure_order(memory_order __order) {
Dan Albert48815f22015-01-06 18:39:37 +0000665 // Avoid switch statement to make this a constexpr.
666 return __order == memory_order_relaxed ? __ATOMIC_RELAXED:
667 (__order == memory_order_acquire ? __ATOMIC_ACQUIRE:
668 (__order == memory_order_release ? __ATOMIC_RELAXED:
669 (__order == memory_order_seq_cst ? __ATOMIC_SEQ_CST:
670 (__order == memory_order_acq_rel ? __ATOMIC_ACQUIRE:
671 __ATOMIC_CONSUME))));
672}
673
Davide Italiano011f80a2019-03-05 18:40:49 +0000674template <typename _Tp>
675_LIBCPP_INLINE_VISIBILITY
676void __cxx_atomic_init(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __val) {
677 __cxx_atomic_assign_volatile(__a->__a_value, __val);
678}
Dan Albert7b65ace2014-08-09 23:51:51 +0000679
680template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000681_LIBCPP_INLINE_VISIBILITY
682void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp>* __a, _Tp __val) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000683 __a->__a_value = __val;
684}
685
Davide Italiano011f80a2019-03-05 18:40:49 +0000686_LIBCPP_INLINE_VISIBILITY inline
687void __cxx_atomic_thread_fence(memory_order __order) {
688 __atomic_thread_fence(__to_gcc_order(__order));
689}
690
691_LIBCPP_INLINE_VISIBILITY inline
692void __cxx_atomic_signal_fence(memory_order __order) {
693 __atomic_signal_fence(__to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000694}
695
696template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000697_LIBCPP_INLINE_VISIBILITY
698void __cxx_atomic_store(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __val,
699 memory_order __order) {
Dan Albert48815f22015-01-06 18:39:37 +0000700 __atomic_store(&__a->__a_value, &__val,
Davide Italiano011f80a2019-03-05 18:40:49 +0000701 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000702}
703
704template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000705_LIBCPP_INLINE_VISIBILITY
706void __cxx_atomic_store(__cxx_atomic_base_impl<_Tp>* __a, _Tp __val,
707 memory_order __order) {
708 __atomic_store(&__a->__a_value, &__val,
709 __to_gcc_order(__order));
710}
711
712template <typename _Tp>
713_LIBCPP_INLINE_VISIBILITY
714_Tp __cxx_atomic_load(const volatile __cxx_atomic_base_impl<_Tp>* __a,
715 memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000716 _Tp __ret;
717 __atomic_load(&__a->__a_value, &__ret,
Davide Italiano011f80a2019-03-05 18:40:49 +0000718 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000719 return __ret;
720}
721
722template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000723_LIBCPP_INLINE_VISIBILITY
724_Tp __cxx_atomic_load(const __cxx_atomic_base_impl<_Tp>* __a, memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000725 _Tp __ret;
726 __atomic_load(&__a->__a_value, &__ret,
Davide Italiano011f80a2019-03-05 18:40:49 +0000727 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000728 return __ret;
729}
730
731template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000732_LIBCPP_INLINE_VISIBILITY
733_Tp __cxx_atomic_exchange(volatile __cxx_atomic_base_impl<_Tp>* __a,
734 _Tp __value, memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000735 _Tp __ret;
736 __atomic_exchange(&__a->__a_value, &__value, &__ret,
Davide Italiano011f80a2019-03-05 18:40:49 +0000737 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000738 return __ret;
739}
740
741template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000742_LIBCPP_INLINE_VISIBILITY
743_Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp>* __a, _Tp __value,
744 memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000745 _Tp __ret;
746 __atomic_exchange(&__a->__a_value, &__value, &__ret,
Davide Italiano011f80a2019-03-05 18:40:49 +0000747 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000748 return __ret;
749}
750
751template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000752_LIBCPP_INLINE_VISIBILITY
753bool __cxx_atomic_compare_exchange_strong(
754 volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value,
JF Bastien6e412d92018-05-26 19:44:45 +0000755 memory_order __success, memory_order __failure) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000756 return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
757 false,
Davide Italiano011f80a2019-03-05 18:40:49 +0000758 __to_gcc_order(__success),
759 __to_gcc_failure_order(__failure));
Dan Albert7b65ace2014-08-09 23:51:51 +0000760}
761
762template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000763_LIBCPP_INLINE_VISIBILITY
764bool __cxx_atomic_compare_exchange_strong(
765 __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success,
JF Bastien6e412d92018-05-26 19:44:45 +0000766 memory_order __failure) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000767 return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
768 false,
Davide Italiano011f80a2019-03-05 18:40:49 +0000769 __to_gcc_order(__success),
770 __to_gcc_failure_order(__failure));
Dan Albert7b65ace2014-08-09 23:51:51 +0000771}
772
773template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000774_LIBCPP_INLINE_VISIBILITY
775bool __cxx_atomic_compare_exchange_weak(
776 volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value,
JF Bastien6e412d92018-05-26 19:44:45 +0000777 memory_order __success, memory_order __failure) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000778 return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
779 true,
Davide Italiano011f80a2019-03-05 18:40:49 +0000780 __to_gcc_order(__success),
781 __to_gcc_failure_order(__failure));
Dan Albert7b65ace2014-08-09 23:51:51 +0000782}
783
784template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000785_LIBCPP_INLINE_VISIBILITY
786bool __cxx_atomic_compare_exchange_weak(
787 __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success,
JF Bastien6e412d92018-05-26 19:44:45 +0000788 memory_order __failure) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000789 return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
790 true,
Davide Italiano011f80a2019-03-05 18:40:49 +0000791 __to_gcc_order(__success),
792 __to_gcc_failure_order(__failure));
Dan Albert7b65ace2014-08-09 23:51:51 +0000793}
794
795template <typename _Tp>
796struct __skip_amt { enum {value = 1}; };
797
798template <typename _Tp>
799struct __skip_amt<_Tp*> { enum {value = sizeof(_Tp)}; };
800
801// FIXME: Haven't figured out what the spec says about using arrays with
802// atomic_fetch_add. Force a failure rather than creating bad behavior.
803template <typename _Tp>
804struct __skip_amt<_Tp[]> { };
805template <typename _Tp, int n>
806struct __skip_amt<_Tp[n]> { };
807
808template <typename _Tp, typename _Td>
Davide Italiano011f80a2019-03-05 18:40:49 +0000809_LIBCPP_INLINE_VISIBILITY
810_Tp __cxx_atomic_fetch_add(volatile __cxx_atomic_base_impl<_Tp>* __a,
811 _Td __delta, memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000812 return __atomic_fetch_add(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
Davide Italiano011f80a2019-03-05 18:40:49 +0000813 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000814}
815
816template <typename _Tp, typename _Td>
Davide Italiano011f80a2019-03-05 18:40:49 +0000817_LIBCPP_INLINE_VISIBILITY
818_Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp>* __a, _Td __delta,
819 memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000820 return __atomic_fetch_add(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
Davide Italiano011f80a2019-03-05 18:40:49 +0000821 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000822}
823
824template <typename _Tp, typename _Td>
Davide Italiano011f80a2019-03-05 18:40:49 +0000825_LIBCPP_INLINE_VISIBILITY
826_Tp __cxx_atomic_fetch_sub(volatile __cxx_atomic_base_impl<_Tp>* __a,
827 _Td __delta, memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000828 return __atomic_fetch_sub(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
Davide Italiano011f80a2019-03-05 18:40:49 +0000829 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000830}
831
832template <typename _Tp, typename _Td>
Davide Italiano011f80a2019-03-05 18:40:49 +0000833_LIBCPP_INLINE_VISIBILITY
834_Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp>* __a, _Td __delta,
835 memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000836 return __atomic_fetch_sub(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
Davide Italiano011f80a2019-03-05 18:40:49 +0000837 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000838}
839
840template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000841_LIBCPP_INLINE_VISIBILITY
842_Tp __cxx_atomic_fetch_and(volatile __cxx_atomic_base_impl<_Tp>* __a,
843 _Tp __pattern, memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000844 return __atomic_fetch_and(&__a->__a_value, __pattern,
Davide Italiano011f80a2019-03-05 18:40:49 +0000845 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000846}
847
848template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000849_LIBCPP_INLINE_VISIBILITY
850_Tp __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp>* __a,
851 _Tp __pattern, memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000852 return __atomic_fetch_and(&__a->__a_value, __pattern,
Davide Italiano011f80a2019-03-05 18:40:49 +0000853 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000854}
855
856template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000857_LIBCPP_INLINE_VISIBILITY
858_Tp __cxx_atomic_fetch_or(volatile __cxx_atomic_base_impl<_Tp>* __a,
859 _Tp __pattern, memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000860 return __atomic_fetch_or(&__a->__a_value, __pattern,
Davide Italiano011f80a2019-03-05 18:40:49 +0000861 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000862}
863
864template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000865_LIBCPP_INLINE_VISIBILITY
866_Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern,
867 memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000868 return __atomic_fetch_or(&__a->__a_value, __pattern,
Davide Italiano011f80a2019-03-05 18:40:49 +0000869 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000870}
871
872template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000873_LIBCPP_INLINE_VISIBILITY
874_Tp __cxx_atomic_fetch_xor(volatile __cxx_atomic_base_impl<_Tp>* __a,
875 _Tp __pattern, memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000876 return __atomic_fetch_xor(&__a->__a_value, __pattern,
Davide Italiano011f80a2019-03-05 18:40:49 +0000877 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000878}
879
880template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000881_LIBCPP_INLINE_VISIBILITY
882_Tp __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern,
883 memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000884 return __atomic_fetch_xor(&__a->__a_value, __pattern,
Davide Italiano011f80a2019-03-05 18:40:49 +0000885 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000886}
Davide Italiano011f80a2019-03-05 18:40:49 +0000887
888#define __cxx_atomic_is_lock_free(__s) __atomic_is_lock_free(__s, 0)
889
890#elif defined(_LIBCPP_HAS_C_ATOMIC_IMP)
891
892template <typename _Tp>
893struct __cxx_atomic_base_impl {
894
895 _LIBCPP_INLINE_VISIBILITY
896#ifndef _LIBCPP_CXX03_LANG
897 __cxx_atomic_base_impl() _NOEXCEPT = default;
898#else
899 __cxx_atomic_base_impl() _NOEXCEPT : __a_value() {}
900#endif // _LIBCPP_CXX03_LANG
901 _LIBCPP_CONSTEXPR explicit __cxx_atomic_base_impl(_Tp value) _NOEXCEPT
902 : __a_value(value) {}
Louis Dionnefaa17452019-09-04 12:44:19 +0000903 _LIBCPP_DISABLE_EXTENSION_WARNING _Atomic(_Tp) __a_value;
Davide Italiano011f80a2019-03-05 18:40:49 +0000904};
905
906#define __cxx_atomic_is_lock_free(__s) __c11_atomic_is_lock_free(__s)
907
908_LIBCPP_INLINE_VISIBILITY inline
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000909void __cxx_atomic_thread_fence(memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +0000910 __c11_atomic_thread_fence(static_cast<__memory_order_underlying_t>(__order));
911}
912
913_LIBCPP_INLINE_VISIBILITY inline
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000914void __cxx_atomic_signal_fence(memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +0000915 __c11_atomic_signal_fence(static_cast<__memory_order_underlying_t>(__order));
916}
917
918template<class _Tp>
919_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000920void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __val) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +0000921 __c11_atomic_init(&__a->__a_value, __val);
922}
923template<class _Tp>
924_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000925void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp> * __a, _Tp __val) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +0000926 __c11_atomic_init(&__a->__a_value, __val);
927}
928
929template<class _Tp>
930_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000931void __cxx_atomic_store(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __val, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +0000932 __c11_atomic_store(&__a->__a_value, __val, static_cast<__memory_order_underlying_t>(__order));
933}
934template<class _Tp>
935_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000936void __cxx_atomic_store(__cxx_atomic_base_impl<_Tp> * __a, _Tp __val, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +0000937 __c11_atomic_store(&__a->__a_value, __val, static_cast<__memory_order_underlying_t>(__order));
938}
939
940template<class _Tp>
941_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000942_Tp __cxx_atomic_load(__cxx_atomic_base_impl<_Tp> const volatile* __a, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +0000943 using __ptr_type = typename remove_const<decltype(__a->__a_value)>::type*;
944 return __c11_atomic_load(const_cast<__ptr_type>(&__a->__a_value), static_cast<__memory_order_underlying_t>(__order));
945}
946template<class _Tp>
947_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000948_Tp __cxx_atomic_load(__cxx_atomic_base_impl<_Tp> const* __a, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +0000949 using __ptr_type = typename remove_const<decltype(__a->__a_value)>::type*;
950 return __c11_atomic_load(const_cast<__ptr_type>(&__a->__a_value), static_cast<__memory_order_underlying_t>(__order));
951}
952
953template<class _Tp>
954_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000955_Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __value, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +0000956 return __c11_atomic_exchange(&__a->__a_value, __value, static_cast<__memory_order_underlying_t>(__order));
957}
958template<class _Tp>
959_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000960_Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp> * __a, _Tp __value, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +0000961 return __c11_atomic_exchange(&__a->__a_value, __value, static_cast<__memory_order_underlying_t>(__order));
962}
963
Jordan Rupprechtd2e31a82021-06-15 07:55:23 -0700964_LIBCPP_INLINE_VISIBILITY inline _LIBCPP_CONSTEXPR memory_order __to_failure_order(memory_order __order) {
965 // Avoid switch statement to make this a constexpr.
966 return __order == memory_order_release ? memory_order_relaxed:
967 (__order == memory_order_acq_rel ? memory_order_acquire:
968 __order);
969}
970
Davide Italiano011f80a2019-03-05 18:40:49 +0000971template<class _Tp>
972_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000973bool __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 -0700974 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 +0000975}
976template<class _Tp>
977_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000978bool __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 -0700979 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 +0000980}
981
982template<class _Tp>
983_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000984bool __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 -0700985 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 +0000986}
987template<class _Tp>
988_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000989bool __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 -0700990 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 +0000991}
992
993template<class _Tp>
994_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000995_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 +0000996 return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
997}
998template<class _Tp>
999_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001000_Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp> * __a, _Tp __delta, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +00001001 return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
1002}
1003
1004template<class _Tp>
1005_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001006_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 +00001007 return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
1008}
1009template<class _Tp>
1010_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001011_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 +00001012 return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
1013}
1014
1015template<class _Tp>
1016_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001017_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 +00001018 return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
1019}
1020template<class _Tp>
1021_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001022_Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp> * __a, _Tp __delta, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +00001023 return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
1024}
1025template<class _Tp>
1026_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001027_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 +00001028 return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
1029}
1030template<class _Tp>
1031_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001032_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 +00001033 return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
1034}
1035
1036template<class _Tp>
1037_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001038_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 +00001039 return __c11_atomic_fetch_and(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
1040}
1041template<class _Tp>
1042_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001043_Tp __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +00001044 return __c11_atomic_fetch_and(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
1045}
1046
1047template<class _Tp>
1048_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001049_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 +00001050 return __c11_atomic_fetch_or(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
1051}
1052template<class _Tp>
1053_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001054_Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +00001055 return __c11_atomic_fetch_or(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
1056}
1057
1058template<class _Tp>
1059_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001060_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 +00001061 return __c11_atomic_fetch_xor(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
1062}
1063template<class _Tp>
1064_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001065_Tp __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +00001066 return __c11_atomic_fetch_xor(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
1067}
1068
1069#endif // _LIBCPP_HAS_GCC_ATOMIC_IMP, _LIBCPP_HAS_C_ATOMIC_IMP
Dan Albert7b65ace2014-08-09 23:51:51 +00001070
Howard Hinnantdca6e712010-09-28 17:13:38 +00001071template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001072_LIBCPP_INLINE_VISIBILITY
1073_Tp kill_dependency(_Tp __y) _NOEXCEPT
Howard Hinnantdca6e712010-09-28 17:13:38 +00001074{
1075 return __y;
1076}
Howard Hinnant71be7292010-09-27 21:17:38 +00001077
Eric Fiselierbed42df2017-04-20 23:22:46 +00001078#if defined(__CLANG_ATOMIC_BOOL_LOCK_FREE)
1079# define ATOMIC_BOOL_LOCK_FREE __CLANG_ATOMIC_BOOL_LOCK_FREE
1080# define ATOMIC_CHAR_LOCK_FREE __CLANG_ATOMIC_CHAR_LOCK_FREE
Arthur O'Dwyerafa5d5f2021-04-18 21:47:08 -04001081#ifndef _LIBCPP_HAS_NO_CHAR8_T
Marek Kurdej91bebaa2020-11-24 21:07:06 +01001082# define ATOMIC_CHAR8_T_LOCK_FREE __CLANG_ATOMIC_CHAR8_T_LOCK_FREE
1083#endif
Eric Fiselierbed42df2017-04-20 23:22:46 +00001084# define ATOMIC_CHAR16_T_LOCK_FREE __CLANG_ATOMIC_CHAR16_T_LOCK_FREE
1085# define ATOMIC_CHAR32_T_LOCK_FREE __CLANG_ATOMIC_CHAR32_T_LOCK_FREE
1086# define ATOMIC_WCHAR_T_LOCK_FREE __CLANG_ATOMIC_WCHAR_T_LOCK_FREE
1087# define ATOMIC_SHORT_LOCK_FREE __CLANG_ATOMIC_SHORT_LOCK_FREE
1088# define ATOMIC_INT_LOCK_FREE __CLANG_ATOMIC_INT_LOCK_FREE
1089# define ATOMIC_LONG_LOCK_FREE __CLANG_ATOMIC_LONG_LOCK_FREE
1090# define ATOMIC_LLONG_LOCK_FREE __CLANG_ATOMIC_LLONG_LOCK_FREE
1091# define ATOMIC_POINTER_LOCK_FREE __CLANG_ATOMIC_POINTER_LOCK_FREE
Davide Italiano011f80a2019-03-05 18:40:49 +00001092#elif defined(__GCC_ATOMIC_BOOL_LOCK_FREE)
Eric Fiselierbed42df2017-04-20 23:22:46 +00001093# define ATOMIC_BOOL_LOCK_FREE __GCC_ATOMIC_BOOL_LOCK_FREE
1094# define ATOMIC_CHAR_LOCK_FREE __GCC_ATOMIC_CHAR_LOCK_FREE
Arthur O'Dwyerafa5d5f2021-04-18 21:47:08 -04001095#ifndef _LIBCPP_HAS_NO_CHAR8_T
Marek Kurdej91bebaa2020-11-24 21:07:06 +01001096# define ATOMIC_CHAR8_T_LOCK_FREE __GCC_ATOMIC_CHAR8_T_LOCK_FREE
1097#endif
Eric Fiselierbed42df2017-04-20 23:22:46 +00001098# define ATOMIC_CHAR16_T_LOCK_FREE __GCC_ATOMIC_CHAR16_T_LOCK_FREE
1099# define ATOMIC_CHAR32_T_LOCK_FREE __GCC_ATOMIC_CHAR32_T_LOCK_FREE
1100# define ATOMIC_WCHAR_T_LOCK_FREE __GCC_ATOMIC_WCHAR_T_LOCK_FREE
1101# define ATOMIC_SHORT_LOCK_FREE __GCC_ATOMIC_SHORT_LOCK_FREE
1102# define ATOMIC_INT_LOCK_FREE __GCC_ATOMIC_INT_LOCK_FREE
1103# define ATOMIC_LONG_LOCK_FREE __GCC_ATOMIC_LONG_LOCK_FREE
1104# define ATOMIC_LLONG_LOCK_FREE __GCC_ATOMIC_LLONG_LOCK_FREE
1105# define ATOMIC_POINTER_LOCK_FREE __GCC_ATOMIC_POINTER_LOCK_FREE
1106#endif
JF Bastienfdb42c22016-03-25 15:48:21 +00001107
Davide Italiano011f80a2019-03-05 18:40:49 +00001108#ifdef _LIBCPP_ATOMIC_ONLY_USE_BUILTINS
1109
1110template<typename _Tp>
1111struct __cxx_atomic_lock_impl {
1112
1113 _LIBCPP_INLINE_VISIBILITY
1114 __cxx_atomic_lock_impl() _NOEXCEPT
1115 : __a_value(), __a_lock(0) {}
1116 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR explicit
1117 __cxx_atomic_lock_impl(_Tp value) _NOEXCEPT
1118 : __a_value(value), __a_lock(0) {}
1119
1120 _Tp __a_value;
1121 mutable __cxx_atomic_base_impl<_LIBCPP_ATOMIC_FLAG_TYPE> __a_lock;
1122
1123 _LIBCPP_INLINE_VISIBILITY void __lock() const volatile {
1124 while(1 == __cxx_atomic_exchange(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(true), memory_order_acquire))
1125 /*spin*/;
1126 }
1127 _LIBCPP_INLINE_VISIBILITY void __lock() const {
1128 while(1 == __cxx_atomic_exchange(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(true), memory_order_acquire))
1129 /*spin*/;
1130 }
1131 _LIBCPP_INLINE_VISIBILITY void __unlock() const volatile {
1132 __cxx_atomic_store(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(false), memory_order_release);
1133 }
1134 _LIBCPP_INLINE_VISIBILITY void __unlock() const {
1135 __cxx_atomic_store(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(false), memory_order_release);
1136 }
1137 _LIBCPP_INLINE_VISIBILITY _Tp __read() const volatile {
1138 __lock();
1139 _Tp __old;
1140 __cxx_atomic_assign_volatile(__old, __a_value);
1141 __unlock();
1142 return __old;
1143 }
1144 _LIBCPP_INLINE_VISIBILITY _Tp __read() const {
1145 __lock();
1146 _Tp __old = __a_value;
1147 __unlock();
1148 return __old;
1149 }
1150};
1151
1152template <typename _Tp>
1153_LIBCPP_INLINE_VISIBILITY
1154void __cxx_atomic_init(volatile __cxx_atomic_lock_impl<_Tp>* __a, _Tp __val) {
1155 __cxx_atomic_assign_volatile(__a->__a_value, __val);
1156}
1157template <typename _Tp>
1158_LIBCPP_INLINE_VISIBILITY
1159void __cxx_atomic_init(__cxx_atomic_lock_impl<_Tp>* __a, _Tp __val) {
1160 __a->__a_value = __val;
1161}
1162
1163template <typename _Tp>
1164_LIBCPP_INLINE_VISIBILITY
1165void __cxx_atomic_store(volatile __cxx_atomic_lock_impl<_Tp>* __a, _Tp __val, memory_order) {
1166 __a->__lock();
1167 __cxx_atomic_assign_volatile(__a->__a_value, __val);
1168 __a->__unlock();
1169}
1170template <typename _Tp>
1171_LIBCPP_INLINE_VISIBILITY
1172void __cxx_atomic_store(__cxx_atomic_lock_impl<_Tp>* __a, _Tp __val, memory_order) {
1173 __a->__lock();
1174 __a->__a_value = __val;
1175 __a->__unlock();
1176}
1177
1178template <typename _Tp>
1179_LIBCPP_INLINE_VISIBILITY
1180_Tp __cxx_atomic_load(const volatile __cxx_atomic_lock_impl<_Tp>* __a, memory_order) {
1181 return __a->__read();
1182}
1183template <typename _Tp>
1184_LIBCPP_INLINE_VISIBILITY
1185_Tp __cxx_atomic_load(const __cxx_atomic_lock_impl<_Tp>* __a, memory_order) {
1186 return __a->__read();
1187}
1188
1189template <typename _Tp>
1190_LIBCPP_INLINE_VISIBILITY
1191_Tp __cxx_atomic_exchange(volatile __cxx_atomic_lock_impl<_Tp>* __a, _Tp __value, memory_order) {
1192 __a->__lock();
1193 _Tp __old;
1194 __cxx_atomic_assign_volatile(__old, __a->__a_value);
1195 __cxx_atomic_assign_volatile(__a->__a_value, __value);
1196 __a->__unlock();
1197 return __old;
1198}
1199template <typename _Tp>
1200_LIBCPP_INLINE_VISIBILITY
1201_Tp __cxx_atomic_exchange(__cxx_atomic_lock_impl<_Tp>* __a, _Tp __value, memory_order) {
1202 __a->__lock();
1203 _Tp __old = __a->__a_value;
1204 __a->__a_value = __value;
1205 __a->__unlock();
1206 return __old;
1207}
1208
1209template <typename _Tp>
1210_LIBCPP_INLINE_VISIBILITY
1211bool __cxx_atomic_compare_exchange_strong(volatile __cxx_atomic_lock_impl<_Tp>* __a,
1212 _Tp* __expected, _Tp __value, memory_order, memory_order) {
Olivier Giroux161e6e82020-02-18 09:58:34 -05001213 _Tp __temp;
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07001214 __a->__lock();
Olivier Giroux161e6e82020-02-18 09:58:34 -05001215 __cxx_atomic_assign_volatile(__temp, __a->__a_value);
Arthur O'Dwyer22236632020-12-07 21:50:15 -05001216 bool __ret = (_VSTD::memcmp(&__temp, __expected, sizeof(_Tp)) == 0);
Davide Italiano011f80a2019-03-05 18:40:49 +00001217 if(__ret)
1218 __cxx_atomic_assign_volatile(__a->__a_value, __value);
1219 else
1220 __cxx_atomic_assign_volatile(*__expected, __a->__a_value);
1221 __a->__unlock();
1222 return __ret;
1223}
1224template <typename _Tp>
1225_LIBCPP_INLINE_VISIBILITY
1226bool __cxx_atomic_compare_exchange_strong(__cxx_atomic_lock_impl<_Tp>* __a,
1227 _Tp* __expected, _Tp __value, memory_order, memory_order) {
1228 __a->__lock();
Arthur O'Dwyer22236632020-12-07 21:50:15 -05001229 bool __ret = (_VSTD::memcmp(&__a->__a_value, __expected, sizeof(_Tp)) == 0);
Davide Italiano011f80a2019-03-05 18:40:49 +00001230 if(__ret)
Arthur O'Dwyer22236632020-12-07 21:50:15 -05001231 _VSTD::memcpy(&__a->__a_value, &__value, sizeof(_Tp));
Davide Italiano011f80a2019-03-05 18:40:49 +00001232 else
Arthur O'Dwyer22236632020-12-07 21:50:15 -05001233 _VSTD::memcpy(__expected, &__a->__a_value, sizeof(_Tp));
Davide Italiano011f80a2019-03-05 18:40:49 +00001234 __a->__unlock();
1235 return __ret;
1236}
1237
1238template <typename _Tp>
1239_LIBCPP_INLINE_VISIBILITY
1240bool __cxx_atomic_compare_exchange_weak(volatile __cxx_atomic_lock_impl<_Tp>* __a,
1241 _Tp* __expected, _Tp __value, memory_order, memory_order) {
Olivier Giroux161e6e82020-02-18 09:58:34 -05001242 _Tp __temp;
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07001243 __a->__lock();
Olivier Giroux161e6e82020-02-18 09:58:34 -05001244 __cxx_atomic_assign_volatile(__temp, __a->__a_value);
Arthur O'Dwyer22236632020-12-07 21:50:15 -05001245 bool __ret = (_VSTD::memcmp(&__temp, __expected, sizeof(_Tp)) == 0);
Davide Italiano011f80a2019-03-05 18:40:49 +00001246 if(__ret)
1247 __cxx_atomic_assign_volatile(__a->__a_value, __value);
1248 else
1249 __cxx_atomic_assign_volatile(*__expected, __a->__a_value);
1250 __a->__unlock();
1251 return __ret;
1252}
1253template <typename _Tp>
1254_LIBCPP_INLINE_VISIBILITY
1255bool __cxx_atomic_compare_exchange_weak(__cxx_atomic_lock_impl<_Tp>* __a,
1256 _Tp* __expected, _Tp __value, memory_order, memory_order) {
1257 __a->__lock();
Arthur O'Dwyer22236632020-12-07 21:50:15 -05001258 bool __ret = (_VSTD::memcmp(&__a->__a_value, __expected, sizeof(_Tp)) == 0);
Davide Italiano011f80a2019-03-05 18:40:49 +00001259 if(__ret)
Arthur O'Dwyer22236632020-12-07 21:50:15 -05001260 _VSTD::memcpy(&__a->__a_value, &__value, sizeof(_Tp));
Davide Italiano011f80a2019-03-05 18:40:49 +00001261 else
Arthur O'Dwyer22236632020-12-07 21:50:15 -05001262 _VSTD::memcpy(__expected, &__a->__a_value, sizeof(_Tp));
Davide Italiano011f80a2019-03-05 18:40:49 +00001263 __a->__unlock();
1264 return __ret;
1265}
1266
1267template <typename _Tp, typename _Td>
1268_LIBCPP_INLINE_VISIBILITY
1269_Tp __cxx_atomic_fetch_add(volatile __cxx_atomic_lock_impl<_Tp>* __a,
1270 _Td __delta, memory_order) {
1271 __a->__lock();
1272 _Tp __old;
1273 __cxx_atomic_assign_volatile(__old, __a->__a_value);
1274 __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old + __delta));
1275 __a->__unlock();
1276 return __old;
1277}
1278template <typename _Tp, typename _Td>
1279_LIBCPP_INLINE_VISIBILITY
1280_Tp __cxx_atomic_fetch_add(__cxx_atomic_lock_impl<_Tp>* __a,
1281 _Td __delta, memory_order) {
1282 __a->__lock();
1283 _Tp __old = __a->__a_value;
1284 __a->__a_value += __delta;
1285 __a->__unlock();
1286 return __old;
1287}
1288
1289template <typename _Tp, typename _Td>
1290_LIBCPP_INLINE_VISIBILITY
1291_Tp* __cxx_atomic_fetch_add(volatile __cxx_atomic_lock_impl<_Tp*>* __a,
1292 ptrdiff_t __delta, memory_order) {
1293 __a->__lock();
1294 _Tp* __old;
1295 __cxx_atomic_assign_volatile(__old, __a->__a_value);
1296 __cxx_atomic_assign_volatile(__a->__a_value, __old + __delta);
1297 __a->__unlock();
1298 return __old;
1299}
1300template <typename _Tp, typename _Td>
1301_LIBCPP_INLINE_VISIBILITY
1302_Tp* __cxx_atomic_fetch_add(__cxx_atomic_lock_impl<_Tp*>* __a,
1303 ptrdiff_t __delta, memory_order) {
1304 __a->__lock();
1305 _Tp* __old = __a->__a_value;
1306 __a->__a_value += __delta;
1307 __a->__unlock();
1308 return __old;
1309}
1310
1311template <typename _Tp, typename _Td>
1312_LIBCPP_INLINE_VISIBILITY
1313_Tp __cxx_atomic_fetch_sub(volatile __cxx_atomic_lock_impl<_Tp>* __a,
1314 _Td __delta, memory_order) {
1315 __a->__lock();
1316 _Tp __old;
1317 __cxx_atomic_assign_volatile(__old, __a->__a_value);
1318 __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old - __delta));
1319 __a->__unlock();
1320 return __old;
1321}
1322template <typename _Tp, typename _Td>
1323_LIBCPP_INLINE_VISIBILITY
1324_Tp __cxx_atomic_fetch_sub(__cxx_atomic_lock_impl<_Tp>* __a,
1325 _Td __delta, memory_order) {
1326 __a->__lock();
1327 _Tp __old = __a->__a_value;
1328 __a->__a_value -= __delta;
1329 __a->__unlock();
1330 return __old;
1331}
1332
1333template <typename _Tp>
1334_LIBCPP_INLINE_VISIBILITY
1335_Tp __cxx_atomic_fetch_and(volatile __cxx_atomic_lock_impl<_Tp>* __a,
1336 _Tp __pattern, memory_order) {
1337 __a->__lock();
1338 _Tp __old;
1339 __cxx_atomic_assign_volatile(__old, __a->__a_value);
1340 __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old & __pattern));
1341 __a->__unlock();
1342 return __old;
1343}
1344template <typename _Tp>
1345_LIBCPP_INLINE_VISIBILITY
1346_Tp __cxx_atomic_fetch_and(__cxx_atomic_lock_impl<_Tp>* __a,
1347 _Tp __pattern, memory_order) {
1348 __a->__lock();
1349 _Tp __old = __a->__a_value;
1350 __a->__a_value &= __pattern;
1351 __a->__unlock();
1352 return __old;
1353}
1354
1355template <typename _Tp>
1356_LIBCPP_INLINE_VISIBILITY
1357_Tp __cxx_atomic_fetch_or(volatile __cxx_atomic_lock_impl<_Tp>* __a,
1358 _Tp __pattern, memory_order) {
1359 __a->__lock();
1360 _Tp __old;
1361 __cxx_atomic_assign_volatile(__old, __a->__a_value);
1362 __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old | __pattern));
1363 __a->__unlock();
1364 return __old;
1365}
1366template <typename _Tp>
1367_LIBCPP_INLINE_VISIBILITY
1368_Tp __cxx_atomic_fetch_or(__cxx_atomic_lock_impl<_Tp>* __a,
1369 _Tp __pattern, memory_order) {
1370 __a->__lock();
1371 _Tp __old = __a->__a_value;
1372 __a->__a_value |= __pattern;
1373 __a->__unlock();
1374 return __old;
1375}
1376
1377template <typename _Tp>
1378_LIBCPP_INLINE_VISIBILITY
1379_Tp __cxx_atomic_fetch_xor(volatile __cxx_atomic_lock_impl<_Tp>* __a,
1380 _Tp __pattern, memory_order) {
1381 __a->__lock();
1382 _Tp __old;
1383 __cxx_atomic_assign_volatile(__old, __a->__a_value);
1384 __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old ^ __pattern));
1385 __a->__unlock();
1386 return __old;
1387}
1388template <typename _Tp>
1389_LIBCPP_INLINE_VISIBILITY
1390_Tp __cxx_atomic_fetch_xor(__cxx_atomic_lock_impl<_Tp>* __a,
1391 _Tp __pattern, memory_order) {
1392 __a->__lock();
1393 _Tp __old = __a->__a_value;
1394 __a->__a_value ^= __pattern;
1395 __a->__unlock();
1396 return __old;
1397}
1398
1399#ifdef __cpp_lib_atomic_is_always_lock_free
1400
1401template<typename _Tp> struct __cxx_is_always_lock_free {
1402 enum { __value = __atomic_always_lock_free(sizeof(_Tp), 0) }; };
1403
1404#else
1405
1406template<typename _Tp> struct __cxx_is_always_lock_free { enum { __value = false }; };
1407// Implementations must match the C ATOMIC_*_LOCK_FREE macro values.
1408template<> struct __cxx_is_always_lock_free<bool> { enum { __value = 2 == ATOMIC_BOOL_LOCK_FREE }; };
1409template<> struct __cxx_is_always_lock_free<char> { enum { __value = 2 == ATOMIC_CHAR_LOCK_FREE }; };
1410template<> struct __cxx_is_always_lock_free<signed char> { enum { __value = 2 == ATOMIC_CHAR_LOCK_FREE }; };
1411template<> struct __cxx_is_always_lock_free<unsigned char> { enum { __value = 2 == ATOMIC_CHAR_LOCK_FREE }; };
Arthur O'Dwyerafa5d5f2021-04-18 21:47:08 -04001412#ifndef _LIBCPP_HAS_NO_CHAR8_T
Marek Kurdej91bebaa2020-11-24 21:07:06 +01001413template<> struct __cxx_is_always_lock_free<char8_t> { enum { __value = 2 == ATOMIC_CHAR8_T_LOCK_FREE }; };
1414#endif
Davide Italiano011f80a2019-03-05 18:40:49 +00001415template<> struct __cxx_is_always_lock_free<char16_t> { enum { __value = 2 == ATOMIC_CHAR16_T_LOCK_FREE }; };
1416template<> struct __cxx_is_always_lock_free<char32_t> { enum { __value = 2 == ATOMIC_CHAR32_T_LOCK_FREE }; };
Louis Dionne89258142021-08-23 15:32:36 -04001417#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Davide Italiano011f80a2019-03-05 18:40:49 +00001418template<> struct __cxx_is_always_lock_free<wchar_t> { enum { __value = 2 == ATOMIC_WCHAR_T_LOCK_FREE }; };
Louis Dionne89258142021-08-23 15:32:36 -04001419#endif
Davide Italiano011f80a2019-03-05 18:40:49 +00001420template<> struct __cxx_is_always_lock_free<short> { enum { __value = 2 == ATOMIC_SHORT_LOCK_FREE }; };
1421template<> struct __cxx_is_always_lock_free<unsigned short> { enum { __value = 2 == ATOMIC_SHORT_LOCK_FREE }; };
1422template<> struct __cxx_is_always_lock_free<int> { enum { __value = 2 == ATOMIC_INT_LOCK_FREE }; };
1423template<> struct __cxx_is_always_lock_free<unsigned int> { enum { __value = 2 == ATOMIC_INT_LOCK_FREE }; };
1424template<> struct __cxx_is_always_lock_free<long> { enum { __value = 2 == ATOMIC_LONG_LOCK_FREE }; };
1425template<> struct __cxx_is_always_lock_free<unsigned long> { enum { __value = 2 == ATOMIC_LONG_LOCK_FREE }; };
1426template<> struct __cxx_is_always_lock_free<long long> { enum { __value = 2 == ATOMIC_LLONG_LOCK_FREE }; };
1427template<> struct __cxx_is_always_lock_free<unsigned long long> { enum { __value = 2 == ATOMIC_LLONG_LOCK_FREE }; };
1428template<typename _Tp> struct __cxx_is_always_lock_free<_Tp*> { enum { __value = 2 == ATOMIC_POINTER_LOCK_FREE }; };
1429template<> struct __cxx_is_always_lock_free<std::nullptr_t> { enum { __value = 2 == ATOMIC_POINTER_LOCK_FREE }; };
1430
1431#endif //__cpp_lib_atomic_is_always_lock_free
1432
1433template <typename _Tp,
1434 typename _Base = typename conditional<__cxx_is_always_lock_free<_Tp>::__value,
1435 __cxx_atomic_base_impl<_Tp>,
1436 __cxx_atomic_lock_impl<_Tp> >::type>
1437#else
1438template <typename _Tp,
1439 typename _Base = __cxx_atomic_base_impl<_Tp> >
1440#endif //_LIBCPP_ATOMIC_ONLY_USE_BUILTINS
1441struct __cxx_atomic_impl : public _Base {
Davide Italiano011f80a2019-03-05 18:40:49 +00001442 static_assert(is_trivially_copyable<_Tp>::value,
1443 "std::atomic<Tp> requires that 'Tp' be a trivially copyable type");
Davide Italiano011f80a2019-03-05 18:40:49 +00001444
1445 _LIBCPP_INLINE_VISIBILITY __cxx_atomic_impl() _NOEXCEPT _LIBCPP_DEFAULT
1446 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR explicit __cxx_atomic_impl(_Tp value) _NOEXCEPT
1447 : _Base(value) {}
1448};
1449
Olivier Giroux161e6e82020-02-18 09:58:34 -05001450#ifdef __linux__
1451 using __cxx_contention_t = int32_t;
1452#else
1453 using __cxx_contention_t = int64_t;
1454#endif //__linux__
1455
Olivier Giroux161e6e82020-02-18 09:58:34 -05001456using __cxx_atomic_contention_t = __cxx_atomic_impl<__cxx_contention_t>;
1457
1458#ifndef _LIBCPP_HAS_NO_PLATFORM_WAIT
1459
Louis Dionne48a828b2020-02-24 10:08:41 -05001460_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_one(void const volatile*);
1461_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_all(void const volatile*);
1462_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t __libcpp_atomic_monitor(void const volatile*);
1463_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __libcpp_atomic_wait(void const volatile*, __cxx_contention_t);
Olivier Giroux161e6e82020-02-18 09:58:34 -05001464
Louis Dionne48a828b2020-02-24 10:08:41 -05001465_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_one(__cxx_atomic_contention_t const volatile*);
1466_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_all(__cxx_atomic_contention_t const volatile*);
1467_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t __libcpp_atomic_monitor(__cxx_atomic_contention_t const volatile*);
1468_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 -05001469
1470template <class _Atp, class _Fn>
Louis Dionne08cd5cb2020-02-24 11:39:48 -05001471struct __libcpp_atomic_wait_backoff_impl {
1472 _Atp* __a;
1473 _Fn __test_fn;
Louis Dionne3dde4ab2020-02-24 10:09:29 -05001474 _LIBCPP_AVAILABILITY_SYNC
Louis Dionne08cd5cb2020-02-24 11:39:48 -05001475 _LIBCPP_INLINE_VISIBILITY bool operator()(chrono::nanoseconds __elapsed) const
1476 {
Olivier Giroux161e6e82020-02-18 09:58:34 -05001477 if(__elapsed > chrono::microseconds(64))
1478 {
1479 auto const __monitor = __libcpp_atomic_monitor(__a);
1480 if(__test_fn())
1481 return true;
1482 __libcpp_atomic_wait(__a, __monitor);
1483 }
1484 else if(__elapsed > chrono::microseconds(4))
1485 __libcpp_thread_yield();
1486 else
Marek Kurdejc79652f2020-11-15 16:17:52 +01001487 {} // poll
Olivier Giroux161e6e82020-02-18 09:58:34 -05001488 return false;
Louis Dionne08cd5cb2020-02-24 11:39:48 -05001489 }
1490};
1491
1492template <class _Atp, class _Fn>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05001493_LIBCPP_AVAILABILITY_SYNC
Louis Dionne08cd5cb2020-02-24 11:39:48 -05001494_LIBCPP_INLINE_VISIBILITY bool __cxx_atomic_wait(_Atp* __a, _Fn && __test_fn)
1495{
1496 __libcpp_atomic_wait_backoff_impl<_Atp, typename decay<_Fn>::type> __backoff_fn = {__a, __test_fn};
1497 return __libcpp_thread_poll_with_backoff(__test_fn, __backoff_fn);
Olivier Giroux161e6e82020-02-18 09:58:34 -05001498}
1499
1500#else // _LIBCPP_HAS_NO_PLATFORM_WAIT
1501
1502template <class _Tp>
1503_LIBCPP_INLINE_VISIBILITY void __cxx_atomic_notify_all(__cxx_atomic_impl<_Tp> const volatile*) { }
1504template <class _Tp>
1505_LIBCPP_INLINE_VISIBILITY void __cxx_atomic_notify_one(__cxx_atomic_impl<_Tp> const volatile*) { }
1506template <class _Atp, class _Fn>
1507_LIBCPP_INLINE_VISIBILITY bool __cxx_atomic_wait(_Atp*, _Fn && __test_fn)
1508{
1509 return __libcpp_thread_poll_with_backoff(__test_fn, __libcpp_timed_backoff_policy());
1510}
1511
1512#endif // _LIBCPP_HAS_NO_PLATFORM_WAIT
1513
1514template <class _Atp, class _Tp>
Louis Dionne08cd5cb2020-02-24 11:39:48 -05001515struct __cxx_atomic_wait_test_fn_impl {
1516 _Atp* __a;
1517 _Tp __val;
1518 memory_order __order;
1519 _LIBCPP_INLINE_VISIBILITY bool operator()() const
1520 {
1521 return !__cxx_nonatomic_compare_equal(__cxx_atomic_load(__a, __order), __val);
1522 }
1523};
1524
1525template <class _Atp, class _Tp>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05001526_LIBCPP_AVAILABILITY_SYNC
Olivier Giroux161e6e82020-02-18 09:58:34 -05001527_LIBCPP_INLINE_VISIBILITY bool __cxx_atomic_wait(_Atp* __a, _Tp const __val, memory_order __order)
1528{
Louis Dionne08cd5cb2020-02-24 11:39:48 -05001529 __cxx_atomic_wait_test_fn_impl<_Atp, _Tp> __test_fn = {__a, __val, __order};
Olivier Giroux161e6e82020-02-18 09:58:34 -05001530 return __cxx_atomic_wait(__a, __test_fn);
1531}
1532
Howard Hinnant138f5922010-12-07 20:46:14 +00001533// general atomic<T>
1534
1535template <class _Tp, bool = is_integral<_Tp>::value && !is_same<_Tp, bool>::value>
1536struct __atomic_base // false
1537{
Davide Italiano011f80a2019-03-05 18:40:49 +00001538 mutable __cxx_atomic_impl<_Tp> __a_;
Howard Hinnant138f5922010-12-07 20:46:14 +00001539
JF Bastienfdb42c22016-03-25 15:48:21 +00001540#if defined(__cpp_lib_atomic_is_always_lock_free)
1541 static _LIBCPP_CONSTEXPR bool is_always_lock_free = __atomic_always_lock_free(sizeof(__a_), 0);
1542#endif
1543
Howard Hinnant138f5922010-12-07 20:46:14 +00001544 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001545 bool is_lock_free() const volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001546 {return __cxx_atomic_is_lock_free(sizeof(_Tp));}
Howard Hinnant138f5922010-12-07 20:46:14 +00001547 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001548 bool is_lock_free() const _NOEXCEPT
Eric Fiselier3fd22c22015-06-13 00:23:07 +00001549 {return static_cast<__atomic_base const volatile*>(this)->is_lock_free();}
Howard Hinnant138f5922010-12-07 20:46:14 +00001550 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001551 void store(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001552 _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
Davide Italiano011f80a2019-03-05 18:40:49 +00001553 {__cxx_atomic_store(&__a_, __d, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001554 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001555 void store(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001556 _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
Davide Italiano011f80a2019-03-05 18:40:49 +00001557 {__cxx_atomic_store(&__a_, __d, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001558 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001559 _Tp load(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001560 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
Davide Italiano011f80a2019-03-05 18:40:49 +00001561 {return __cxx_atomic_load(&__a_, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001562 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001563 _Tp load(memory_order __m = memory_order_seq_cst) const _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001564 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
Davide Italiano011f80a2019-03-05 18:40:49 +00001565 {return __cxx_atomic_load(&__a_, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001566 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001567 operator _Tp() const volatile _NOEXCEPT {return load();}
Howard Hinnant138f5922010-12-07 20:46:14 +00001568 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001569 operator _Tp() const _NOEXCEPT {return load();}
Howard Hinnant138f5922010-12-07 20:46:14 +00001570 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001571 _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001572 {return __cxx_atomic_exchange(&__a_, __d, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001573 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001574 _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001575 {return __cxx_atomic_exchange(&__a_, __d, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001576 _LIBCPP_INLINE_VISIBILITY
1577 bool compare_exchange_weak(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001578 memory_order __s, memory_order __f) volatile _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001579 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Davide Italiano011f80a2019-03-05 18:40:49 +00001580 {return __cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001581 _LIBCPP_INLINE_VISIBILITY
1582 bool compare_exchange_weak(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001583 memory_order __s, memory_order __f) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001584 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Davide Italiano011f80a2019-03-05 18:40:49 +00001585 {return __cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001586 _LIBCPP_INLINE_VISIBILITY
1587 bool compare_exchange_strong(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001588 memory_order __s, memory_order __f) volatile _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001589 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Davide Italiano011f80a2019-03-05 18:40:49 +00001590 {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001591 _LIBCPP_INLINE_VISIBILITY
1592 bool compare_exchange_strong(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001593 memory_order __s, memory_order __f) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001594 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Davide Italiano011f80a2019-03-05 18:40:49 +00001595 {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001596 _LIBCPP_INLINE_VISIBILITY
1597 bool compare_exchange_weak(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001598 memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001599 {return __cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001600 _LIBCPP_INLINE_VISIBILITY
1601 bool compare_exchange_weak(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001602 memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001603 {return __cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001604 _LIBCPP_INLINE_VISIBILITY
1605 bool compare_exchange_strong(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001606 memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001607 {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}
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 __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001611 {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001612
Louis Dionne3dde4ab2020-02-24 10:09:29 -05001613 _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 -05001614 {__cxx_atomic_wait(&__a_, __v, __m);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05001615 _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 -05001616 {__cxx_atomic_wait(&__a_, __v, __m);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05001617 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_one() volatile _NOEXCEPT
Olivier Giroux161e6e82020-02-18 09:58:34 -05001618 {__cxx_atomic_notify_one(&__a_);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05001619 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_one() _NOEXCEPT
Olivier Giroux161e6e82020-02-18 09:58:34 -05001620 {__cxx_atomic_notify_one(&__a_);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05001621 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_all() volatile _NOEXCEPT
Olivier Giroux161e6e82020-02-18 09:58:34 -05001622 {__cxx_atomic_notify_all(&__a_);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05001623 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_all() _NOEXCEPT
Olivier Giroux161e6e82020-02-18 09:58:34 -05001624 {__cxx_atomic_notify_all(&__a_);}
1625
Raul Tambre4e0e88f2021-06-06 19:02:20 +03001626#if _LIBCPP_STD_VER > 17
1627 _LIBCPP_INLINE_VISIBILITY constexpr
1628 __atomic_base() noexcept(is_nothrow_default_constructible_v<_Tp>) : __a_(_Tp()) {}
1629#else
Howard Hinnant138f5922010-12-07 20:46:14 +00001630 _LIBCPP_INLINE_VISIBILITY
Davide Italiano011f80a2019-03-05 18:40:49 +00001631 __atomic_base() _NOEXCEPT _LIBCPP_DEFAULT
Raul Tambre4e0e88f2021-06-06 19:02:20 +03001632#endif
Howard Hinnant3d284222013-05-02 20:18:43 +00001633
Davide Italiano011f80a2019-03-05 18:40:49 +00001634 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
1635 __atomic_base(_Tp __d) _NOEXCEPT : __a_(__d) {}
1636
Eric Fiselier2d8515f2017-01-06 20:58:25 +00001637#ifndef _LIBCPP_CXX03_LANG
Howard Hinnant138f5922010-12-07 20:46:14 +00001638 __atomic_base(const __atomic_base&) = delete;
Eric Fiselier2d8515f2017-01-06 20:58:25 +00001639#else
Howard Hinnant6ac60f82010-12-08 17:20:28 +00001640private:
Olivier Giroux161e6e82020-02-18 09:58:34 -05001641 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant6ac60f82010-12-08 17:20:28 +00001642 __atomic_base(const __atomic_base&);
Eric Fiselier2d8515f2017-01-06 20:58:25 +00001643#endif
Howard Hinnant138f5922010-12-07 20:46:14 +00001644};
1645
JF Bastienfdb42c22016-03-25 15:48:21 +00001646#if defined(__cpp_lib_atomic_is_always_lock_free)
1647template <class _Tp, bool __b>
1648_LIBCPP_CONSTEXPR bool __atomic_base<_Tp, __b>::is_always_lock_free;
1649#endif
1650
Howard Hinnant138f5922010-12-07 20:46:14 +00001651// atomic<Integral>
1652
1653template <class _Tp>
1654struct __atomic_base<_Tp, true>
1655 : public __atomic_base<_Tp, false>
1656{
1657 typedef __atomic_base<_Tp, false> __base;
Raul Tambre4e0e88f2021-06-06 19:02:20 +03001658
1659 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
Howard Hinnant3d284222013-05-02 20:18:43 +00001660 __atomic_base() _NOEXCEPT _LIBCPP_DEFAULT
Raul Tambre4e0e88f2021-06-06 19:02:20 +03001661
Howard Hinnant138f5922010-12-07 20:46:14 +00001662 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001663 _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __base(__d) {}
Howard Hinnant138f5922010-12-07 20:46:14 +00001664
1665 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001666 _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001667 {return __cxx_atomic_fetch_add(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001668 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001669 _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001670 {return __cxx_atomic_fetch_add(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001671 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001672 _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001673 {return __cxx_atomic_fetch_sub(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001674 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001675 _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001676 {return __cxx_atomic_fetch_sub(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001677 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001678 _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001679 {return __cxx_atomic_fetch_and(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001680 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001681 _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001682 {return __cxx_atomic_fetch_and(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001683 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001684 _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001685 {return __cxx_atomic_fetch_or(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001686 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001687 _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001688 {return __cxx_atomic_fetch_or(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001689 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001690 _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001691 {return __cxx_atomic_fetch_xor(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001692 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001693 _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001694 {return __cxx_atomic_fetch_xor(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001695
1696 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001697 _Tp operator++(int) volatile _NOEXCEPT {return fetch_add(_Tp(1));}
Howard Hinnant138f5922010-12-07 20:46:14 +00001698 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001699 _Tp operator++(int) _NOEXCEPT {return fetch_add(_Tp(1));}
Howard Hinnant138f5922010-12-07 20:46:14 +00001700 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001701 _Tp operator--(int) volatile _NOEXCEPT {return fetch_sub(_Tp(1));}
Howard Hinnant138f5922010-12-07 20:46:14 +00001702 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001703 _Tp operator--(int) _NOEXCEPT {return fetch_sub(_Tp(1));}
Howard Hinnant138f5922010-12-07 20:46:14 +00001704 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001705 _Tp operator++() volatile _NOEXCEPT {return fetch_add(_Tp(1)) + _Tp(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001706 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001707 _Tp operator++() _NOEXCEPT {return fetch_add(_Tp(1)) + _Tp(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001708 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001709 _Tp operator--() volatile _NOEXCEPT {return fetch_sub(_Tp(1)) - _Tp(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001710 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001711 _Tp operator--() _NOEXCEPT {return fetch_sub(_Tp(1)) - _Tp(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001712 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001713 _Tp operator+=(_Tp __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001714 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001715 _Tp operator+=(_Tp __op) _NOEXCEPT {return fetch_add(__op) + __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001716 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001717 _Tp operator-=(_Tp __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001718 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001719 _Tp operator-=(_Tp __op) _NOEXCEPT {return fetch_sub(__op) - __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001720 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001721 _Tp operator&=(_Tp __op) volatile _NOEXCEPT {return fetch_and(__op) & __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001722 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001723 _Tp operator&=(_Tp __op) _NOEXCEPT {return fetch_and(__op) & __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001724 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001725 _Tp operator|=(_Tp __op) volatile _NOEXCEPT {return fetch_or(__op) | __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001726 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001727 _Tp operator|=(_Tp __op) _NOEXCEPT {return fetch_or(__op) | __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001728 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001729 _Tp operator^=(_Tp __op) volatile _NOEXCEPT {return fetch_xor(__op) ^ __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001730 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001731 _Tp operator^=(_Tp __op) _NOEXCEPT {return fetch_xor(__op) ^ __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001732};
1733
1734// atomic<T>
1735
1736template <class _Tp>
1737struct atomic
1738 : public __atomic_base<_Tp>
1739{
1740 typedef __atomic_base<_Tp> __base;
Olivier Giroux161e6e82020-02-18 09:58:34 -05001741 typedef _Tp value_type;
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07001742 typedef value_type difference_type;
Raul Tambre4e0e88f2021-06-06 19:02:20 +03001743
1744#if _LIBCPP_STD_VER > 17
1745 _LIBCPP_INLINE_VISIBILITY
1746 atomic() = default;
1747#else
Howard Hinnant138f5922010-12-07 20:46:14 +00001748 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3d284222013-05-02 20:18:43 +00001749 atomic() _NOEXCEPT _LIBCPP_DEFAULT
Raul Tambre4e0e88f2021-06-06 19:02:20 +03001750#endif
1751
Howard Hinnant138f5922010-12-07 20:46:14 +00001752 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001753 _LIBCPP_CONSTEXPR atomic(_Tp __d) _NOEXCEPT : __base(__d) {}
Howard Hinnant96e4cd62010-12-07 23:24:41 +00001754
1755 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001756 _Tp operator=(_Tp __d) volatile _NOEXCEPT
Howard Hinnant96e4cd62010-12-07 23:24:41 +00001757 {__base::store(__d); return __d;}
1758 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001759 _Tp operator=(_Tp __d) _NOEXCEPT
Howard Hinnant96e4cd62010-12-07 23:24:41 +00001760 {__base::store(__d); return __d;}
Ruslan Arutyunyan033093f2021-02-01 10:12:09 -05001761
1762 atomic& operator=(const atomic&) = delete;
1763 atomic& operator=(const atomic&) volatile = delete;
Howard Hinnant138f5922010-12-07 20:46:14 +00001764};
1765
1766// atomic<T*>
1767
1768template <class _Tp>
1769struct atomic<_Tp*>
1770 : public __atomic_base<_Tp*>
1771{
Howard Hinnant96e4cd62010-12-07 23:24:41 +00001772 typedef __atomic_base<_Tp*> __base;
Olivier Giroux161e6e82020-02-18 09:58:34 -05001773 typedef _Tp* value_type;
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07001774 typedef ptrdiff_t difference_type;
Raul Tambre4e0e88f2021-06-06 19:02:20 +03001775
Howard Hinnant138f5922010-12-07 20:46:14 +00001776 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3d284222013-05-02 20:18:43 +00001777 atomic() _NOEXCEPT _LIBCPP_DEFAULT
Raul Tambre4e0e88f2021-06-06 19:02:20 +03001778
Howard Hinnant138f5922010-12-07 20:46:14 +00001779 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001780 _LIBCPP_CONSTEXPR atomic(_Tp* __d) _NOEXCEPT : __base(__d) {}
Howard Hinnant138f5922010-12-07 20:46:14 +00001781
1782 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001783 _Tp* operator=(_Tp* __d) volatile _NOEXCEPT
Howard Hinnant96e4cd62010-12-07 23:24:41 +00001784 {__base::store(__d); return __d;}
1785 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001786 _Tp* operator=(_Tp* __d) _NOEXCEPT
Howard Hinnant96e4cd62010-12-07 23:24:41 +00001787 {__base::store(__d); return __d;}
1788
1789 _LIBCPP_INLINE_VISIBILITY
Mark de Wever494905b2021-06-09 20:26:34 +02001790 _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
1791 // __atomic_fetch_add accepts function pointers, guard against them.
1792 static_assert(!is_function<typename remove_pointer<_Tp>::type>::value, "Pointer to function isn't allowed");
1793 return __cxx_atomic_fetch_add(&this->__a_, __op, __m);
1794 }
1795
Howard Hinnant138f5922010-12-07 20:46:14 +00001796 _LIBCPP_INLINE_VISIBILITY
Mark de Wever494905b2021-06-09 20:26:34 +02001797 _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
1798 // __atomic_fetch_add accepts function pointers, guard against them.
1799 static_assert(!is_function<typename remove_pointer<_Tp>::type>::value, "Pointer to function isn't allowed");
1800 return __cxx_atomic_fetch_add(&this->__a_, __op, __m);
1801 }
1802
Howard Hinnant138f5922010-12-07 20:46:14 +00001803 _LIBCPP_INLINE_VISIBILITY
Mark de Wever494905b2021-06-09 20:26:34 +02001804 _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
1805 // __atomic_fetch_add accepts function pointers, guard against them.
1806 static_assert(!is_function<typename remove_pointer<_Tp>::type>::value, "Pointer to function isn't allowed");
1807 return __cxx_atomic_fetch_sub(&this->__a_, __op, __m);
1808 }
1809
Howard Hinnant138f5922010-12-07 20:46:14 +00001810 _LIBCPP_INLINE_VISIBILITY
Mark de Wever494905b2021-06-09 20:26:34 +02001811 _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
1812 // __atomic_fetch_add accepts function pointers, guard against them.
1813 static_assert(!is_function<typename remove_pointer<_Tp>::type>::value, "Pointer to function isn't allowed");
1814 return __cxx_atomic_fetch_sub(&this->__a_, __op, __m);
1815 }
Howard Hinnant138f5922010-12-07 20:46:14 +00001816
1817 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001818 _Tp* operator++(int) volatile _NOEXCEPT {return fetch_add(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001819 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001820 _Tp* operator++(int) _NOEXCEPT {return fetch_add(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001821 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001822 _Tp* operator--(int) volatile _NOEXCEPT {return fetch_sub(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001823 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001824 _Tp* operator--(int) _NOEXCEPT {return fetch_sub(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001825 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001826 _Tp* operator++() volatile _NOEXCEPT {return fetch_add(1) + 1;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001827 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001828 _Tp* operator++() _NOEXCEPT {return fetch_add(1) + 1;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001829 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001830 _Tp* operator--() volatile _NOEXCEPT {return fetch_sub(1) - 1;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001831 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001832 _Tp* operator--() _NOEXCEPT {return fetch_sub(1) - 1;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001833 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001834 _Tp* operator+=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001835 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001836 _Tp* operator+=(ptrdiff_t __op) _NOEXCEPT {return fetch_add(__op) + __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001837 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001838 _Tp* operator-=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001839 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001840 _Tp* operator-=(ptrdiff_t __op) _NOEXCEPT {return fetch_sub(__op) - __op;}
Ruslan Arutyunyan033093f2021-02-01 10:12:09 -05001841
1842 atomic& operator=(const atomic&) = delete;
1843 atomic& operator=(const atomic&) volatile = delete;
Howard Hinnant138f5922010-12-07 20:46:14 +00001844};
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001845
1846// atomic_is_lock_free
1847
1848template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001849_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001850bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00001851atomic_is_lock_free(const volatile atomic<_Tp>* __o) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001852{
Howard Hinnant138f5922010-12-07 20:46:14 +00001853 return __o->is_lock_free();
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001854}
1855
1856template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001857_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001858bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00001859atomic_is_lock_free(const atomic<_Tp>* __o) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001860{
Howard Hinnant138f5922010-12-07 20:46:14 +00001861 return __o->is_lock_free();
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001862}
1863
1864// atomic_init
1865
1866template <class _Tp>
Raul Tambre4e0e88f2021-06-06 19:02:20 +03001867_LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001868void
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07001869atomic_init(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001870{
Davide Italiano011f80a2019-03-05 18:40:49 +00001871 __cxx_atomic_init(&__o->__a_, __d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001872}
1873
1874template <class _Tp>
Raul Tambre4e0e88f2021-06-06 19:02:20 +03001875_LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001876void
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07001877atomic_init(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001878{
Davide Italiano011f80a2019-03-05 18:40:49 +00001879 __cxx_atomic_init(&__o->__a_, __d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001880}
1881
1882// atomic_store
1883
1884template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001885_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001886void
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07001887atomic_store(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001888{
Howard Hinnant138f5922010-12-07 20:46:14 +00001889 __o->store(__d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001890}
1891
1892template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001893_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001894void
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07001895atomic_store(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001896{
Howard Hinnant138f5922010-12-07 20:46:14 +00001897 __o->store(__d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001898}
1899
1900// atomic_store_explicit
1901
1902template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001903_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001904void
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07001905atomic_store_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001906 _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001907{
Howard Hinnant138f5922010-12-07 20:46:14 +00001908 __o->store(__d, __m);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001909}
1910
1911template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001912_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001913void
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07001914atomic_store_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001915 _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001916{
Howard Hinnant138f5922010-12-07 20:46:14 +00001917 __o->store(__d, __m);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001918}
1919
1920// atomic_load
1921
1922template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001923_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001924_Tp
Howard Hinnanteee2c142012-04-11 20:14:21 +00001925atomic_load(const volatile atomic<_Tp>* __o) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001926{
Howard Hinnant138f5922010-12-07 20:46:14 +00001927 return __o->load();
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001928}
1929
1930template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001931_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001932_Tp
Howard Hinnanteee2c142012-04-11 20:14:21 +00001933atomic_load(const atomic<_Tp>* __o) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001934{
Howard Hinnant138f5922010-12-07 20:46:14 +00001935 return __o->load();
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001936}
1937
1938// atomic_load_explicit
1939
1940template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001941_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001942_Tp
Howard Hinnanteee2c142012-04-11 20:14:21 +00001943atomic_load_explicit(const volatile atomic<_Tp>* __o, memory_order __m) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001944 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001945{
Howard Hinnant138f5922010-12-07 20:46:14 +00001946 return __o->load(__m);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001947}
1948
1949template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001950_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001951_Tp
Howard Hinnanteee2c142012-04-11 20:14:21 +00001952atomic_load_explicit(const atomic<_Tp>* __o, memory_order __m) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001953 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001954{
Howard Hinnant138f5922010-12-07 20:46:14 +00001955 return __o->load(__m);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001956}
1957
1958// atomic_exchange
1959
1960template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001961_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001962_Tp
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07001963atomic_exchange(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001964{
Howard Hinnant138f5922010-12-07 20:46:14 +00001965 return __o->exchange(__d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001966}
1967
1968template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001969_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001970_Tp
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07001971atomic_exchange(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001972{
Howard Hinnant138f5922010-12-07 20:46:14 +00001973 return __o->exchange(__d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001974}
1975
1976// atomic_exchange_explicit
1977
1978template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001979_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001980_Tp
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07001981atomic_exchange_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001982{
Howard Hinnant138f5922010-12-07 20:46:14 +00001983 return __o->exchange(__d, __m);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001984}
1985
1986template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001987_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001988_Tp
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07001989atomic_exchange_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001990{
Howard Hinnant138f5922010-12-07 20:46:14 +00001991 return __o->exchange(__d, __m);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001992}
1993
1994// atomic_compare_exchange_weak
1995
1996template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001997_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001998bool
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07001999atomic_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 +00002000{
Howard Hinnant138f5922010-12-07 20:46:14 +00002001 return __o->compare_exchange_weak(*__e, __d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002002}
2003
2004template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002005_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002006bool
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002007atomic_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 +00002008{
Howard Hinnant138f5922010-12-07 20:46:14 +00002009 return __o->compare_exchange_weak(*__e, __d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002010}
2011
2012// atomic_compare_exchange_strong
2013
2014template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002015_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002016bool
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002017atomic_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 +00002018{
Howard Hinnant138f5922010-12-07 20:46:14 +00002019 return __o->compare_exchange_strong(*__e, __d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002020}
2021
2022template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002023_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002024bool
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002025atomic_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 +00002026{
Howard Hinnant138f5922010-12-07 20:46:14 +00002027 return __o->compare_exchange_strong(*__e, __d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002028}
2029
2030// atomic_compare_exchange_weak_explicit
2031
2032template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002033_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002034bool
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002035atomic_compare_exchange_weak_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e,
2036 typename atomic<_Tp>::value_type __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00002037 memory_order __s, memory_order __f) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00002038 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002039{
Howard Hinnant138f5922010-12-07 20:46:14 +00002040 return __o->compare_exchange_weak(*__e, __d, __s, __f);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002041}
2042
2043template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002044_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002045bool
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002046atomic_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 +00002047 memory_order __s, memory_order __f) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00002048 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002049{
Howard Hinnant138f5922010-12-07 20:46:14 +00002050 return __o->compare_exchange_weak(*__e, __d, __s, __f);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002051}
2052
2053// atomic_compare_exchange_strong_explicit
2054
2055template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002056_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002057bool
2058atomic_compare_exchange_strong_explicit(volatile atomic<_Tp>* __o,
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002059 typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00002060 memory_order __s, memory_order __f) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00002061 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002062{
Howard Hinnant138f5922010-12-07 20:46:14 +00002063 return __o->compare_exchange_strong(*__e, __d, __s, __f);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002064}
2065
2066template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002067_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002068bool
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002069atomic_compare_exchange_strong_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e,
2070 typename atomic<_Tp>::value_type __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00002071 memory_order __s, memory_order __f) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00002072 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002073{
Howard Hinnant138f5922010-12-07 20:46:14 +00002074 return __o->compare_exchange_strong(*__e, __d, __s, __f);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002075}
2076
Olivier Giroux161e6e82020-02-18 09:58:34 -05002077// atomic_wait
2078
2079template <class _Tp>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002080_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002081void atomic_wait(const volatile atomic<_Tp>* __o,
2082 typename atomic<_Tp>::value_type __v) _NOEXCEPT
2083{
2084 return __o->wait(__v);
2085}
2086
2087template <class _Tp>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002088_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002089void atomic_wait(const atomic<_Tp>* __o,
2090 typename atomic<_Tp>::value_type __v) _NOEXCEPT
2091{
2092 return __o->wait(__v);
2093}
2094
2095// atomic_wait_explicit
2096
2097template <class _Tp>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002098_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002099void atomic_wait_explicit(const volatile atomic<_Tp>* __o,
2100 typename atomic<_Tp>::value_type __v,
2101 memory_order __m) _NOEXCEPT
2102 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
2103{
2104 return __o->wait(__v, __m);
2105}
2106
2107template <class _Tp>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002108_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002109void atomic_wait_explicit(const atomic<_Tp>* __o,
2110 typename atomic<_Tp>::value_type __v,
2111 memory_order __m) _NOEXCEPT
2112 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
2113{
2114 return __o->wait(__v, __m);
2115}
2116
2117// atomic_notify_one
2118
2119template <class _Tp>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002120_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002121void atomic_notify_one(volatile atomic<_Tp>* __o) _NOEXCEPT
2122{
2123 __o->notify_one();
2124}
2125template <class _Tp>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002126_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002127void atomic_notify_one(atomic<_Tp>* __o) _NOEXCEPT
2128{
2129 __o->notify_one();
2130}
2131
2132// atomic_notify_one
2133
2134template <class _Tp>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002135_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002136void atomic_notify_all(volatile atomic<_Tp>* __o) _NOEXCEPT
2137{
2138 __o->notify_all();
2139}
2140template <class _Tp>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002141_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002142void atomic_notify_all(atomic<_Tp>* __o) _NOEXCEPT
2143{
2144 __o->notify_all();
2145}
2146
Howard Hinnant138f5922010-12-07 20:46:14 +00002147// atomic_fetch_add
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002148
2149template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002150_LIBCPP_INLINE_VISIBILITY
Mark de Wever494905b2021-06-09 20:26:34 +02002151_Tp
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002152atomic_fetch_add(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002153{
Howard Hinnant138f5922010-12-07 20:46:14 +00002154 return __o->fetch_add(__op);
2155}
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002156
Howard Hinnant138f5922010-12-07 20:46:14 +00002157template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002158_LIBCPP_INLINE_VISIBILITY
Mark de Wever494905b2021-06-09 20:26:34 +02002159_Tp
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002160atomic_fetch_add(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002161{
2162 return __o->fetch_add(__op);
2163}
2164
2165// atomic_fetch_add_explicit
2166
2167template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002168_LIBCPP_INLINE_VISIBILITY
Mark de Wever494905b2021-06-09 20:26:34 +02002169_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 +00002170{
2171 return __o->fetch_add(__op, __m);
2172}
2173
2174template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002175_LIBCPP_INLINE_VISIBILITY
Mark de Wever494905b2021-06-09 20:26:34 +02002176_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 -07002177{
2178 return __o->fetch_add(__op, __m);
2179}
2180
Howard Hinnant138f5922010-12-07 20:46:14 +00002181// atomic_fetch_sub
2182
2183template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002184_LIBCPP_INLINE_VISIBILITY
Mark de Wever494905b2021-06-09 20:26:34 +02002185_Tp atomic_fetch_sub(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002186{
2187 return __o->fetch_sub(__op);
2188}
2189
2190template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002191_LIBCPP_INLINE_VISIBILITY
Mark de Wever494905b2021-06-09 20:26:34 +02002192_Tp atomic_fetch_sub(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT
Olivier Girouxdf485172020-09-11 12:13:35 -07002193{
2194 return __o->fetch_sub(__op);
2195}
2196
Howard Hinnant138f5922010-12-07 20:46:14 +00002197// atomic_fetch_sub_explicit
2198
2199template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002200_LIBCPP_INLINE_VISIBILITY
Mark de Wever494905b2021-06-09 20:26:34 +02002201_Tp atomic_fetch_sub_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002202{
2203 return __o->fetch_sub(__op, __m);
2204}
2205
2206template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002207_LIBCPP_INLINE_VISIBILITY
Mark de Wever494905b2021-06-09 20:26:34 +02002208_Tp atomic_fetch_sub_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT
Olivier Girouxdf485172020-09-11 12:13:35 -07002209{
2210 return __o->fetch_sub(__op, __m);
2211}
2212
Howard Hinnant138f5922010-12-07 20:46:14 +00002213// atomic_fetch_and
2214
2215template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002216_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002217typename enable_if
2218<
2219 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2220 _Tp
2221>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002222atomic_fetch_and(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002223{
2224 return __o->fetch_and(__op);
2225}
2226
2227template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002228_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002229typename enable_if
2230<
2231 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2232 _Tp
2233>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002234atomic_fetch_and(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002235{
2236 return __o->fetch_and(__op);
2237}
2238
2239// atomic_fetch_and_explicit
2240
2241template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002242_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002243typename enable_if
2244<
2245 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2246 _Tp
2247>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002248atomic_fetch_and_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002249{
2250 return __o->fetch_and(__op, __m);
2251}
2252
2253template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002254_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002255typename enable_if
2256<
2257 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2258 _Tp
2259>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002260atomic_fetch_and_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002261{
2262 return __o->fetch_and(__op, __m);
2263}
2264
2265// atomic_fetch_or
2266
2267template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002268_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002269typename enable_if
2270<
2271 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2272 _Tp
2273>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002274atomic_fetch_or(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002275{
2276 return __o->fetch_or(__op);
2277}
2278
2279template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002280_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002281typename enable_if
2282<
2283 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2284 _Tp
2285>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002286atomic_fetch_or(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002287{
2288 return __o->fetch_or(__op);
2289}
2290
2291// atomic_fetch_or_explicit
2292
2293template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002294_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002295typename enable_if
2296<
2297 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2298 _Tp
2299>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002300atomic_fetch_or_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002301{
2302 return __o->fetch_or(__op, __m);
2303}
2304
2305template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002306_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002307typename enable_if
2308<
2309 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2310 _Tp
2311>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002312atomic_fetch_or_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002313{
2314 return __o->fetch_or(__op, __m);
2315}
2316
2317// atomic_fetch_xor
2318
2319template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002320_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002321typename enable_if
2322<
2323 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2324 _Tp
2325>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002326atomic_fetch_xor(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002327{
2328 return __o->fetch_xor(__op);
2329}
2330
2331template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002332_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002333typename enable_if
2334<
2335 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2336 _Tp
2337>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002338atomic_fetch_xor(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002339{
2340 return __o->fetch_xor(__op);
2341}
2342
2343// atomic_fetch_xor_explicit
2344
2345template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002346_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002347typename enable_if
2348<
2349 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2350 _Tp
2351>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002352atomic_fetch_xor_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002353{
2354 return __o->fetch_xor(__op, __m);
2355}
2356
2357template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002358_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002359typename enable_if
2360<
2361 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2362 _Tp
2363>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002364atomic_fetch_xor_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002365{
2366 return __o->fetch_xor(__op, __m);
2367}
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002368
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002369// flag type and operations
2370
2371typedef struct atomic_flag
2372{
Davide Italiano011f80a2019-03-05 18:40:49 +00002373 __cxx_atomic_impl<_LIBCPP_ATOMIC_FLAG_TYPE> __a_;
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002374
2375 _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002376 bool test(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
2377 {return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m);}
2378 _LIBCPP_INLINE_VISIBILITY
2379 bool test(memory_order __m = memory_order_seq_cst) const _NOEXCEPT
2380 {return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m);}
2381
2382 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00002383 bool test_and_set(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00002384 {return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);}
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002385 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00002386 bool test_and_set(memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00002387 {return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);}
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002388 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00002389 void clear(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00002390 {__cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);}
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002391 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00002392 void clear(memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00002393 {__cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);}
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002394
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002395 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002396 void wait(bool __v, memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
2397 {__cxx_atomic_wait(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002398 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002399 void wait(bool __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT
2400 {__cxx_atomic_wait(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002401 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002402 void notify_one() volatile _NOEXCEPT
2403 {__cxx_atomic_notify_one(&__a_);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002404 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002405 void notify_one() _NOEXCEPT
2406 {__cxx_atomic_notify_one(&__a_);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002407 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002408 void notify_all() volatile _NOEXCEPT
2409 {__cxx_atomic_notify_all(&__a_);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002410 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002411 void notify_all() _NOEXCEPT
2412 {__cxx_atomic_notify_all(&__a_);}
2413
Raul Tambre4e0e88f2021-06-06 19:02:20 +03002414#if _LIBCPP_STD_VER > 17
2415 _LIBCPP_INLINE_VISIBILITY constexpr
2416 atomic_flag() _NOEXCEPT : __a_(false) {}
2417#else
Olivier Giroux161e6e82020-02-18 09:58:34 -05002418 _LIBCPP_INLINE_VISIBILITY
Davide Italiano011f80a2019-03-05 18:40:49 +00002419 atomic_flag() _NOEXCEPT _LIBCPP_DEFAULT
Raul Tambre4e0e88f2021-06-06 19:02:20 +03002420#endif
Howard Hinnant3d284222013-05-02 20:18:43 +00002421
Marshall Clowcf990752018-04-25 14:27:29 +00002422 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
Eric Fiselierfec26a92016-05-03 02:12:26 +00002423 atomic_flag(bool __b) _NOEXCEPT : __a_(__b) {} // EXTENSION
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002424
Eric Fiselier2d8515f2017-01-06 20:58:25 +00002425#ifndef _LIBCPP_CXX03_LANG
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002426 atomic_flag(const atomic_flag&) = delete;
2427 atomic_flag& operator=(const atomic_flag&) = delete;
2428 atomic_flag& operator=(const atomic_flag&) volatile = delete;
Eric Fiselier2d8515f2017-01-06 20:58:25 +00002429#else
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002430private:
Olivier Giroux161e6e82020-02-18 09:58:34 -05002431 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002432 atomic_flag(const atomic_flag&);
Olivier Giroux161e6e82020-02-18 09:58:34 -05002433 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002434 atomic_flag& operator=(const atomic_flag&);
Olivier Giroux161e6e82020-02-18 09:58:34 -05002435 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002436 atomic_flag& operator=(const atomic_flag&) volatile;
Eric Fiselier2d8515f2017-01-06 20:58:25 +00002437#endif
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002438} atomic_flag;
2439
Olivier Giroux161e6e82020-02-18 09:58:34 -05002440
2441inline _LIBCPP_INLINE_VISIBILITY
2442bool
2443atomic_flag_test(const volatile atomic_flag* __o) _NOEXCEPT
2444{
2445 return __o->test();
2446}
2447
2448inline _LIBCPP_INLINE_VISIBILITY
2449bool
2450atomic_flag_test(const atomic_flag* __o) _NOEXCEPT
2451{
2452 return __o->test();
2453}
2454
2455inline _LIBCPP_INLINE_VISIBILITY
2456bool
2457atomic_flag_test_explicit(const volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
2458{
2459 return __o->test(__m);
2460}
2461
2462inline _LIBCPP_INLINE_VISIBILITY
2463bool
2464atomic_flag_test_explicit(const atomic_flag* __o, memory_order __m) _NOEXCEPT
2465{
2466 return __o->test(__m);
2467}
2468
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002469inline _LIBCPP_INLINE_VISIBILITY
2470bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00002471atomic_flag_test_and_set(volatile atomic_flag* __o) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002472{
2473 return __o->test_and_set();
2474}
2475
2476inline _LIBCPP_INLINE_VISIBILITY
2477bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00002478atomic_flag_test_and_set(atomic_flag* __o) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002479{
2480 return __o->test_and_set();
2481}
2482
2483inline _LIBCPP_INLINE_VISIBILITY
2484bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00002485atomic_flag_test_and_set_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002486{
2487 return __o->test_and_set(__m);
2488}
2489
2490inline _LIBCPP_INLINE_VISIBILITY
2491bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00002492atomic_flag_test_and_set_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002493{
2494 return __o->test_and_set(__m);
2495}
2496
2497inline _LIBCPP_INLINE_VISIBILITY
2498void
Howard Hinnanteee2c142012-04-11 20:14:21 +00002499atomic_flag_clear(volatile atomic_flag* __o) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002500{
2501 __o->clear();
2502}
2503
2504inline _LIBCPP_INLINE_VISIBILITY
2505void
Howard Hinnanteee2c142012-04-11 20:14:21 +00002506atomic_flag_clear(atomic_flag* __o) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002507{
2508 __o->clear();
2509}
2510
2511inline _LIBCPP_INLINE_VISIBILITY
2512void
Howard Hinnanteee2c142012-04-11 20:14:21 +00002513atomic_flag_clear_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002514{
2515 __o->clear(__m);
2516}
2517
2518inline _LIBCPP_INLINE_VISIBILITY
2519void
Howard Hinnanteee2c142012-04-11 20:14:21 +00002520atomic_flag_clear_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002521{
2522 __o->clear(__m);
2523}
2524
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002525inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
Olivier Giroux161e6e82020-02-18 09:58:34 -05002526void
2527atomic_flag_wait(const volatile atomic_flag* __o, bool __v) _NOEXCEPT
2528{
2529 __o->wait(__v);
2530}
2531
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002532inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
Olivier Giroux161e6e82020-02-18 09:58:34 -05002533void
2534atomic_flag_wait(const atomic_flag* __o, bool __v) _NOEXCEPT
2535{
2536 __o->wait(__v);
2537}
2538
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002539inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
Olivier Giroux161e6e82020-02-18 09:58:34 -05002540void
2541atomic_flag_wait_explicit(const volatile atomic_flag* __o,
2542 bool __v, memory_order __m) _NOEXCEPT
2543{
2544 __o->wait(__v, __m);
2545}
2546
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002547inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
Olivier Giroux161e6e82020-02-18 09:58:34 -05002548void
2549atomic_flag_wait_explicit(const atomic_flag* __o,
2550 bool __v, memory_order __m) _NOEXCEPT
2551{
2552 __o->wait(__v, __m);
2553}
2554
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002555inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
Olivier Giroux161e6e82020-02-18 09:58:34 -05002556void
2557atomic_flag_notify_one(volatile atomic_flag* __o) _NOEXCEPT
2558{
2559 __o->notify_one();
2560}
2561
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002562inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
Olivier Giroux161e6e82020-02-18 09:58:34 -05002563void
2564atomic_flag_notify_one(atomic_flag* __o) _NOEXCEPT
2565{
2566 __o->notify_one();
2567}
2568
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002569inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
Olivier Giroux161e6e82020-02-18 09:58:34 -05002570void
2571atomic_flag_notify_all(volatile atomic_flag* __o) _NOEXCEPT
2572{
2573 __o->notify_all();
2574}
2575
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002576inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
Olivier Giroux161e6e82020-02-18 09:58:34 -05002577void
2578atomic_flag_notify_all(atomic_flag* __o) _NOEXCEPT
2579{
2580 __o->notify_all();
2581}
2582
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002583// fences
2584
2585inline _LIBCPP_INLINE_VISIBILITY
2586void
Howard Hinnanteee2c142012-04-11 20:14:21 +00002587atomic_thread_fence(memory_order __m) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002588{
Davide Italiano011f80a2019-03-05 18:40:49 +00002589 __cxx_atomic_thread_fence(__m);
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002590}
2591
2592inline _LIBCPP_INLINE_VISIBILITY
2593void
Howard Hinnanteee2c142012-04-11 20:14:21 +00002594atomic_signal_fence(memory_order __m) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002595{
Davide Italiano011f80a2019-03-05 18:40:49 +00002596 __cxx_atomic_signal_fence(__m);
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002597}
2598
Howard Hinnant96e4cd62010-12-07 23:24:41 +00002599// Atomics for standard typedef types
2600
Howard Hinnantf0af8d92013-01-04 18:58:50 +00002601typedef atomic<bool> atomic_bool;
Howard Hinnant96e4cd62010-12-07 23:24:41 +00002602typedef atomic<char> atomic_char;
2603typedef atomic<signed char> atomic_schar;
2604typedef atomic<unsigned char> atomic_uchar;
2605typedef atomic<short> atomic_short;
2606typedef atomic<unsigned short> atomic_ushort;
2607typedef atomic<int> atomic_int;
2608typedef atomic<unsigned int> atomic_uint;
2609typedef atomic<long> atomic_long;
2610typedef atomic<unsigned long> atomic_ulong;
2611typedef atomic<long long> atomic_llong;
2612typedef atomic<unsigned long long> atomic_ullong;
Arthur O'Dwyerafa5d5f2021-04-18 21:47:08 -04002613#ifndef _LIBCPP_HAS_NO_CHAR8_T
Marek Kurdej91bebaa2020-11-24 21:07:06 +01002614typedef atomic<char8_t> atomic_char8_t;
2615#endif
Howard Hinnant96e4cd62010-12-07 23:24:41 +00002616typedef atomic<char16_t> atomic_char16_t;
2617typedef atomic<char32_t> atomic_char32_t;
Louis Dionne89258142021-08-23 15:32:36 -04002618#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnant96e4cd62010-12-07 23:24:41 +00002619typedef atomic<wchar_t> atomic_wchar_t;
Louis Dionne89258142021-08-23 15:32:36 -04002620#endif
Howard Hinnant96e4cd62010-12-07 23:24:41 +00002621
2622typedef atomic<int_least8_t> atomic_int_least8_t;
2623typedef atomic<uint_least8_t> atomic_uint_least8_t;
2624typedef atomic<int_least16_t> atomic_int_least16_t;
2625typedef atomic<uint_least16_t> atomic_uint_least16_t;
2626typedef atomic<int_least32_t> atomic_int_least32_t;
2627typedef atomic<uint_least32_t> atomic_uint_least32_t;
2628typedef atomic<int_least64_t> atomic_int_least64_t;
2629typedef atomic<uint_least64_t> atomic_uint_least64_t;
2630
2631typedef atomic<int_fast8_t> atomic_int_fast8_t;
2632typedef atomic<uint_fast8_t> atomic_uint_fast8_t;
2633typedef atomic<int_fast16_t> atomic_int_fast16_t;
2634typedef atomic<uint_fast16_t> atomic_uint_fast16_t;
2635typedef atomic<int_fast32_t> atomic_int_fast32_t;
2636typedef atomic<uint_fast32_t> atomic_uint_fast32_t;
2637typedef atomic<int_fast64_t> atomic_int_fast64_t;
2638typedef atomic<uint_fast64_t> atomic_uint_fast64_t;
2639
Marshall Clowf710afc2016-06-30 15:28:38 +00002640typedef atomic< int8_t> atomic_int8_t;
2641typedef atomic<uint8_t> atomic_uint8_t;
2642typedef atomic< int16_t> atomic_int16_t;
2643typedef atomic<uint16_t> atomic_uint16_t;
2644typedef atomic< int32_t> atomic_int32_t;
2645typedef atomic<uint32_t> atomic_uint32_t;
2646typedef atomic< int64_t> atomic_int64_t;
2647typedef atomic<uint64_t> atomic_uint64_t;
2648
Howard Hinnant96e4cd62010-12-07 23:24:41 +00002649typedef atomic<intptr_t> atomic_intptr_t;
2650typedef atomic<uintptr_t> atomic_uintptr_t;
2651typedef atomic<size_t> atomic_size_t;
2652typedef atomic<ptrdiff_t> atomic_ptrdiff_t;
2653typedef atomic<intmax_t> atomic_intmax_t;
2654typedef atomic<uintmax_t> atomic_uintmax_t;
2655
Olivier Giroux161e6e82020-02-18 09:58:34 -05002656// atomic_*_lock_free : prefer the contention type most highly, then the largest lock-free type
2657
2658#ifdef __cpp_lib_atomic_is_always_lock_free
2659# define _LIBCPP_CONTENTION_LOCK_FREE __atomic_always_lock_free(sizeof(__cxx_contention_t), 0)
2660#else
2661# define _LIBCPP_CONTENTION_LOCK_FREE false
2662#endif
2663
2664#if ATOMIC_LLONG_LOCK_FREE == 2
2665typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, long long>::type __libcpp_signed_lock_free;
2666typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned long long>::type __libcpp_unsigned_lock_free;
2667#elif ATOMIC_INT_LOCK_FREE == 2
2668typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, int>::type __libcpp_signed_lock_free;
2669typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned int>::type __libcpp_unsigned_lock_free;
2670#elif ATOMIC_SHORT_LOCK_FREE == 2
2671typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, short>::type __libcpp_signed_lock_free;
2672typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned short>::type __libcpp_unsigned_lock_free;
2673#elif ATOMIC_CHAR_LOCK_FREE == 2
2674typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, char>::type __libcpp_signed_lock_free;
2675typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned char>::type __libcpp_unsigned_lock_free;
2676#else
2677 // No signed/unsigned lock-free types
2678#endif
2679
2680typedef atomic<__libcpp_signed_lock_free> atomic_signed_lock_free;
2681typedef atomic<__libcpp_unsigned_lock_free> atomic_unsigned_lock_free;
2682
Howard Hinnantf1f066a2010-09-29 21:20:03 +00002683#define ATOMIC_FLAG_INIT {false}
Howard Hinnant953c31d2010-10-04 18:52:54 +00002684#define ATOMIC_VAR_INIT(__v) {__v}
2685
Howard Hinnant71be7292010-09-27 21:17:38 +00002686_LIBCPP_END_NAMESPACE_STD
2687
Louis Dionne2b1ceaa2021-04-20 12:03:32 -04002688#endif // _LIBCPP_ATOMIC