blob: 90bed4f947661a9f87f61c09927583f6a2729b24 [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
70 atomic() noexcept = default;
71 constexpr atomic(T desr) noexcept;
72 atomic(const atomic&) = delete;
73 atomic& operator=(const atomic&) = delete;
74 atomic& operator=(const atomic&) volatile = delete;
75
Howard Hinnanteee2c142012-04-11 20:14:21 +000076 T load(memory_order m = memory_order_seq_cst) const volatile noexcept;
77 T load(memory_order m = memory_order_seq_cst) const noexcept;
78 operator T() const volatile noexcept;
79 operator T() const noexcept;
Olivier Giroux6031a712020-06-01 14:30:13 -070080 void store(T desr, memory_order m = memory_order_seq_cst) volatile noexcept;
81 void store(T desr, memory_order m = memory_order_seq_cst) noexcept;
82 T operator=(T) volatile noexcept;
83 T operator=(T) noexcept;
84
Howard Hinnanteee2c142012-04-11 20:14:21 +000085 T exchange(T desr, memory_order m = memory_order_seq_cst) volatile noexcept;
86 T exchange(T desr, memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +000087 bool compare_exchange_weak(T& expc, T desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +000088 memory_order s, memory_order f) volatile noexcept;
89 bool compare_exchange_weak(T& expc, T desr, memory_order s, memory_order f) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +000090 bool compare_exchange_strong(T& expc, T desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +000091 memory_order s, memory_order f) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +000092 bool compare_exchange_strong(T& expc, T desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +000093 memory_order s, memory_order f) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +000094 bool compare_exchange_weak(T& expc, T desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +000095 memory_order m = memory_order_seq_cst) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +000096 bool compare_exchange_weak(T& expc, T desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +000097 memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +000098 bool compare_exchange_strong(T& expc, T desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +000099 memory_order m = memory_order_seq_cst) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000100 bool compare_exchange_strong(T& expc, T desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000101 memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +0000102
Olivier Giroux6031a712020-06-01 14:30:13 -0700103 void wait(T, memory_order = memory_order::seq_cst) const volatile noexcept;
104 void wait(T, memory_order = memory_order::seq_cst) const noexcept;
105 void notify_one() volatile noexcept;
106 void notify_one() noexcept;
107 void notify_all() volatile noexcept;
108 void notify_all() noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +0000109};
110
111template <>
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000112struct atomic<integral>
Howard Hinnant71be7292010-09-27 21:17:38 +0000113{
Olivier Giroux6031a712020-06-01 14:30:13 -0700114 using value_type = integral;
Olivier Girouxdf5bfa32020-09-09 10:00:09 -0700115 using difference_type = value_type;
Olivier Giroux6031a712020-06-01 14:30:13 -0700116
JF Bastienfdb42c22016-03-25 15:48:21 +0000117 static constexpr bool is_always_lock_free;
Howard Hinnanteee2c142012-04-11 20:14:21 +0000118 bool is_lock_free() const volatile noexcept;
119 bool is_lock_free() const noexcept;
Olivier Giroux6031a712020-06-01 14:30:13 -0700120
121 atomic() noexcept = default;
122 constexpr atomic(integral desr) noexcept;
123 atomic(const atomic&) = delete;
124 atomic& operator=(const atomic&) = delete;
125 atomic& operator=(const atomic&) volatile = delete;
126
Howard Hinnanteee2c142012-04-11 20:14:21 +0000127 integral load(memory_order m = memory_order_seq_cst) const volatile noexcept;
128 integral load(memory_order m = memory_order_seq_cst) const noexcept;
129 operator integral() const volatile noexcept;
130 operator integral() const noexcept;
Olivier Giroux6031a712020-06-01 14:30:13 -0700131 void store(integral desr, memory_order m = memory_order_seq_cst) volatile noexcept;
132 void store(integral desr, memory_order m = memory_order_seq_cst) noexcept;
133 integral operator=(integral desr) volatile noexcept;
134 integral operator=(integral desr) noexcept;
135
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000136 integral exchange(integral desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000137 memory_order m = memory_order_seq_cst) volatile noexcept;
138 integral exchange(integral desr, memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000139 bool compare_exchange_weak(integral& expc, integral desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000140 memory_order s, memory_order f) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000141 bool compare_exchange_weak(integral& expc, integral desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000142 memory_order s, memory_order f) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000143 bool compare_exchange_strong(integral& expc, integral desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000144 memory_order s, memory_order f) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000145 bool compare_exchange_strong(integral& expc, integral desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000146 memory_order s, memory_order f) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000147 bool compare_exchange_weak(integral& expc, integral desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000148 memory_order m = memory_order_seq_cst) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000149 bool compare_exchange_weak(integral& expc, integral desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000150 memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000151 bool compare_exchange_strong(integral& expc, integral desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000152 memory_order m = memory_order_seq_cst) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000153 bool compare_exchange_strong(integral& expc, integral desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000154 memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +0000155
Olivier Giroux6031a712020-06-01 14:30:13 -0700156 integral fetch_add(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
Howard Hinnanteee2c142012-04-11 20:14:21 +0000157 integral fetch_add(integral op, memory_order m = memory_order_seq_cst) noexcept;
Olivier Giroux6031a712020-06-01 14:30:13 -0700158 integral fetch_sub(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
Howard Hinnanteee2c142012-04-11 20:14:21 +0000159 integral fetch_sub(integral op, memory_order m = memory_order_seq_cst) noexcept;
Olivier Giroux6031a712020-06-01 14:30:13 -0700160 integral fetch_and(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
Howard Hinnanteee2c142012-04-11 20:14:21 +0000161 integral fetch_and(integral op, memory_order m = memory_order_seq_cst) noexcept;
Olivier Giroux6031a712020-06-01 14:30:13 -0700162 integral fetch_or(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
Howard Hinnanteee2c142012-04-11 20:14:21 +0000163 integral fetch_or(integral op, memory_order m = memory_order_seq_cst) noexcept;
Olivier Giroux6031a712020-06-01 14:30:13 -0700164 integral fetch_xor(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
Howard Hinnanteee2c142012-04-11 20:14:21 +0000165 integral fetch_xor(integral op, memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +0000166
Howard Hinnanteee2c142012-04-11 20:14:21 +0000167 integral operator++(int) volatile noexcept;
168 integral operator++(int) noexcept;
169 integral operator--(int) volatile noexcept;
170 integral operator--(int) noexcept;
171 integral operator++() volatile noexcept;
172 integral operator++() noexcept;
173 integral operator--() volatile noexcept;
174 integral operator--() noexcept;
175 integral operator+=(integral op) volatile noexcept;
176 integral operator+=(integral op) noexcept;
177 integral operator-=(integral op) volatile noexcept;
178 integral operator-=(integral op) noexcept;
179 integral operator&=(integral op) volatile noexcept;
180 integral operator&=(integral op) noexcept;
181 integral operator|=(integral op) volatile noexcept;
182 integral operator|=(integral op) noexcept;
183 integral operator^=(integral op) volatile noexcept;
184 integral operator^=(integral op) noexcept;
Olivier Giroux6031a712020-06-01 14:30:13 -0700185
186 void wait(integral, memory_order = memory_order::seq_cst) const volatile noexcept;
187 void wait(integral, memory_order = memory_order::seq_cst) const noexcept;
188 void notify_one() volatile noexcept;
189 void notify_one() noexcept;
190 void notify_all() volatile noexcept;
191 void notify_all() noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +0000192};
193
194template <class T>
195struct atomic<T*>
Howard Hinnant71be7292010-09-27 21:17:38 +0000196{
Olivier Giroux6031a712020-06-01 14:30:13 -0700197 using value_type = T*;
Olivier Girouxdf5bfa32020-09-09 10:00:09 -0700198 using difference_type = ptrdiff_t;
Olivier Giroux6031a712020-06-01 14:30:13 -0700199
JF Bastienfdb42c22016-03-25 15:48:21 +0000200 static constexpr bool is_always_lock_free;
Howard Hinnanteee2c142012-04-11 20:14:21 +0000201 bool is_lock_free() const volatile noexcept;
202 bool is_lock_free() const noexcept;
Olivier Giroux6031a712020-06-01 14:30:13 -0700203
204 atomic() noexcept = default;
205 constexpr atomic(T* desr) noexcept;
206 atomic(const atomic&) = delete;
207 atomic& operator=(const atomic&) = delete;
208 atomic& operator=(const atomic&) volatile = delete;
209
Howard Hinnanteee2c142012-04-11 20:14:21 +0000210 T* load(memory_order m = memory_order_seq_cst) const volatile noexcept;
211 T* load(memory_order m = memory_order_seq_cst) const noexcept;
212 operator T*() const volatile noexcept;
213 operator T*() const noexcept;
Olivier Giroux6031a712020-06-01 14:30:13 -0700214 void store(T* desr, memory_order m = memory_order_seq_cst) volatile noexcept;
215 void store(T* desr, memory_order m = memory_order_seq_cst) noexcept;
216 T* operator=(T*) volatile noexcept;
217 T* operator=(T*) noexcept;
218
Howard Hinnanteee2c142012-04-11 20:14:21 +0000219 T* exchange(T* desr, memory_order m = memory_order_seq_cst) volatile noexcept;
220 T* exchange(T* desr, memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000221 bool compare_exchange_weak(T*& expc, T* desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000222 memory_order s, memory_order f) volatile 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) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000225 bool compare_exchange_strong(T*& expc, T* desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000226 memory_order s, memory_order f) volatile 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) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000229 bool compare_exchange_weak(T*& expc, T* desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000230 memory_order m = memory_order_seq_cst) volatile 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) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000233 bool compare_exchange_strong(T*& expc, T* desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000234 memory_order m = memory_order_seq_cst) volatile 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) noexcept;
237 T* fetch_add(ptrdiff_t op, memory_order m = memory_order_seq_cst) volatile noexcept;
238 T* fetch_add(ptrdiff_t op, memory_order m = memory_order_seq_cst) noexcept;
239 T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst) volatile noexcept;
240 T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000241
Howard Hinnanteee2c142012-04-11 20:14:21 +0000242 T* operator++(int) volatile noexcept;
243 T* operator++(int) noexcept;
244 T* operator--(int) volatile noexcept;
245 T* operator--(int) noexcept;
246 T* operator++() volatile noexcept;
247 T* operator++() noexcept;
248 T* operator--() volatile noexcept;
249 T* operator--() noexcept;
250 T* operator+=(ptrdiff_t op) volatile noexcept;
251 T* operator+=(ptrdiff_t op) noexcept;
252 T* operator-=(ptrdiff_t op) volatile noexcept;
253 T* operator-=(ptrdiff_t op) noexcept;
Olivier Giroux6031a712020-06-01 14:30:13 -0700254
255 void wait(T*, memory_order = memory_order::seq_cst) const volatile noexcept;
256 void wait(T*, memory_order = memory_order::seq_cst) const noexcept;
257 void notify_one() volatile noexcept;
258 void notify_one() noexcept;
259 void notify_all() volatile noexcept;
260 void notify_all() noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +0000261};
262
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000263
264template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700265 bool atomic_is_lock_free(const volatile atomic<T>* obj) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000266
267template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700268 bool atomic_is_lock_free(const atomic<T>* obj) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000269
270template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700271 void atomic_store(volatile atomic<T>* obj, T desr) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000272
273template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700274 void atomic_store(atomic<T>* obj, T desr) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000275
276template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700277 void atomic_store_explicit(volatile atomic<T>* obj, T desr, memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000278
279template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700280 void atomic_store_explicit(atomic<T>* obj, T desr, memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000281
282template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700283 T atomic_load(const volatile atomic<T>* obj) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000284
285template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700286 T atomic_load(const atomic<T>* obj) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000287
288template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700289 T atomic_load_explicit(const volatile atomic<T>* obj, memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000290
291template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700292 T atomic_load_explicit(const atomic<T>* obj, memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000293
294template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700295 T atomic_exchange(volatile atomic<T>* obj, T desr) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000296
297template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700298 T atomic_exchange(atomic<T>* obj, T desr) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000299
300template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700301 T atomic_exchange_explicit(volatile atomic<T>* obj, T desr, memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000302
303template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700304 T atomic_exchange_explicit(atomic<T>* obj, T desr, memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000305
306template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700307 bool atomic_compare_exchange_weak(volatile atomic<T>* obj, T* expc, T desr) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000308
309template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700310 bool atomic_compare_exchange_weak(atomic<T>* obj, T* expc, T desr) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000311
312template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700313 bool atomic_compare_exchange_strong(volatile atomic<T>* obj, T* expc, T desr) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000314
315template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700316 bool atomic_compare_exchange_strong(atomic<T>* obj, T* expc, T desr) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000317
318template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700319 bool atomic_compare_exchange_weak_explicit(volatile atomic<T>* obj, T* expc,
320 T desr,
321 memory_order s, memory_order f) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000322
323template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700324 bool atomic_compare_exchange_weak_explicit(atomic<T>* obj, T* expc, T desr,
325 memory_order s, memory_order f) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000326
327template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700328 bool atomic_compare_exchange_strong_explicit(volatile atomic<T>* obj,
329 T* expc, T desr,
330 memory_order s, memory_order f) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000331
332template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700333 bool atomic_compare_exchange_strong_explicit(atomic<T>* obj, T* expc,
334 T desr,
335 memory_order s, memory_order f) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000336
337template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700338 void atomic_wait(const volatile atomic<T>* obj, T old) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000339
340template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700341 void atomic_wait(const atomic<T>* obj, T old) noexcept;
342
343template <class T>
344 void atomic_wait_explicit(const volatile atomic<T>* obj, T old, memory_order m) noexcept;
345
346template <class T>
347 void atomic_wait_explicit(const atomic<T>* obj, T old, memory_order m) noexcept;
348
349template <class T>
350 void atomic_one(volatile atomic<T>* obj) noexcept;
351
352template <class T>
353 void atomic_one(atomic<T>* obj) noexcept;
354
355template <class T>
356 void atomic_all(volatile atomic<T>* obj) noexcept;
357
358template <class T>
359 void atomic_all(atomic<T>* obj) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000360
361template <class Integral>
Olivier Giroux6031a712020-06-01 14:30:13 -0700362 Integral atomic_fetch_add(volatile atomic<Integral>* obj, Integral op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000363
364template <class Integral>
Olivier Giroux6031a712020-06-01 14:30:13 -0700365 Integral atomic_fetch_add(atomic<Integral>* obj, Integral op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000366
367template <class Integral>
Olivier Giroux6031a712020-06-01 14:30:13 -0700368 Integral atomic_fetch_add_explicit(volatile atomic<Integral>* obj, Integral op,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000369 memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000370template <class Integral>
Olivier Giroux6031a712020-06-01 14:30:13 -0700371 Integral atomic_fetch_add_explicit(atomic<Integral>* obj, Integral op,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000372 memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000373template <class Integral>
Olivier Giroux6031a712020-06-01 14:30:13 -0700374 Integral atomic_fetch_sub(volatile atomic<Integral>* obj, Integral op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000375
376template <class Integral>
Olivier Giroux6031a712020-06-01 14:30:13 -0700377 Integral atomic_fetch_sub(atomic<Integral>* obj, Integral op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000378
379template <class Integral>
Olivier Giroux6031a712020-06-01 14:30:13 -0700380 Integral atomic_fetch_sub_explicit(volatile atomic<Integral>* obj, Integral op,
381 memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000382
383template <class Integral>
Olivier Giroux6031a712020-06-01 14:30:13 -0700384 Integral atomic_fetch_sub_explicit(atomic<Integral>* obj, Integral op,
385 memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000386
387template <class Integral>
Olivier Giroux6031a712020-06-01 14:30:13 -0700388 Integral atomic_fetch_and(volatile atomic<Integral>* obj, Integral op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000389
390template <class Integral>
Olivier Giroux6031a712020-06-01 14:30:13 -0700391 Integral atomic_fetch_and(atomic<Integral>* obj, Integral op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000392
393template <class Integral>
Olivier Giroux6031a712020-06-01 14:30:13 -0700394 Integral atomic_fetch_and_explicit(volatile atomic<Integral>* obj, Integral op,
395 memory_order m) noexcept;
396
397template <class Integral>
398 Integral atomic_fetch_and_explicit(atomic<Integral>* obj, Integral op,
399 memory_order m) noexcept;
400
401template <class Integral>
402 Integral atomic_fetch_or(volatile atomic<Integral>* obj, Integral op) noexcept;
403
404template <class Integral>
405 Integral atomic_fetch_or(atomic<Integral>* obj, Integral op) noexcept;
406
407template <class Integral>
408 Integral atomic_fetch_or_explicit(volatile atomic<Integral>* obj, Integral op,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000409 memory_order m) noexcept;
Olivier Giroux6031a712020-06-01 14:30:13 -0700410
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000411template <class Integral>
Olivier Giroux6031a712020-06-01 14:30:13 -0700412 Integral atomic_fetch_or_explicit(atomic<Integral>* obj, Integral op,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000413 memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000414
415template <class Integral>
Olivier Giroux6031a712020-06-01 14:30:13 -0700416 Integral atomic_fetch_xor(volatile atomic<Integral>* obj, Integral op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000417
418template <class Integral>
Olivier Giroux6031a712020-06-01 14:30:13 -0700419 Integral atomic_fetch_xor(atomic<Integral>* obj, Integral op) noexcept;
420
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000421template <class Integral>
Olivier Giroux6031a712020-06-01 14:30:13 -0700422 Integral atomic_fetch_xor_explicit(volatile atomic<Integral>* obj, Integral op,
423 memory_order m) noexcept;
424
425template <class Integral>
426 Integral atomic_fetch_xor_explicit(atomic<Integral>* obj, Integral op,
427 memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000428
429template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700430 T* atomic_fetch_add(volatile atomic<T*>* obj, ptrdiff_t op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000431
432template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700433 T* atomic_fetch_add(atomic<T*>* obj, ptrdiff_t op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000434
435template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700436 T* atomic_fetch_add_explicit(volatile atomic<T*>* obj, ptrdiff_t op,
437 memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000438
439template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700440 T* atomic_fetch_add_explicit(atomic<T*>* obj, ptrdiff_t op, memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000441
442template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700443 T* atomic_fetch_sub(volatile atomic<T*>* obj, ptrdiff_t op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000444
445template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700446 T* atomic_fetch_sub(atomic<T*>* obj, ptrdiff_t op) noexcept;
447
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000448template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700449 T* atomic_fetch_sub_explicit(volatile atomic<T*>* obj, ptrdiff_t op,
450 memory_order m) noexcept;
451
452template <class T>
453 T* atomic_fetch_sub_explicit(atomic<T*>* obj, ptrdiff_t op, memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000454
455// Atomics for standard typedef types
456
Howard Hinnantf0af8d92013-01-04 18:58:50 +0000457typedef atomic<bool> atomic_bool;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000458typedef atomic<char> atomic_char;
459typedef atomic<signed char> atomic_schar;
460typedef atomic<unsigned char> atomic_uchar;
461typedef atomic<short> atomic_short;
462typedef atomic<unsigned short> atomic_ushort;
463typedef atomic<int> atomic_int;
464typedef atomic<unsigned int> atomic_uint;
465typedef atomic<long> atomic_long;
466typedef atomic<unsigned long> atomic_ulong;
467typedef atomic<long long> atomic_llong;
468typedef atomic<unsigned long long> atomic_ullong;
Marek Kurdej91bebaa2020-11-24 21:07:06 +0100469typedef atomic<char8_t> atomic_char8_t; // C++20
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000470typedef atomic<char16_t> atomic_char16_t;
471typedef atomic<char32_t> atomic_char32_t;
472typedef atomic<wchar_t> atomic_wchar_t;
473
474typedef atomic<int_least8_t> atomic_int_least8_t;
475typedef atomic<uint_least8_t> atomic_uint_least8_t;
476typedef atomic<int_least16_t> atomic_int_least16_t;
477typedef atomic<uint_least16_t> atomic_uint_least16_t;
478typedef atomic<int_least32_t> atomic_int_least32_t;
479typedef atomic<uint_least32_t> atomic_uint_least32_t;
480typedef atomic<int_least64_t> atomic_int_least64_t;
481typedef atomic<uint_least64_t> atomic_uint_least64_t;
482
483typedef atomic<int_fast8_t> atomic_int_fast8_t;
484typedef atomic<uint_fast8_t> atomic_uint_fast8_t;
485typedef atomic<int_fast16_t> atomic_int_fast16_t;
486typedef atomic<uint_fast16_t> atomic_uint_fast16_t;
Louis Dionneb39adc52020-11-04 14:07:59 -0500487typedef atomic<int_fast32_t> atomic_int_fast32_t;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000488typedef atomic<uint_fast32_t> atomic_uint_fast32_t;
489typedef atomic<int_fast64_t> atomic_int_fast64_t;
490typedef atomic<uint_fast64_t> atomic_uint_fast64_t;
491
Marshall Clowf710afc2016-06-30 15:28:38 +0000492typedef atomic<int8_t> atomic_int8_t;
493typedef atomic<uint8_t> atomic_uint8_t;
494typedef atomic<int16_t> atomic_int16_t;
495typedef atomic<uint16_t> atomic_uint16_t;
496typedef atomic<int32_t> atomic_int32_t;
497typedef atomic<uint32_t> atomic_uint32_t;
498typedef atomic<int64_t> atomic_int64_t;
499typedef atomic<uint64_t> atomic_uint64_t;
500
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000501typedef atomic<intptr_t> atomic_intptr_t;
502typedef atomic<uintptr_t> atomic_uintptr_t;
503typedef atomic<size_t> atomic_size_t;
504typedef atomic<ptrdiff_t> atomic_ptrdiff_t;
505typedef atomic<intmax_t> atomic_intmax_t;
506typedef atomic<uintmax_t> atomic_uintmax_t;
507
Olivier Giroux6031a712020-06-01 14:30:13 -0700508// flag type and operations
509
510typedef struct atomic_flag
511{
512 atomic_flag() noexcept = default;
513 atomic_flag(const atomic_flag&) = delete;
514 atomic_flag& operator=(const atomic_flag&) = delete;
515 atomic_flag& operator=(const atomic_flag&) volatile = delete;
516
517 bool test(memory_order m = memory_order_seq_cst) volatile noexcept;
518 bool test(memory_order m = memory_order_seq_cst) noexcept;
519 bool test_and_set(memory_order m = memory_order_seq_cst) volatile noexcept;
520 bool test_and_set(memory_order m = memory_order_seq_cst) noexcept;
521 void clear(memory_order m = memory_order_seq_cst) volatile noexcept;
522 void clear(memory_order m = memory_order_seq_cst) noexcept;
523
524 void wait(bool, memory_order = memory_order::seq_cst) const volatile noexcept;
525 void wait(bool, memory_order = memory_order::seq_cst) const noexcept;
526 void notify_one() volatile noexcept;
527 void notify_one() noexcept;
528 void notify_all() volatile noexcept;
529 void notify_all() noexcept;
530} atomic_flag;
531
532bool atomic_flag_test(volatile atomic_flag* obj) noexcept;
533bool atomic_flag_test(atomic_flag* obj) noexcept;
534bool atomic_flag_test_explicit(volatile atomic_flag* obj,
535 memory_order m) noexcept;
536bool atomic_flag_test_explicit(atomic_flag* obj, memory_order m) noexcept;
537bool atomic_flag_test_and_set(volatile atomic_flag* obj) noexcept;
538bool atomic_flag_test_and_set(atomic_flag* obj) noexcept;
539bool atomic_flag_test_and_set_explicit(volatile atomic_flag* obj,
540 memory_order m) noexcept;
541bool atomic_flag_test_and_set_explicit(atomic_flag* obj, memory_order m) noexcept;
542void atomic_flag_clear(volatile atomic_flag* obj) noexcept;
543void atomic_flag_clear(atomic_flag* obj) noexcept;
544void atomic_flag_clear_explicit(volatile atomic_flag* obj, memory_order m) noexcept;
545void atomic_flag_clear_explicit(atomic_flag* obj, memory_order m) noexcept;
546
547void atomic_wait(const volatile atomic_flag* obj, T old) noexcept;
548void atomic_wait(const atomic_flag* obj, T old) noexcept;
549void atomic_wait_explicit(const volatile atomic_flag* obj, T old, memory_order m) noexcept;
550void atomic_wait_explicit(const atomic_flag* obj, T old, memory_order m) noexcept;
551void atomic_one(volatile atomic_flag* obj) noexcept;
552void atomic_one(atomic_flag* obj) noexcept;
553void atomic_all(volatile atomic_flag* obj) noexcept;
554void atomic_all(atomic_flag* obj) noexcept;
555
Howard Hinnant71be7292010-09-27 21:17:38 +0000556// fences
557
Howard Hinnanteee2c142012-04-11 20:14:21 +0000558void atomic_thread_fence(memory_order m) noexcept;
559void atomic_signal_fence(memory_order m) noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +0000560
Olivier Giroux6031a712020-06-01 14:30:13 -0700561// deprecated
562
563template <class T>
564 void atomic_init(volatile atomic<T>* obj, typename atomic<T>::value_type desr) noexcept;
565
566template <class T>
567 void atomic_init(atomic<T>* obj, typename atomic<T>::value_type desr) noexcept;
568
569#define ATOMIC_VAR_INIT(value) see below
570
571#define ATOMIC_FLAG_INIT see below
572
Howard Hinnant71be7292010-09-27 21:17:38 +0000573} // std
574
575*/
576
Louis Dionne73912b22020-11-04 15:01:25 -0500577#include <__availability>
Arthur O'Dwyeref181602021-05-19 11:57:04 -0400578#include <__config>
Olivier Giroux161e6e82020-02-18 09:58:34 -0500579#include <__threading_support>
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000580#include <cstddef>
581#include <cstdint>
Olivier Giroux161e6e82020-02-18 09:58:34 -0500582#include <cstring>
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000583#include <type_traits>
Marshall Clow0a1e7502018-09-12 19:41:40 +0000584#include <version>
Howard Hinnant71be7292010-09-27 21:17:38 +0000585
Howard Hinnantaaaa52b2011-10-17 20:05:10 +0000586#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
Howard Hinnant71be7292010-09-27 21:17:38 +0000587#pragma GCC system_header
Howard Hinnantaaaa52b2011-10-17 20:05:10 +0000588#endif
Howard Hinnant71be7292010-09-27 21:17:38 +0000589
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000590#ifdef _LIBCPP_HAS_NO_THREADS
Davide Italiano011f80a2019-03-05 18:40:49 +0000591# error <atomic> is not supported on this single threaded system
Eric Fiselier8020b6c2015-08-19 17:21:46 +0000592#endif
Davide Italiano011f80a2019-03-05 18:40:49 +0000593#ifdef _LIBCPP_HAS_NO_ATOMIC_HEADER
594# error <atomic> is not implemented
Eric Fiselier8020b6c2015-08-19 17:21:46 +0000595#endif
Volodymyr Sapsaif3ed1fd2018-05-15 22:38:31 +0000596#ifdef kill_dependency
Davide Italiano011f80a2019-03-05 18:40:49 +0000597# error C++ standard library is incompatible with <stdatomic.h>
Volodymyr Sapsaif3ed1fd2018-05-15 22:38:31 +0000598#endif
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000599
Eric Fiselierb5ab51d2017-01-13 23:45:39 +0000600#define _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) \
601 _LIBCPP_DIAGNOSE_WARNING(__m == memory_order_consume || \
602 __m == memory_order_acquire || \
603 __m == memory_order_acq_rel, \
604 "memory order argument to atomic operation is invalid")
605
606#define _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) \
607 _LIBCPP_DIAGNOSE_WARNING(__m == memory_order_release || \
608 __m == memory_order_acq_rel, \
609 "memory order argument to atomic operation is invalid")
610
611#define _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__m, __f) \
612 _LIBCPP_DIAGNOSE_WARNING(__f == memory_order_release || \
613 __f == memory_order_acq_rel, \
614 "memory order argument to atomic operation is invalid")
615
Howard Hinnant71be7292010-09-27 21:17:38 +0000616_LIBCPP_BEGIN_NAMESPACE_STD
617
Eric Fiselierd4e3e5b2019-03-08 23:15:54 +0000618// Figure out what the underlying type for `memory_order` would be if it were
619// declared as an unscoped enum (accounting for -fshort-enums). Use this result
620// to pin the underlying type in C++20.
621enum __legacy_memory_order {
622 __mo_relaxed,
623 __mo_consume,
624 __mo_acquire,
625 __mo_release,
626 __mo_acq_rel,
627 __mo_seq_cst
628};
629
630typedef underlying_type<__legacy_memory_order>::type __memory_order_underlying_t;
631
Davide Italiano011f80a2019-03-05 18:40:49 +0000632#if _LIBCPP_STD_VER > 17
633
Eric Fiselierd4e3e5b2019-03-08 23:15:54 +0000634enum class memory_order : __memory_order_underlying_t {
635 relaxed = __mo_relaxed,
636 consume = __mo_consume,
637 acquire = __mo_acquire,
638 release = __mo_release,
639 acq_rel = __mo_acq_rel,
640 seq_cst = __mo_seq_cst
Davide Italiano011f80a2019-03-05 18:40:49 +0000641};
642
643inline constexpr auto memory_order_relaxed = memory_order::relaxed;
644inline constexpr auto memory_order_consume = memory_order::consume;
645inline constexpr auto memory_order_acquire = memory_order::acquire;
646inline constexpr auto memory_order_release = memory_order::release;
647inline constexpr auto memory_order_acq_rel = memory_order::acq_rel;
648inline constexpr auto memory_order_seq_cst = memory_order::seq_cst;
649
Davide Italiano011f80a2019-03-05 18:40:49 +0000650#else
651
652typedef enum memory_order {
Eric Fiselierd4e3e5b2019-03-08 23:15:54 +0000653 memory_order_relaxed = __mo_relaxed,
654 memory_order_consume = __mo_consume,
655 memory_order_acquire = __mo_acquire,
656 memory_order_release = __mo_release,
657 memory_order_acq_rel = __mo_acq_rel,
658 memory_order_seq_cst = __mo_seq_cst,
Howard Hinnantdca6e712010-09-28 17:13:38 +0000659} memory_order;
660
Davide Italiano011f80a2019-03-05 18:40:49 +0000661#endif // _LIBCPP_STD_VER > 17
662
Olivier Giroux161e6e82020-02-18 09:58:34 -0500663template <typename _Tp> _LIBCPP_INLINE_VISIBILITY
664bool __cxx_nonatomic_compare_equal(_Tp const& __lhs, _Tp const& __rhs) {
Arthur O'Dwyer22236632020-12-07 21:50:15 -0500665 return _VSTD::memcmp(&__lhs, &__rhs, sizeof(_Tp)) == 0;
Olivier Giroux161e6e82020-02-18 09:58:34 -0500666}
667
Eric Fiselier51525172019-03-08 23:30:26 +0000668static_assert((is_same<underlying_type<memory_order>::type, __memory_order_underlying_t>::value),
Eric Fiselierd4e3e5b2019-03-08 23:15:54 +0000669 "unexpected underlying type for std::memory_order");
Davide Italiano011f80a2019-03-05 18:40:49 +0000670
671#if defined(_LIBCPP_HAS_GCC_ATOMIC_IMP) || \
Arthur O'Dwyer2fc9b5d2021-04-17 17:03:20 -0400672 defined(_LIBCPP_ATOMIC_ONLY_USE_BUILTINS)
Davide Italiano011f80a2019-03-05 18:40:49 +0000673
674// [atomics.types.generic]p1 guarantees _Tp is trivially copyable. Because
675// the default operator= in an object is not volatile, a byte-by-byte copy
676// is required.
677template <typename _Tp, typename _Tv> _LIBCPP_INLINE_VISIBILITY
678typename enable_if<is_assignable<_Tp&, _Tv>::value>::type
679__cxx_atomic_assign_volatile(_Tp& __a_value, _Tv const& __val) {
680 __a_value = __val;
681}
682template <typename _Tp, typename _Tv> _LIBCPP_INLINE_VISIBILITY
683typename enable_if<is_assignable<_Tp&, _Tv>::value>::type
684__cxx_atomic_assign_volatile(_Tp volatile& __a_value, _Tv volatile const& __val) {
685 volatile char* __to = reinterpret_cast<volatile char*>(&__a_value);
686 volatile char* __end = __to + sizeof(_Tp);
687 volatile const char* __from = reinterpret_cast<volatile const char*>(&__val);
688 while (__to != __end)
689 *__to++ = *__from++;
690}
691
Davide Italiano31f218a2019-03-05 17:38:33 +0000692#endif
Louis Dionnea1ae0032019-03-04 15:26:27 +0000693
Davide Italiano011f80a2019-03-05 18:40:49 +0000694#if defined(_LIBCPP_HAS_GCC_ATOMIC_IMP)
695
696template <typename _Tp>
697struct __cxx_atomic_base_impl {
698
Eric Fiselier684aaca2015-10-14 08:36:22 +0000699 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier07b2b552016-11-18 06:42:17 +0000700#ifndef _LIBCPP_CXX03_LANG
Davide Italiano011f80a2019-03-05 18:40:49 +0000701 __cxx_atomic_base_impl() _NOEXCEPT = default;
Eric Fiselier684aaca2015-10-14 08:36:22 +0000702#else
Davide Italiano011f80a2019-03-05 18:40:49 +0000703 __cxx_atomic_base_impl() _NOEXCEPT : __a_value() {}
Eric Fiselier07b2b552016-11-18 06:42:17 +0000704#endif // _LIBCPP_CXX03_LANG
Davide Italiano011f80a2019-03-05 18:40:49 +0000705 _LIBCPP_CONSTEXPR explicit __cxx_atomic_base_impl(_Tp value) _NOEXCEPT
Eric Fiselier719e0442015-07-14 17:50:27 +0000706 : __a_value(value) {}
Marshall Clow290eb3f2015-01-11 06:15:59 +0000707 _Tp __a_value;
Dan Albert7b65ace2014-08-09 23:51:51 +0000708};
Dan Albert7b65ace2014-08-09 23:51:51 +0000709
Davide Italiano011f80a2019-03-05 18:40:49 +0000710_LIBCPP_INLINE_VISIBILITY inline _LIBCPP_CONSTEXPR int __to_gcc_order(memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000711 // Avoid switch statement to make this a constexpr.
712 return __order == memory_order_relaxed ? __ATOMIC_RELAXED:
713 (__order == memory_order_acquire ? __ATOMIC_ACQUIRE:
714 (__order == memory_order_release ? __ATOMIC_RELEASE:
715 (__order == memory_order_seq_cst ? __ATOMIC_SEQ_CST:
716 (__order == memory_order_acq_rel ? __ATOMIC_ACQ_REL:
717 __ATOMIC_CONSUME))));
718}
719
Davide Italiano011f80a2019-03-05 18:40:49 +0000720_LIBCPP_INLINE_VISIBILITY inline _LIBCPP_CONSTEXPR int __to_gcc_failure_order(memory_order __order) {
Dan Albert48815f22015-01-06 18:39:37 +0000721 // Avoid switch statement to make this a constexpr.
722 return __order == memory_order_relaxed ? __ATOMIC_RELAXED:
723 (__order == memory_order_acquire ? __ATOMIC_ACQUIRE:
724 (__order == memory_order_release ? __ATOMIC_RELAXED:
725 (__order == memory_order_seq_cst ? __ATOMIC_SEQ_CST:
726 (__order == memory_order_acq_rel ? __ATOMIC_ACQUIRE:
727 __ATOMIC_CONSUME))));
728}
729
Davide Italiano011f80a2019-03-05 18:40:49 +0000730template <typename _Tp>
731_LIBCPP_INLINE_VISIBILITY
732void __cxx_atomic_init(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __val) {
733 __cxx_atomic_assign_volatile(__a->__a_value, __val);
734}
Dan Albert7b65ace2014-08-09 23:51:51 +0000735
736template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000737_LIBCPP_INLINE_VISIBILITY
738void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp>* __a, _Tp __val) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000739 __a->__a_value = __val;
740}
741
Davide Italiano011f80a2019-03-05 18:40:49 +0000742_LIBCPP_INLINE_VISIBILITY inline
743void __cxx_atomic_thread_fence(memory_order __order) {
744 __atomic_thread_fence(__to_gcc_order(__order));
745}
746
747_LIBCPP_INLINE_VISIBILITY inline
748void __cxx_atomic_signal_fence(memory_order __order) {
749 __atomic_signal_fence(__to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000750}
751
752template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000753_LIBCPP_INLINE_VISIBILITY
754void __cxx_atomic_store(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __val,
755 memory_order __order) {
Dan Albert48815f22015-01-06 18:39:37 +0000756 __atomic_store(&__a->__a_value, &__val,
Davide Italiano011f80a2019-03-05 18:40:49 +0000757 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000758}
759
760template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000761_LIBCPP_INLINE_VISIBILITY
762void __cxx_atomic_store(__cxx_atomic_base_impl<_Tp>* __a, _Tp __val,
763 memory_order __order) {
764 __atomic_store(&__a->__a_value, &__val,
765 __to_gcc_order(__order));
766}
767
768template <typename _Tp>
769_LIBCPP_INLINE_VISIBILITY
770_Tp __cxx_atomic_load(const volatile __cxx_atomic_base_impl<_Tp>* __a,
771 memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000772 _Tp __ret;
773 __atomic_load(&__a->__a_value, &__ret,
Davide Italiano011f80a2019-03-05 18:40:49 +0000774 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000775 return __ret;
776}
777
778template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000779_LIBCPP_INLINE_VISIBILITY
780_Tp __cxx_atomic_load(const __cxx_atomic_base_impl<_Tp>* __a, memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000781 _Tp __ret;
782 __atomic_load(&__a->__a_value, &__ret,
Davide Italiano011f80a2019-03-05 18:40:49 +0000783 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000784 return __ret;
785}
786
787template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000788_LIBCPP_INLINE_VISIBILITY
789_Tp __cxx_atomic_exchange(volatile __cxx_atomic_base_impl<_Tp>* __a,
790 _Tp __value, memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000791 _Tp __ret;
792 __atomic_exchange(&__a->__a_value, &__value, &__ret,
Davide Italiano011f80a2019-03-05 18:40:49 +0000793 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000794 return __ret;
795}
796
797template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000798_LIBCPP_INLINE_VISIBILITY
799_Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp>* __a, _Tp __value,
800 memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000801 _Tp __ret;
802 __atomic_exchange(&__a->__a_value, &__value, &__ret,
Davide Italiano011f80a2019-03-05 18:40:49 +0000803 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000804 return __ret;
805}
806
807template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000808_LIBCPP_INLINE_VISIBILITY
809bool __cxx_atomic_compare_exchange_strong(
810 volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value,
JF Bastien6e412d92018-05-26 19:44:45 +0000811 memory_order __success, memory_order __failure) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000812 return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
813 false,
Davide Italiano011f80a2019-03-05 18:40:49 +0000814 __to_gcc_order(__success),
815 __to_gcc_failure_order(__failure));
Dan Albert7b65ace2014-08-09 23:51:51 +0000816}
817
818template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000819_LIBCPP_INLINE_VISIBILITY
820bool __cxx_atomic_compare_exchange_strong(
821 __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success,
JF Bastien6e412d92018-05-26 19:44:45 +0000822 memory_order __failure) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000823 return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
824 false,
Davide Italiano011f80a2019-03-05 18:40:49 +0000825 __to_gcc_order(__success),
826 __to_gcc_failure_order(__failure));
Dan Albert7b65ace2014-08-09 23:51:51 +0000827}
828
829template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000830_LIBCPP_INLINE_VISIBILITY
831bool __cxx_atomic_compare_exchange_weak(
832 volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value,
JF Bastien6e412d92018-05-26 19:44:45 +0000833 memory_order __success, memory_order __failure) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000834 return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
835 true,
Davide Italiano011f80a2019-03-05 18:40:49 +0000836 __to_gcc_order(__success),
837 __to_gcc_failure_order(__failure));
Dan Albert7b65ace2014-08-09 23:51:51 +0000838}
839
840template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000841_LIBCPP_INLINE_VISIBILITY
842bool __cxx_atomic_compare_exchange_weak(
843 __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success,
JF Bastien6e412d92018-05-26 19:44:45 +0000844 memory_order __failure) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000845 return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
846 true,
Davide Italiano011f80a2019-03-05 18:40:49 +0000847 __to_gcc_order(__success),
848 __to_gcc_failure_order(__failure));
Dan Albert7b65ace2014-08-09 23:51:51 +0000849}
850
851template <typename _Tp>
852struct __skip_amt { enum {value = 1}; };
853
854template <typename _Tp>
855struct __skip_amt<_Tp*> { enum {value = sizeof(_Tp)}; };
856
857// FIXME: Haven't figured out what the spec says about using arrays with
858// atomic_fetch_add. Force a failure rather than creating bad behavior.
859template <typename _Tp>
860struct __skip_amt<_Tp[]> { };
861template <typename _Tp, int n>
862struct __skip_amt<_Tp[n]> { };
863
864template <typename _Tp, typename _Td>
Davide Italiano011f80a2019-03-05 18:40:49 +0000865_LIBCPP_INLINE_VISIBILITY
866_Tp __cxx_atomic_fetch_add(volatile __cxx_atomic_base_impl<_Tp>* __a,
867 _Td __delta, memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000868 return __atomic_fetch_add(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
Davide Italiano011f80a2019-03-05 18:40:49 +0000869 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000870}
871
872template <typename _Tp, typename _Td>
Davide Italiano011f80a2019-03-05 18:40:49 +0000873_LIBCPP_INLINE_VISIBILITY
874_Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp>* __a, _Td __delta,
875 memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000876 return __atomic_fetch_add(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
Davide Italiano011f80a2019-03-05 18:40:49 +0000877 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000878}
879
880template <typename _Tp, typename _Td>
Davide Italiano011f80a2019-03-05 18:40:49 +0000881_LIBCPP_INLINE_VISIBILITY
882_Tp __cxx_atomic_fetch_sub(volatile __cxx_atomic_base_impl<_Tp>* __a,
883 _Td __delta, memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000884 return __atomic_fetch_sub(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
Davide Italiano011f80a2019-03-05 18:40:49 +0000885 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000886}
887
888template <typename _Tp, typename _Td>
Davide Italiano011f80a2019-03-05 18:40:49 +0000889_LIBCPP_INLINE_VISIBILITY
890_Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp>* __a, _Td __delta,
891 memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000892 return __atomic_fetch_sub(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
Davide Italiano011f80a2019-03-05 18:40:49 +0000893 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000894}
895
896template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000897_LIBCPP_INLINE_VISIBILITY
898_Tp __cxx_atomic_fetch_and(volatile __cxx_atomic_base_impl<_Tp>* __a,
899 _Tp __pattern, memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000900 return __atomic_fetch_and(&__a->__a_value, __pattern,
Davide Italiano011f80a2019-03-05 18:40:49 +0000901 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000902}
903
904template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000905_LIBCPP_INLINE_VISIBILITY
906_Tp __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp>* __a,
907 _Tp __pattern, memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000908 return __atomic_fetch_and(&__a->__a_value, __pattern,
Davide Italiano011f80a2019-03-05 18:40:49 +0000909 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000910}
911
912template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000913_LIBCPP_INLINE_VISIBILITY
914_Tp __cxx_atomic_fetch_or(volatile __cxx_atomic_base_impl<_Tp>* __a,
915 _Tp __pattern, memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000916 return __atomic_fetch_or(&__a->__a_value, __pattern,
Davide Italiano011f80a2019-03-05 18:40:49 +0000917 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000918}
919
920template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000921_LIBCPP_INLINE_VISIBILITY
922_Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern,
923 memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000924 return __atomic_fetch_or(&__a->__a_value, __pattern,
Davide Italiano011f80a2019-03-05 18:40:49 +0000925 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000926}
927
928template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000929_LIBCPP_INLINE_VISIBILITY
930_Tp __cxx_atomic_fetch_xor(volatile __cxx_atomic_base_impl<_Tp>* __a,
931 _Tp __pattern, memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000932 return __atomic_fetch_xor(&__a->__a_value, __pattern,
Davide Italiano011f80a2019-03-05 18:40:49 +0000933 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000934}
935
936template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000937_LIBCPP_INLINE_VISIBILITY
938_Tp __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern,
939 memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000940 return __atomic_fetch_xor(&__a->__a_value, __pattern,
Davide Italiano011f80a2019-03-05 18:40:49 +0000941 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000942}
Davide Italiano011f80a2019-03-05 18:40:49 +0000943
944#define __cxx_atomic_is_lock_free(__s) __atomic_is_lock_free(__s, 0)
945
946#elif defined(_LIBCPP_HAS_C_ATOMIC_IMP)
947
948template <typename _Tp>
949struct __cxx_atomic_base_impl {
950
951 _LIBCPP_INLINE_VISIBILITY
952#ifndef _LIBCPP_CXX03_LANG
953 __cxx_atomic_base_impl() _NOEXCEPT = default;
954#else
955 __cxx_atomic_base_impl() _NOEXCEPT : __a_value() {}
956#endif // _LIBCPP_CXX03_LANG
957 _LIBCPP_CONSTEXPR explicit __cxx_atomic_base_impl(_Tp value) _NOEXCEPT
958 : __a_value(value) {}
Louis Dionnefaa17452019-09-04 12:44:19 +0000959 _LIBCPP_DISABLE_EXTENSION_WARNING _Atomic(_Tp) __a_value;
Davide Italiano011f80a2019-03-05 18:40:49 +0000960};
961
962#define __cxx_atomic_is_lock_free(__s) __c11_atomic_is_lock_free(__s)
963
964_LIBCPP_INLINE_VISIBILITY inline
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000965void __cxx_atomic_thread_fence(memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +0000966 __c11_atomic_thread_fence(static_cast<__memory_order_underlying_t>(__order));
967}
968
969_LIBCPP_INLINE_VISIBILITY inline
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000970void __cxx_atomic_signal_fence(memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +0000971 __c11_atomic_signal_fence(static_cast<__memory_order_underlying_t>(__order));
972}
973
974template<class _Tp>
975_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000976void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __val) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +0000977 __c11_atomic_init(&__a->__a_value, __val);
978}
979template<class _Tp>
980_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000981void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp> * __a, _Tp __val) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +0000982 __c11_atomic_init(&__a->__a_value, __val);
983}
984
985template<class _Tp>
986_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000987void __cxx_atomic_store(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __val, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +0000988 __c11_atomic_store(&__a->__a_value, __val, static_cast<__memory_order_underlying_t>(__order));
989}
990template<class _Tp>
991_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000992void __cxx_atomic_store(__cxx_atomic_base_impl<_Tp> * __a, _Tp __val, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +0000993 __c11_atomic_store(&__a->__a_value, __val, static_cast<__memory_order_underlying_t>(__order));
994}
995
996template<class _Tp>
997_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000998_Tp __cxx_atomic_load(__cxx_atomic_base_impl<_Tp> const volatile* __a, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +0000999 using __ptr_type = typename remove_const<decltype(__a->__a_value)>::type*;
1000 return __c11_atomic_load(const_cast<__ptr_type>(&__a->__a_value), static_cast<__memory_order_underlying_t>(__order));
1001}
1002template<class _Tp>
1003_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001004_Tp __cxx_atomic_load(__cxx_atomic_base_impl<_Tp> const* __a, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +00001005 using __ptr_type = typename remove_const<decltype(__a->__a_value)>::type*;
1006 return __c11_atomic_load(const_cast<__ptr_type>(&__a->__a_value), static_cast<__memory_order_underlying_t>(__order));
1007}
1008
1009template<class _Tp>
1010_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001011_Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __value, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +00001012 return __c11_atomic_exchange(&__a->__a_value, __value, static_cast<__memory_order_underlying_t>(__order));
1013}
1014template<class _Tp>
1015_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001016_Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp> * __a, _Tp __value, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +00001017 return __c11_atomic_exchange(&__a->__a_value, __value, static_cast<__memory_order_underlying_t>(__order));
1018}
1019
Jordan Rupprechtd2e31a82021-06-15 07:55:23 -07001020_LIBCPP_INLINE_VISIBILITY inline _LIBCPP_CONSTEXPR memory_order __to_failure_order(memory_order __order) {
1021 // Avoid switch statement to make this a constexpr.
1022 return __order == memory_order_release ? memory_order_relaxed:
1023 (__order == memory_order_acq_rel ? memory_order_acquire:
1024 __order);
1025}
1026
Davide Italiano011f80a2019-03-05 18:40:49 +00001027template<class _Tp>
1028_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001029bool __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 -07001030 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 +00001031}
1032template<class _Tp>
1033_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001034bool __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 -07001035 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 +00001036}
1037
1038template<class _Tp>
1039_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001040bool __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 -07001041 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 +00001042}
1043template<class _Tp>
1044_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001045bool __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 -07001046 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 +00001047}
1048
1049template<class _Tp>
1050_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001051_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 +00001052 return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
1053}
1054template<class _Tp>
1055_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001056_Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp> * __a, _Tp __delta, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +00001057 return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
1058}
1059
1060template<class _Tp>
1061_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001062_Tp* __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp*> volatile* __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +00001063 return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
1064}
1065template<class _Tp>
1066_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001067_Tp* __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp*> * __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +00001068 return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
1069}
1070
1071template<class _Tp>
1072_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001073_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 +00001074 return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
1075}
1076template<class _Tp>
1077_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001078_Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp> * __a, _Tp __delta, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +00001079 return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
1080}
1081template<class _Tp>
1082_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001083_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 +00001084 return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
1085}
1086template<class _Tp>
1087_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001088_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 +00001089 return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
1090}
1091
1092template<class _Tp>
1093_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001094_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 +00001095 return __c11_atomic_fetch_and(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
1096}
1097template<class _Tp>
1098_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001099_Tp __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +00001100 return __c11_atomic_fetch_and(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
1101}
1102
1103template<class _Tp>
1104_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001105_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 +00001106 return __c11_atomic_fetch_or(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
1107}
1108template<class _Tp>
1109_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001110_Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +00001111 return __c11_atomic_fetch_or(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
1112}
1113
1114template<class _Tp>
1115_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001116_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 +00001117 return __c11_atomic_fetch_xor(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
1118}
1119template<class _Tp>
1120_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001121_Tp __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +00001122 return __c11_atomic_fetch_xor(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
1123}
1124
1125#endif // _LIBCPP_HAS_GCC_ATOMIC_IMP, _LIBCPP_HAS_C_ATOMIC_IMP
Dan Albert7b65ace2014-08-09 23:51:51 +00001126
Howard Hinnantdca6e712010-09-28 17:13:38 +00001127template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001128_LIBCPP_INLINE_VISIBILITY
1129_Tp kill_dependency(_Tp __y) _NOEXCEPT
Howard Hinnantdca6e712010-09-28 17:13:38 +00001130{
1131 return __y;
1132}
Howard Hinnant71be7292010-09-27 21:17:38 +00001133
Eric Fiselierbed42df2017-04-20 23:22:46 +00001134#if defined(__CLANG_ATOMIC_BOOL_LOCK_FREE)
1135# define ATOMIC_BOOL_LOCK_FREE __CLANG_ATOMIC_BOOL_LOCK_FREE
1136# define ATOMIC_CHAR_LOCK_FREE __CLANG_ATOMIC_CHAR_LOCK_FREE
Arthur O'Dwyerafa5d5f2021-04-18 21:47:08 -04001137#ifndef _LIBCPP_HAS_NO_CHAR8_T
Marek Kurdej91bebaa2020-11-24 21:07:06 +01001138# define ATOMIC_CHAR8_T_LOCK_FREE __CLANG_ATOMIC_CHAR8_T_LOCK_FREE
1139#endif
Eric Fiselierbed42df2017-04-20 23:22:46 +00001140# define ATOMIC_CHAR16_T_LOCK_FREE __CLANG_ATOMIC_CHAR16_T_LOCK_FREE
1141# define ATOMIC_CHAR32_T_LOCK_FREE __CLANG_ATOMIC_CHAR32_T_LOCK_FREE
1142# define ATOMIC_WCHAR_T_LOCK_FREE __CLANG_ATOMIC_WCHAR_T_LOCK_FREE
1143# define ATOMIC_SHORT_LOCK_FREE __CLANG_ATOMIC_SHORT_LOCK_FREE
1144# define ATOMIC_INT_LOCK_FREE __CLANG_ATOMIC_INT_LOCK_FREE
1145# define ATOMIC_LONG_LOCK_FREE __CLANG_ATOMIC_LONG_LOCK_FREE
1146# define ATOMIC_LLONG_LOCK_FREE __CLANG_ATOMIC_LLONG_LOCK_FREE
1147# define ATOMIC_POINTER_LOCK_FREE __CLANG_ATOMIC_POINTER_LOCK_FREE
Davide Italiano011f80a2019-03-05 18:40:49 +00001148#elif defined(__GCC_ATOMIC_BOOL_LOCK_FREE)
Eric Fiselierbed42df2017-04-20 23:22:46 +00001149# define ATOMIC_BOOL_LOCK_FREE __GCC_ATOMIC_BOOL_LOCK_FREE
1150# define ATOMIC_CHAR_LOCK_FREE __GCC_ATOMIC_CHAR_LOCK_FREE
Arthur O'Dwyerafa5d5f2021-04-18 21:47:08 -04001151#ifndef _LIBCPP_HAS_NO_CHAR8_T
Marek Kurdej91bebaa2020-11-24 21:07:06 +01001152# define ATOMIC_CHAR8_T_LOCK_FREE __GCC_ATOMIC_CHAR8_T_LOCK_FREE
1153#endif
Eric Fiselierbed42df2017-04-20 23:22:46 +00001154# define ATOMIC_CHAR16_T_LOCK_FREE __GCC_ATOMIC_CHAR16_T_LOCK_FREE
1155# define ATOMIC_CHAR32_T_LOCK_FREE __GCC_ATOMIC_CHAR32_T_LOCK_FREE
1156# define ATOMIC_WCHAR_T_LOCK_FREE __GCC_ATOMIC_WCHAR_T_LOCK_FREE
1157# define ATOMIC_SHORT_LOCK_FREE __GCC_ATOMIC_SHORT_LOCK_FREE
1158# define ATOMIC_INT_LOCK_FREE __GCC_ATOMIC_INT_LOCK_FREE
1159# define ATOMIC_LONG_LOCK_FREE __GCC_ATOMIC_LONG_LOCK_FREE
1160# define ATOMIC_LLONG_LOCK_FREE __GCC_ATOMIC_LLONG_LOCK_FREE
1161# define ATOMIC_POINTER_LOCK_FREE __GCC_ATOMIC_POINTER_LOCK_FREE
1162#endif
JF Bastienfdb42c22016-03-25 15:48:21 +00001163
Davide Italiano011f80a2019-03-05 18:40:49 +00001164#ifdef _LIBCPP_ATOMIC_ONLY_USE_BUILTINS
1165
1166template<typename _Tp>
1167struct __cxx_atomic_lock_impl {
1168
1169 _LIBCPP_INLINE_VISIBILITY
1170 __cxx_atomic_lock_impl() _NOEXCEPT
1171 : __a_value(), __a_lock(0) {}
1172 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR explicit
1173 __cxx_atomic_lock_impl(_Tp value) _NOEXCEPT
1174 : __a_value(value), __a_lock(0) {}
1175
1176 _Tp __a_value;
1177 mutable __cxx_atomic_base_impl<_LIBCPP_ATOMIC_FLAG_TYPE> __a_lock;
1178
1179 _LIBCPP_INLINE_VISIBILITY void __lock() const volatile {
1180 while(1 == __cxx_atomic_exchange(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(true), memory_order_acquire))
1181 /*spin*/;
1182 }
1183 _LIBCPP_INLINE_VISIBILITY void __lock() const {
1184 while(1 == __cxx_atomic_exchange(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(true), memory_order_acquire))
1185 /*spin*/;
1186 }
1187 _LIBCPP_INLINE_VISIBILITY void __unlock() const volatile {
1188 __cxx_atomic_store(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(false), memory_order_release);
1189 }
1190 _LIBCPP_INLINE_VISIBILITY void __unlock() const {
1191 __cxx_atomic_store(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(false), memory_order_release);
1192 }
1193 _LIBCPP_INLINE_VISIBILITY _Tp __read() const volatile {
1194 __lock();
1195 _Tp __old;
1196 __cxx_atomic_assign_volatile(__old, __a_value);
1197 __unlock();
1198 return __old;
1199 }
1200 _LIBCPP_INLINE_VISIBILITY _Tp __read() const {
1201 __lock();
1202 _Tp __old = __a_value;
1203 __unlock();
1204 return __old;
1205 }
1206};
1207
1208template <typename _Tp>
1209_LIBCPP_INLINE_VISIBILITY
1210void __cxx_atomic_init(volatile __cxx_atomic_lock_impl<_Tp>* __a, _Tp __val) {
1211 __cxx_atomic_assign_volatile(__a->__a_value, __val);
1212}
1213template <typename _Tp>
1214_LIBCPP_INLINE_VISIBILITY
1215void __cxx_atomic_init(__cxx_atomic_lock_impl<_Tp>* __a, _Tp __val) {
1216 __a->__a_value = __val;
1217}
1218
1219template <typename _Tp>
1220_LIBCPP_INLINE_VISIBILITY
1221void __cxx_atomic_store(volatile __cxx_atomic_lock_impl<_Tp>* __a, _Tp __val, memory_order) {
1222 __a->__lock();
1223 __cxx_atomic_assign_volatile(__a->__a_value, __val);
1224 __a->__unlock();
1225}
1226template <typename _Tp>
1227_LIBCPP_INLINE_VISIBILITY
1228void __cxx_atomic_store(__cxx_atomic_lock_impl<_Tp>* __a, _Tp __val, memory_order) {
1229 __a->__lock();
1230 __a->__a_value = __val;
1231 __a->__unlock();
1232}
1233
1234template <typename _Tp>
1235_LIBCPP_INLINE_VISIBILITY
1236_Tp __cxx_atomic_load(const volatile __cxx_atomic_lock_impl<_Tp>* __a, memory_order) {
1237 return __a->__read();
1238}
1239template <typename _Tp>
1240_LIBCPP_INLINE_VISIBILITY
1241_Tp __cxx_atomic_load(const __cxx_atomic_lock_impl<_Tp>* __a, memory_order) {
1242 return __a->__read();
1243}
1244
1245template <typename _Tp>
1246_LIBCPP_INLINE_VISIBILITY
1247_Tp __cxx_atomic_exchange(volatile __cxx_atomic_lock_impl<_Tp>* __a, _Tp __value, memory_order) {
1248 __a->__lock();
1249 _Tp __old;
1250 __cxx_atomic_assign_volatile(__old, __a->__a_value);
1251 __cxx_atomic_assign_volatile(__a->__a_value, __value);
1252 __a->__unlock();
1253 return __old;
1254}
1255template <typename _Tp>
1256_LIBCPP_INLINE_VISIBILITY
1257_Tp __cxx_atomic_exchange(__cxx_atomic_lock_impl<_Tp>* __a, _Tp __value, memory_order) {
1258 __a->__lock();
1259 _Tp __old = __a->__a_value;
1260 __a->__a_value = __value;
1261 __a->__unlock();
1262 return __old;
1263}
1264
1265template <typename _Tp>
1266_LIBCPP_INLINE_VISIBILITY
1267bool __cxx_atomic_compare_exchange_strong(volatile __cxx_atomic_lock_impl<_Tp>* __a,
1268 _Tp* __expected, _Tp __value, memory_order, memory_order) {
Olivier Giroux161e6e82020-02-18 09:58:34 -05001269 _Tp __temp;
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07001270 __a->__lock();
Olivier Giroux161e6e82020-02-18 09:58:34 -05001271 __cxx_atomic_assign_volatile(__temp, __a->__a_value);
Arthur O'Dwyer22236632020-12-07 21:50:15 -05001272 bool __ret = (_VSTD::memcmp(&__temp, __expected, sizeof(_Tp)) == 0);
Davide Italiano011f80a2019-03-05 18:40:49 +00001273 if(__ret)
1274 __cxx_atomic_assign_volatile(__a->__a_value, __value);
1275 else
1276 __cxx_atomic_assign_volatile(*__expected, __a->__a_value);
1277 __a->__unlock();
1278 return __ret;
1279}
1280template <typename _Tp>
1281_LIBCPP_INLINE_VISIBILITY
1282bool __cxx_atomic_compare_exchange_strong(__cxx_atomic_lock_impl<_Tp>* __a,
1283 _Tp* __expected, _Tp __value, memory_order, memory_order) {
1284 __a->__lock();
Arthur O'Dwyer22236632020-12-07 21:50:15 -05001285 bool __ret = (_VSTD::memcmp(&__a->__a_value, __expected, sizeof(_Tp)) == 0);
Davide Italiano011f80a2019-03-05 18:40:49 +00001286 if(__ret)
Arthur O'Dwyer22236632020-12-07 21:50:15 -05001287 _VSTD::memcpy(&__a->__a_value, &__value, sizeof(_Tp));
Davide Italiano011f80a2019-03-05 18:40:49 +00001288 else
Arthur O'Dwyer22236632020-12-07 21:50:15 -05001289 _VSTD::memcpy(__expected, &__a->__a_value, sizeof(_Tp));
Davide Italiano011f80a2019-03-05 18:40:49 +00001290 __a->__unlock();
1291 return __ret;
1292}
1293
1294template <typename _Tp>
1295_LIBCPP_INLINE_VISIBILITY
1296bool __cxx_atomic_compare_exchange_weak(volatile __cxx_atomic_lock_impl<_Tp>* __a,
1297 _Tp* __expected, _Tp __value, memory_order, memory_order) {
Olivier Giroux161e6e82020-02-18 09:58:34 -05001298 _Tp __temp;
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07001299 __a->__lock();
Olivier Giroux161e6e82020-02-18 09:58:34 -05001300 __cxx_atomic_assign_volatile(__temp, __a->__a_value);
Arthur O'Dwyer22236632020-12-07 21:50:15 -05001301 bool __ret = (_VSTD::memcmp(&__temp, __expected, sizeof(_Tp)) == 0);
Davide Italiano011f80a2019-03-05 18:40:49 +00001302 if(__ret)
1303 __cxx_atomic_assign_volatile(__a->__a_value, __value);
1304 else
1305 __cxx_atomic_assign_volatile(*__expected, __a->__a_value);
1306 __a->__unlock();
1307 return __ret;
1308}
1309template <typename _Tp>
1310_LIBCPP_INLINE_VISIBILITY
1311bool __cxx_atomic_compare_exchange_weak(__cxx_atomic_lock_impl<_Tp>* __a,
1312 _Tp* __expected, _Tp __value, memory_order, memory_order) {
1313 __a->__lock();
Arthur O'Dwyer22236632020-12-07 21:50:15 -05001314 bool __ret = (_VSTD::memcmp(&__a->__a_value, __expected, sizeof(_Tp)) == 0);
Davide Italiano011f80a2019-03-05 18:40:49 +00001315 if(__ret)
Arthur O'Dwyer22236632020-12-07 21:50:15 -05001316 _VSTD::memcpy(&__a->__a_value, &__value, sizeof(_Tp));
Davide Italiano011f80a2019-03-05 18:40:49 +00001317 else
Arthur O'Dwyer22236632020-12-07 21:50:15 -05001318 _VSTD::memcpy(__expected, &__a->__a_value, sizeof(_Tp));
Davide Italiano011f80a2019-03-05 18:40:49 +00001319 __a->__unlock();
1320 return __ret;
1321}
1322
1323template <typename _Tp, typename _Td>
1324_LIBCPP_INLINE_VISIBILITY
1325_Tp __cxx_atomic_fetch_add(volatile __cxx_atomic_lock_impl<_Tp>* __a,
1326 _Td __delta, memory_order) {
1327 __a->__lock();
1328 _Tp __old;
1329 __cxx_atomic_assign_volatile(__old, __a->__a_value);
1330 __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old + __delta));
1331 __a->__unlock();
1332 return __old;
1333}
1334template <typename _Tp, typename _Td>
1335_LIBCPP_INLINE_VISIBILITY
1336_Tp __cxx_atomic_fetch_add(__cxx_atomic_lock_impl<_Tp>* __a,
1337 _Td __delta, memory_order) {
1338 __a->__lock();
1339 _Tp __old = __a->__a_value;
1340 __a->__a_value += __delta;
1341 __a->__unlock();
1342 return __old;
1343}
1344
1345template <typename _Tp, typename _Td>
1346_LIBCPP_INLINE_VISIBILITY
1347_Tp* __cxx_atomic_fetch_add(volatile __cxx_atomic_lock_impl<_Tp*>* __a,
1348 ptrdiff_t __delta, memory_order) {
1349 __a->__lock();
1350 _Tp* __old;
1351 __cxx_atomic_assign_volatile(__old, __a->__a_value);
1352 __cxx_atomic_assign_volatile(__a->__a_value, __old + __delta);
1353 __a->__unlock();
1354 return __old;
1355}
1356template <typename _Tp, typename _Td>
1357_LIBCPP_INLINE_VISIBILITY
1358_Tp* __cxx_atomic_fetch_add(__cxx_atomic_lock_impl<_Tp*>* __a,
1359 ptrdiff_t __delta, memory_order) {
1360 __a->__lock();
1361 _Tp* __old = __a->__a_value;
1362 __a->__a_value += __delta;
1363 __a->__unlock();
1364 return __old;
1365}
1366
1367template <typename _Tp, typename _Td>
1368_LIBCPP_INLINE_VISIBILITY
1369_Tp __cxx_atomic_fetch_sub(volatile __cxx_atomic_lock_impl<_Tp>* __a,
1370 _Td __delta, memory_order) {
1371 __a->__lock();
1372 _Tp __old;
1373 __cxx_atomic_assign_volatile(__old, __a->__a_value);
1374 __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old - __delta));
1375 __a->__unlock();
1376 return __old;
1377}
1378template <typename _Tp, typename _Td>
1379_LIBCPP_INLINE_VISIBILITY
1380_Tp __cxx_atomic_fetch_sub(__cxx_atomic_lock_impl<_Tp>* __a,
1381 _Td __delta, memory_order) {
1382 __a->__lock();
1383 _Tp __old = __a->__a_value;
1384 __a->__a_value -= __delta;
1385 __a->__unlock();
1386 return __old;
1387}
1388
1389template <typename _Tp>
1390_LIBCPP_INLINE_VISIBILITY
1391_Tp __cxx_atomic_fetch_and(volatile __cxx_atomic_lock_impl<_Tp>* __a,
1392 _Tp __pattern, memory_order) {
1393 __a->__lock();
1394 _Tp __old;
1395 __cxx_atomic_assign_volatile(__old, __a->__a_value);
1396 __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old & __pattern));
1397 __a->__unlock();
1398 return __old;
1399}
1400template <typename _Tp>
1401_LIBCPP_INLINE_VISIBILITY
1402_Tp __cxx_atomic_fetch_and(__cxx_atomic_lock_impl<_Tp>* __a,
1403 _Tp __pattern, memory_order) {
1404 __a->__lock();
1405 _Tp __old = __a->__a_value;
1406 __a->__a_value &= __pattern;
1407 __a->__unlock();
1408 return __old;
1409}
1410
1411template <typename _Tp>
1412_LIBCPP_INLINE_VISIBILITY
1413_Tp __cxx_atomic_fetch_or(volatile __cxx_atomic_lock_impl<_Tp>* __a,
1414 _Tp __pattern, memory_order) {
1415 __a->__lock();
1416 _Tp __old;
1417 __cxx_atomic_assign_volatile(__old, __a->__a_value);
1418 __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old | __pattern));
1419 __a->__unlock();
1420 return __old;
1421}
1422template <typename _Tp>
1423_LIBCPP_INLINE_VISIBILITY
1424_Tp __cxx_atomic_fetch_or(__cxx_atomic_lock_impl<_Tp>* __a,
1425 _Tp __pattern, memory_order) {
1426 __a->__lock();
1427 _Tp __old = __a->__a_value;
1428 __a->__a_value |= __pattern;
1429 __a->__unlock();
1430 return __old;
1431}
1432
1433template <typename _Tp>
1434_LIBCPP_INLINE_VISIBILITY
1435_Tp __cxx_atomic_fetch_xor(volatile __cxx_atomic_lock_impl<_Tp>* __a,
1436 _Tp __pattern, memory_order) {
1437 __a->__lock();
1438 _Tp __old;
1439 __cxx_atomic_assign_volatile(__old, __a->__a_value);
1440 __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old ^ __pattern));
1441 __a->__unlock();
1442 return __old;
1443}
1444template <typename _Tp>
1445_LIBCPP_INLINE_VISIBILITY
1446_Tp __cxx_atomic_fetch_xor(__cxx_atomic_lock_impl<_Tp>* __a,
1447 _Tp __pattern, memory_order) {
1448 __a->__lock();
1449 _Tp __old = __a->__a_value;
1450 __a->__a_value ^= __pattern;
1451 __a->__unlock();
1452 return __old;
1453}
1454
1455#ifdef __cpp_lib_atomic_is_always_lock_free
1456
1457template<typename _Tp> struct __cxx_is_always_lock_free {
1458 enum { __value = __atomic_always_lock_free(sizeof(_Tp), 0) }; };
1459
1460#else
1461
1462template<typename _Tp> struct __cxx_is_always_lock_free { enum { __value = false }; };
1463// Implementations must match the C ATOMIC_*_LOCK_FREE macro values.
1464template<> struct __cxx_is_always_lock_free<bool> { enum { __value = 2 == ATOMIC_BOOL_LOCK_FREE }; };
1465template<> struct __cxx_is_always_lock_free<char> { enum { __value = 2 == ATOMIC_CHAR_LOCK_FREE }; };
1466template<> struct __cxx_is_always_lock_free<signed char> { enum { __value = 2 == ATOMIC_CHAR_LOCK_FREE }; };
1467template<> struct __cxx_is_always_lock_free<unsigned char> { enum { __value = 2 == ATOMIC_CHAR_LOCK_FREE }; };
Arthur O'Dwyerafa5d5f2021-04-18 21:47:08 -04001468#ifndef _LIBCPP_HAS_NO_CHAR8_T
Marek Kurdej91bebaa2020-11-24 21:07:06 +01001469template<> struct __cxx_is_always_lock_free<char8_t> { enum { __value = 2 == ATOMIC_CHAR8_T_LOCK_FREE }; };
1470#endif
Davide Italiano011f80a2019-03-05 18:40:49 +00001471template<> struct __cxx_is_always_lock_free<char16_t> { enum { __value = 2 == ATOMIC_CHAR16_T_LOCK_FREE }; };
1472template<> struct __cxx_is_always_lock_free<char32_t> { enum { __value = 2 == ATOMIC_CHAR32_T_LOCK_FREE }; };
1473template<> struct __cxx_is_always_lock_free<wchar_t> { enum { __value = 2 == ATOMIC_WCHAR_T_LOCK_FREE }; };
1474template<> struct __cxx_is_always_lock_free<short> { enum { __value = 2 == ATOMIC_SHORT_LOCK_FREE }; };
1475template<> struct __cxx_is_always_lock_free<unsigned short> { enum { __value = 2 == ATOMIC_SHORT_LOCK_FREE }; };
1476template<> struct __cxx_is_always_lock_free<int> { enum { __value = 2 == ATOMIC_INT_LOCK_FREE }; };
1477template<> struct __cxx_is_always_lock_free<unsigned int> { enum { __value = 2 == ATOMIC_INT_LOCK_FREE }; };
1478template<> struct __cxx_is_always_lock_free<long> { enum { __value = 2 == ATOMIC_LONG_LOCK_FREE }; };
1479template<> struct __cxx_is_always_lock_free<unsigned long> { enum { __value = 2 == ATOMIC_LONG_LOCK_FREE }; };
1480template<> struct __cxx_is_always_lock_free<long long> { enum { __value = 2 == ATOMIC_LLONG_LOCK_FREE }; };
1481template<> struct __cxx_is_always_lock_free<unsigned long long> { enum { __value = 2 == ATOMIC_LLONG_LOCK_FREE }; };
1482template<typename _Tp> struct __cxx_is_always_lock_free<_Tp*> { enum { __value = 2 == ATOMIC_POINTER_LOCK_FREE }; };
1483template<> struct __cxx_is_always_lock_free<std::nullptr_t> { enum { __value = 2 == ATOMIC_POINTER_LOCK_FREE }; };
1484
1485#endif //__cpp_lib_atomic_is_always_lock_free
1486
1487template <typename _Tp,
1488 typename _Base = typename conditional<__cxx_is_always_lock_free<_Tp>::__value,
1489 __cxx_atomic_base_impl<_Tp>,
1490 __cxx_atomic_lock_impl<_Tp> >::type>
1491#else
1492template <typename _Tp,
1493 typename _Base = __cxx_atomic_base_impl<_Tp> >
1494#endif //_LIBCPP_ATOMIC_ONLY_USE_BUILTINS
1495struct __cxx_atomic_impl : public _Base {
1496
1497#if _GNUC_VER >= 501
1498 static_assert(is_trivially_copyable<_Tp>::value,
1499 "std::atomic<Tp> requires that 'Tp' be a trivially copyable type");
1500#endif
1501
1502 _LIBCPP_INLINE_VISIBILITY __cxx_atomic_impl() _NOEXCEPT _LIBCPP_DEFAULT
1503 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR explicit __cxx_atomic_impl(_Tp value) _NOEXCEPT
1504 : _Base(value) {}
1505};
1506
Olivier Giroux161e6e82020-02-18 09:58:34 -05001507#ifdef __linux__
1508 using __cxx_contention_t = int32_t;
1509#else
1510 using __cxx_contention_t = int64_t;
1511#endif //__linux__
1512
Olivier Giroux161e6e82020-02-18 09:58:34 -05001513using __cxx_atomic_contention_t = __cxx_atomic_impl<__cxx_contention_t>;
1514
1515#ifndef _LIBCPP_HAS_NO_PLATFORM_WAIT
1516
Louis Dionne48a828b2020-02-24 10:08:41 -05001517_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_one(void const volatile*);
1518_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_all(void const volatile*);
1519_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t __libcpp_atomic_monitor(void const volatile*);
1520_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __libcpp_atomic_wait(void const volatile*, __cxx_contention_t);
Olivier Giroux161e6e82020-02-18 09:58:34 -05001521
Louis Dionne48a828b2020-02-24 10:08:41 -05001522_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_one(__cxx_atomic_contention_t const volatile*);
1523_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_all(__cxx_atomic_contention_t const volatile*);
1524_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t __libcpp_atomic_monitor(__cxx_atomic_contention_t const volatile*);
1525_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 -05001526
1527template <class _Atp, class _Fn>
Louis Dionne08cd5cb2020-02-24 11:39:48 -05001528struct __libcpp_atomic_wait_backoff_impl {
1529 _Atp* __a;
1530 _Fn __test_fn;
Louis Dionne3dde4ab2020-02-24 10:09:29 -05001531 _LIBCPP_AVAILABILITY_SYNC
Louis Dionne08cd5cb2020-02-24 11:39:48 -05001532 _LIBCPP_INLINE_VISIBILITY bool operator()(chrono::nanoseconds __elapsed) const
1533 {
Olivier Giroux161e6e82020-02-18 09:58:34 -05001534 if(__elapsed > chrono::microseconds(64))
1535 {
1536 auto const __monitor = __libcpp_atomic_monitor(__a);
1537 if(__test_fn())
1538 return true;
1539 __libcpp_atomic_wait(__a, __monitor);
1540 }
1541 else if(__elapsed > chrono::microseconds(4))
1542 __libcpp_thread_yield();
1543 else
Marek Kurdejc79652f2020-11-15 16:17:52 +01001544 {} // poll
Olivier Giroux161e6e82020-02-18 09:58:34 -05001545 return false;
Louis Dionne08cd5cb2020-02-24 11:39:48 -05001546 }
1547};
1548
1549template <class _Atp, class _Fn>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05001550_LIBCPP_AVAILABILITY_SYNC
Louis Dionne08cd5cb2020-02-24 11:39:48 -05001551_LIBCPP_INLINE_VISIBILITY bool __cxx_atomic_wait(_Atp* __a, _Fn && __test_fn)
1552{
1553 __libcpp_atomic_wait_backoff_impl<_Atp, typename decay<_Fn>::type> __backoff_fn = {__a, __test_fn};
1554 return __libcpp_thread_poll_with_backoff(__test_fn, __backoff_fn);
Olivier Giroux161e6e82020-02-18 09:58:34 -05001555}
1556
1557#else // _LIBCPP_HAS_NO_PLATFORM_WAIT
1558
1559template <class _Tp>
1560_LIBCPP_INLINE_VISIBILITY void __cxx_atomic_notify_all(__cxx_atomic_impl<_Tp> const volatile*) { }
1561template <class _Tp>
1562_LIBCPP_INLINE_VISIBILITY void __cxx_atomic_notify_one(__cxx_atomic_impl<_Tp> const volatile*) { }
1563template <class _Atp, class _Fn>
1564_LIBCPP_INLINE_VISIBILITY bool __cxx_atomic_wait(_Atp*, _Fn && __test_fn)
1565{
1566 return __libcpp_thread_poll_with_backoff(__test_fn, __libcpp_timed_backoff_policy());
1567}
1568
1569#endif // _LIBCPP_HAS_NO_PLATFORM_WAIT
1570
1571template <class _Atp, class _Tp>
Louis Dionne08cd5cb2020-02-24 11:39:48 -05001572struct __cxx_atomic_wait_test_fn_impl {
1573 _Atp* __a;
1574 _Tp __val;
1575 memory_order __order;
1576 _LIBCPP_INLINE_VISIBILITY bool operator()() const
1577 {
1578 return !__cxx_nonatomic_compare_equal(__cxx_atomic_load(__a, __order), __val);
1579 }
1580};
1581
1582template <class _Atp, class _Tp>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05001583_LIBCPP_AVAILABILITY_SYNC
Olivier Giroux161e6e82020-02-18 09:58:34 -05001584_LIBCPP_INLINE_VISIBILITY bool __cxx_atomic_wait(_Atp* __a, _Tp const __val, memory_order __order)
1585{
Louis Dionne08cd5cb2020-02-24 11:39:48 -05001586 __cxx_atomic_wait_test_fn_impl<_Atp, _Tp> __test_fn = {__a, __val, __order};
Olivier Giroux161e6e82020-02-18 09:58:34 -05001587 return __cxx_atomic_wait(__a, __test_fn);
1588}
1589
Howard Hinnant138f5922010-12-07 20:46:14 +00001590// general atomic<T>
1591
1592template <class _Tp, bool = is_integral<_Tp>::value && !is_same<_Tp, bool>::value>
1593struct __atomic_base // false
1594{
Davide Italiano011f80a2019-03-05 18:40:49 +00001595 mutable __cxx_atomic_impl<_Tp> __a_;
Howard Hinnant138f5922010-12-07 20:46:14 +00001596
JF Bastienfdb42c22016-03-25 15:48:21 +00001597#if defined(__cpp_lib_atomic_is_always_lock_free)
1598 static _LIBCPP_CONSTEXPR bool is_always_lock_free = __atomic_always_lock_free(sizeof(__a_), 0);
1599#endif
1600
Howard Hinnant138f5922010-12-07 20:46:14 +00001601 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001602 bool is_lock_free() const volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001603 {return __cxx_atomic_is_lock_free(sizeof(_Tp));}
Howard Hinnant138f5922010-12-07 20:46:14 +00001604 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001605 bool is_lock_free() const _NOEXCEPT
Eric Fiselier3fd22c22015-06-13 00:23:07 +00001606 {return static_cast<__atomic_base const volatile*>(this)->is_lock_free();}
Howard Hinnant138f5922010-12-07 20:46:14 +00001607 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001608 void store(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001609 _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
Davide Italiano011f80a2019-03-05 18:40:49 +00001610 {__cxx_atomic_store(&__a_, __d, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001611 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001612 void store(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001613 _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
Davide Italiano011f80a2019-03-05 18:40:49 +00001614 {__cxx_atomic_store(&__a_, __d, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001615 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001616 _Tp load(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001617 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
Davide Italiano011f80a2019-03-05 18:40:49 +00001618 {return __cxx_atomic_load(&__a_, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001619 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001620 _Tp load(memory_order __m = memory_order_seq_cst) const _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001621 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
Davide Italiano011f80a2019-03-05 18:40:49 +00001622 {return __cxx_atomic_load(&__a_, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001623 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001624 operator _Tp() const volatile _NOEXCEPT {return load();}
Howard Hinnant138f5922010-12-07 20:46:14 +00001625 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001626 operator _Tp() const _NOEXCEPT {return load();}
Howard Hinnant138f5922010-12-07 20:46:14 +00001627 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001628 _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001629 {return __cxx_atomic_exchange(&__a_, __d, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001630 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001631 _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001632 {return __cxx_atomic_exchange(&__a_, __d, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001633 _LIBCPP_INLINE_VISIBILITY
1634 bool compare_exchange_weak(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001635 memory_order __s, memory_order __f) volatile _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001636 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Davide Italiano011f80a2019-03-05 18:40:49 +00001637 {return __cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001638 _LIBCPP_INLINE_VISIBILITY
1639 bool compare_exchange_weak(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001640 memory_order __s, memory_order __f) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001641 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Davide Italiano011f80a2019-03-05 18:40:49 +00001642 {return __cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001643 _LIBCPP_INLINE_VISIBILITY
1644 bool compare_exchange_strong(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001645 memory_order __s, memory_order __f) volatile _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001646 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Davide Italiano011f80a2019-03-05 18:40:49 +00001647 {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001648 _LIBCPP_INLINE_VISIBILITY
1649 bool compare_exchange_strong(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001650 memory_order __s, memory_order __f) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001651 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Davide Italiano011f80a2019-03-05 18:40:49 +00001652 {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001653 _LIBCPP_INLINE_VISIBILITY
1654 bool compare_exchange_weak(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001655 memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001656 {return __cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001657 _LIBCPP_INLINE_VISIBILITY
1658 bool compare_exchange_weak(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001659 memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001660 {return __cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001661 _LIBCPP_INLINE_VISIBILITY
1662 bool compare_exchange_strong(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001663 memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001664 {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001665 _LIBCPP_INLINE_VISIBILITY
1666 bool compare_exchange_strong(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001667 memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001668 {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001669
Louis Dionne3dde4ab2020-02-24 10:09:29 -05001670 _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 -05001671 {__cxx_atomic_wait(&__a_, __v, __m);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05001672 _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 -05001673 {__cxx_atomic_wait(&__a_, __v, __m);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05001674 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_one() volatile _NOEXCEPT
Olivier Giroux161e6e82020-02-18 09:58:34 -05001675 {__cxx_atomic_notify_one(&__a_);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05001676 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_one() _NOEXCEPT
Olivier Giroux161e6e82020-02-18 09:58:34 -05001677 {__cxx_atomic_notify_one(&__a_);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05001678 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_all() volatile _NOEXCEPT
Olivier Giroux161e6e82020-02-18 09:58:34 -05001679 {__cxx_atomic_notify_all(&__a_);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05001680 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_all() _NOEXCEPT
Olivier Giroux161e6e82020-02-18 09:58:34 -05001681 {__cxx_atomic_notify_all(&__a_);}
1682
Howard Hinnant138f5922010-12-07 20:46:14 +00001683 _LIBCPP_INLINE_VISIBILITY
Davide Italiano011f80a2019-03-05 18:40:49 +00001684 __atomic_base() _NOEXCEPT _LIBCPP_DEFAULT
Howard Hinnant3d284222013-05-02 20:18:43 +00001685
Davide Italiano011f80a2019-03-05 18:40:49 +00001686 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
1687 __atomic_base(_Tp __d) _NOEXCEPT : __a_(__d) {}
1688
Eric Fiselier2d8515f2017-01-06 20:58:25 +00001689#ifndef _LIBCPP_CXX03_LANG
Howard Hinnant138f5922010-12-07 20:46:14 +00001690 __atomic_base(const __atomic_base&) = delete;
Eric Fiselier2d8515f2017-01-06 20:58:25 +00001691#else
Howard Hinnant6ac60f82010-12-08 17:20:28 +00001692private:
Olivier Giroux161e6e82020-02-18 09:58:34 -05001693 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant6ac60f82010-12-08 17:20:28 +00001694 __atomic_base(const __atomic_base&);
Eric Fiselier2d8515f2017-01-06 20:58:25 +00001695#endif
Howard Hinnant138f5922010-12-07 20:46:14 +00001696};
1697
JF Bastienfdb42c22016-03-25 15:48:21 +00001698#if defined(__cpp_lib_atomic_is_always_lock_free)
1699template <class _Tp, bool __b>
1700_LIBCPP_CONSTEXPR bool __atomic_base<_Tp, __b>::is_always_lock_free;
1701#endif
1702
Howard Hinnant138f5922010-12-07 20:46:14 +00001703// atomic<Integral>
1704
1705template <class _Tp>
1706struct __atomic_base<_Tp, true>
1707 : public __atomic_base<_Tp, false>
1708{
1709 typedef __atomic_base<_Tp, false> __base;
1710 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3d284222013-05-02 20:18:43 +00001711 __atomic_base() _NOEXCEPT _LIBCPP_DEFAULT
Howard Hinnant138f5922010-12-07 20:46:14 +00001712 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001713 _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __base(__d) {}
Howard Hinnant138f5922010-12-07 20:46:14 +00001714
1715 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001716 _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001717 {return __cxx_atomic_fetch_add(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001718 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001719 _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001720 {return __cxx_atomic_fetch_add(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001721 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001722 _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001723 {return __cxx_atomic_fetch_sub(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001724 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001725 _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001726 {return __cxx_atomic_fetch_sub(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001727 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001728 _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001729 {return __cxx_atomic_fetch_and(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001730 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001731 _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001732 {return __cxx_atomic_fetch_and(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001733 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001734 _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001735 {return __cxx_atomic_fetch_or(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001736 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001737 _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001738 {return __cxx_atomic_fetch_or(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001739 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001740 _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001741 {return __cxx_atomic_fetch_xor(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001742 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001743 _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001744 {return __cxx_atomic_fetch_xor(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001745
1746 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001747 _Tp operator++(int) volatile _NOEXCEPT {return fetch_add(_Tp(1));}
Howard Hinnant138f5922010-12-07 20:46:14 +00001748 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001749 _Tp operator++(int) _NOEXCEPT {return fetch_add(_Tp(1));}
Howard Hinnant138f5922010-12-07 20:46:14 +00001750 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001751 _Tp operator--(int) volatile _NOEXCEPT {return fetch_sub(_Tp(1));}
Howard Hinnant138f5922010-12-07 20:46:14 +00001752 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001753 _Tp operator--(int) _NOEXCEPT {return fetch_sub(_Tp(1));}
Howard Hinnant138f5922010-12-07 20:46:14 +00001754 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001755 _Tp operator++() volatile _NOEXCEPT {return fetch_add(_Tp(1)) + _Tp(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001756 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001757 _Tp operator++() _NOEXCEPT {return fetch_add(_Tp(1)) + _Tp(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001758 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001759 _Tp operator--() volatile _NOEXCEPT {return fetch_sub(_Tp(1)) - _Tp(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001760 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001761 _Tp operator--() _NOEXCEPT {return fetch_sub(_Tp(1)) - _Tp(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001762 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001763 _Tp operator+=(_Tp __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001764 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001765 _Tp operator+=(_Tp __op) _NOEXCEPT {return fetch_add(__op) + __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001766 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001767 _Tp operator-=(_Tp __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001768 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001769 _Tp operator-=(_Tp __op) _NOEXCEPT {return fetch_sub(__op) - __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001770 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001771 _Tp operator&=(_Tp __op) volatile _NOEXCEPT {return fetch_and(__op) & __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001772 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001773 _Tp operator&=(_Tp __op) _NOEXCEPT {return fetch_and(__op) & __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001774 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001775 _Tp operator|=(_Tp __op) volatile _NOEXCEPT {return fetch_or(__op) | __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001776 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001777 _Tp operator|=(_Tp __op) _NOEXCEPT {return fetch_or(__op) | __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001778 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001779 _Tp operator^=(_Tp __op) volatile _NOEXCEPT {return fetch_xor(__op) ^ __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001780 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001781 _Tp operator^=(_Tp __op) _NOEXCEPT {return fetch_xor(__op) ^ __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001782};
1783
1784// atomic<T>
1785
1786template <class _Tp>
1787struct atomic
1788 : public __atomic_base<_Tp>
1789{
1790 typedef __atomic_base<_Tp> __base;
Olivier Giroux161e6e82020-02-18 09:58:34 -05001791 typedef _Tp value_type;
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07001792 typedef value_type difference_type;
Howard Hinnant138f5922010-12-07 20:46:14 +00001793 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3d284222013-05-02 20:18:43 +00001794 atomic() _NOEXCEPT _LIBCPP_DEFAULT
Howard Hinnant138f5922010-12-07 20:46:14 +00001795 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001796 _LIBCPP_CONSTEXPR atomic(_Tp __d) _NOEXCEPT : __base(__d) {}
Howard Hinnant96e4cd62010-12-07 23:24:41 +00001797
1798 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001799 _Tp operator=(_Tp __d) volatile _NOEXCEPT
Howard Hinnant96e4cd62010-12-07 23:24:41 +00001800 {__base::store(__d); return __d;}
1801 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001802 _Tp operator=(_Tp __d) _NOEXCEPT
Howard Hinnant96e4cd62010-12-07 23:24:41 +00001803 {__base::store(__d); return __d;}
Ruslan Arutyunyan033093f2021-02-01 10:12:09 -05001804
1805 atomic& operator=(const atomic&) = delete;
1806 atomic& operator=(const atomic&) volatile = delete;
Howard Hinnant138f5922010-12-07 20:46:14 +00001807};
1808
1809// atomic<T*>
1810
1811template <class _Tp>
1812struct atomic<_Tp*>
1813 : public __atomic_base<_Tp*>
1814{
Howard Hinnant96e4cd62010-12-07 23:24:41 +00001815 typedef __atomic_base<_Tp*> __base;
Olivier Giroux161e6e82020-02-18 09:58:34 -05001816 typedef _Tp* value_type;
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07001817 typedef ptrdiff_t difference_type;
Howard Hinnant138f5922010-12-07 20:46:14 +00001818 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3d284222013-05-02 20:18:43 +00001819 atomic() _NOEXCEPT _LIBCPP_DEFAULT
Howard Hinnant138f5922010-12-07 20:46:14 +00001820 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001821 _LIBCPP_CONSTEXPR atomic(_Tp* __d) _NOEXCEPT : __base(__d) {}
Howard Hinnant138f5922010-12-07 20:46:14 +00001822
1823 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001824 _Tp* operator=(_Tp* __d) volatile _NOEXCEPT
Howard Hinnant96e4cd62010-12-07 23:24:41 +00001825 {__base::store(__d); return __d;}
1826 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001827 _Tp* operator=(_Tp* __d) _NOEXCEPT
Howard Hinnant96e4cd62010-12-07 23:24:41 +00001828 {__base::store(__d); return __d;}
1829
1830 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00001831 _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst)
Howard Hinnanteee2c142012-04-11 20:14:21 +00001832 volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001833 {return __cxx_atomic_fetch_add(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001834 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001835 _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001836 {return __cxx_atomic_fetch_add(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001837 _LIBCPP_INLINE_VISIBILITY
1838 _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst)
Howard Hinnanteee2c142012-04-11 20:14:21 +00001839 volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001840 {return __cxx_atomic_fetch_sub(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001841 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001842 _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001843 {return __cxx_atomic_fetch_sub(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001844
1845 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001846 _Tp* operator++(int) volatile _NOEXCEPT {return fetch_add(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001847 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001848 _Tp* operator++(int) _NOEXCEPT {return fetch_add(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001849 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001850 _Tp* operator--(int) volatile _NOEXCEPT {return fetch_sub(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001851 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001852 _Tp* operator--(int) _NOEXCEPT {return fetch_sub(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001853 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001854 _Tp* operator++() volatile _NOEXCEPT {return fetch_add(1) + 1;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001855 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001856 _Tp* operator++() _NOEXCEPT {return fetch_add(1) + 1;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001857 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001858 _Tp* operator--() volatile _NOEXCEPT {return fetch_sub(1) - 1;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001859 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001860 _Tp* operator--() _NOEXCEPT {return fetch_sub(1) - 1;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001861 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001862 _Tp* operator+=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001863 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001864 _Tp* operator+=(ptrdiff_t __op) _NOEXCEPT {return fetch_add(__op) + __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001865 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001866 _Tp* operator-=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001867 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001868 _Tp* operator-=(ptrdiff_t __op) _NOEXCEPT {return fetch_sub(__op) - __op;}
Ruslan Arutyunyan033093f2021-02-01 10:12:09 -05001869
1870 atomic& operator=(const atomic&) = delete;
1871 atomic& operator=(const atomic&) volatile = delete;
Howard Hinnant138f5922010-12-07 20:46:14 +00001872};
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001873
1874// atomic_is_lock_free
1875
1876template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001877_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001878bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00001879atomic_is_lock_free(const volatile atomic<_Tp>* __o) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001880{
Howard Hinnant138f5922010-12-07 20:46:14 +00001881 return __o->is_lock_free();
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001882}
1883
1884template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001885_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001886bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00001887atomic_is_lock_free(const atomic<_Tp>* __o) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001888{
Howard Hinnant138f5922010-12-07 20:46:14 +00001889 return __o->is_lock_free();
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001890}
1891
1892// atomic_init
1893
1894template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001895_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001896void
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07001897atomic_init(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001898{
Davide Italiano011f80a2019-03-05 18:40:49 +00001899 __cxx_atomic_init(&__o->__a_, __d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001900}
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_init(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001906{
Davide Italiano011f80a2019-03-05 18:40:49 +00001907 __cxx_atomic_init(&__o->__a_, __d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001908}
1909
1910// atomic_store
1911
1912template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001913_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001914void
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07001915atomic_store(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001916{
Howard Hinnant138f5922010-12-07 20:46:14 +00001917 __o->store(__d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001918}
1919
1920template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001921_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001922void
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07001923atomic_store(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001924{
Howard Hinnant138f5922010-12-07 20:46:14 +00001925 __o->store(__d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001926}
1927
1928// atomic_store_explicit
1929
1930template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001931_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001932void
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07001933atomic_store_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001934 _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001935{
Howard Hinnant138f5922010-12-07 20:46:14 +00001936 __o->store(__d, __m);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001937}
1938
1939template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001940_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001941void
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07001942atomic_store_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001943 _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001944{
Howard Hinnant138f5922010-12-07 20:46:14 +00001945 __o->store(__d, __m);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001946}
1947
1948// atomic_load
1949
1950template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001951_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001952_Tp
Howard Hinnanteee2c142012-04-11 20:14:21 +00001953atomic_load(const volatile atomic<_Tp>* __o) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001954{
Howard Hinnant138f5922010-12-07 20:46:14 +00001955 return __o->load();
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001956}
1957
1958template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001959_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001960_Tp
Howard Hinnanteee2c142012-04-11 20:14:21 +00001961atomic_load(const atomic<_Tp>* __o) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001962{
Howard Hinnant138f5922010-12-07 20:46:14 +00001963 return __o->load();
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001964}
1965
1966// atomic_load_explicit
1967
1968template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001969_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001970_Tp
Howard Hinnanteee2c142012-04-11 20:14:21 +00001971atomic_load_explicit(const volatile atomic<_Tp>* __o, memory_order __m) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001972 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001973{
Howard Hinnant138f5922010-12-07 20:46:14 +00001974 return __o->load(__m);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001975}
1976
1977template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001978_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001979_Tp
Howard Hinnanteee2c142012-04-11 20:14:21 +00001980atomic_load_explicit(const atomic<_Tp>* __o, memory_order __m) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001981 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001982{
Howard Hinnant138f5922010-12-07 20:46:14 +00001983 return __o->load(__m);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001984}
1985
1986// atomic_exchange
1987
1988template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001989_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001990_Tp
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07001991atomic_exchange(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001992{
Howard Hinnant138f5922010-12-07 20:46:14 +00001993 return __o->exchange(__d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001994}
1995
1996template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001997_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001998_Tp
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07001999atomic_exchange(atomic<_Tp>* __o, 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->exchange(__d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002002}
2003
2004// atomic_exchange_explicit
2005
2006template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002007_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002008_Tp
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002009atomic_exchange_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002010{
Howard Hinnant138f5922010-12-07 20:46:14 +00002011 return __o->exchange(__d, __m);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002012}
2013
2014template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002015_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002016_Tp
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002017atomic_exchange_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002018{
Howard Hinnant138f5922010-12-07 20:46:14 +00002019 return __o->exchange(__d, __m);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002020}
2021
2022// atomic_compare_exchange_weak
2023
2024template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002025_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002026bool
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002027atomic_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 +00002028{
Howard Hinnant138f5922010-12-07 20:46:14 +00002029 return __o->compare_exchange_weak(*__e, __d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002030}
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(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002036{
Howard Hinnant138f5922010-12-07 20:46:14 +00002037 return __o->compare_exchange_weak(*__e, __d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002038}
2039
2040// atomic_compare_exchange_strong
2041
2042template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002043_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002044bool
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002045atomic_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 +00002046{
Howard Hinnant138f5922010-12-07 20:46:14 +00002047 return __o->compare_exchange_strong(*__e, __d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002048}
2049
2050template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002051_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002052bool
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002053atomic_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 +00002054{
Howard Hinnant138f5922010-12-07 20:46:14 +00002055 return __o->compare_exchange_strong(*__e, __d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002056}
2057
2058// atomic_compare_exchange_weak_explicit
2059
2060template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002061_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002062bool
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002063atomic_compare_exchange_weak_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e,
2064 typename atomic<_Tp>::value_type __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00002065 memory_order __s, memory_order __f) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00002066 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002067{
Howard Hinnant138f5922010-12-07 20:46:14 +00002068 return __o->compare_exchange_weak(*__e, __d, __s, __f);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002069}
2070
2071template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002072_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002073bool
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002074atomic_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 +00002075 memory_order __s, memory_order __f) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00002076 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002077{
Howard Hinnant138f5922010-12-07 20:46:14 +00002078 return __o->compare_exchange_weak(*__e, __d, __s, __f);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002079}
2080
2081// atomic_compare_exchange_strong_explicit
2082
2083template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002084_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002085bool
2086atomic_compare_exchange_strong_explicit(volatile atomic<_Tp>* __o,
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002087 typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00002088 memory_order __s, memory_order __f) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00002089 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002090{
Howard Hinnant138f5922010-12-07 20:46:14 +00002091 return __o->compare_exchange_strong(*__e, __d, __s, __f);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002092}
2093
2094template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002095_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002096bool
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002097atomic_compare_exchange_strong_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e,
2098 typename atomic<_Tp>::value_type __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00002099 memory_order __s, memory_order __f) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00002100 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002101{
Howard Hinnant138f5922010-12-07 20:46:14 +00002102 return __o->compare_exchange_strong(*__e, __d, __s, __f);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002103}
2104
Olivier Giroux161e6e82020-02-18 09:58:34 -05002105// atomic_wait
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(const volatile atomic<_Tp>* __o,
2110 typename atomic<_Tp>::value_type __v) _NOEXCEPT
2111{
2112 return __o->wait(__v);
2113}
2114
2115template <class _Tp>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002116_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002117void atomic_wait(const atomic<_Tp>* __o,
2118 typename atomic<_Tp>::value_type __v) _NOEXCEPT
2119{
2120 return __o->wait(__v);
2121}
2122
2123// atomic_wait_explicit
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_wait_explicit(const volatile atomic<_Tp>* __o,
2128 typename atomic<_Tp>::value_type __v,
2129 memory_order __m) _NOEXCEPT
2130 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
2131{
2132 return __o->wait(__v, __m);
2133}
2134
2135template <class _Tp>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002136_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002137void atomic_wait_explicit(const atomic<_Tp>* __o,
2138 typename atomic<_Tp>::value_type __v,
2139 memory_order __m) _NOEXCEPT
2140 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
2141{
2142 return __o->wait(__v, __m);
2143}
2144
2145// atomic_notify_one
2146
2147template <class _Tp>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002148_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002149void atomic_notify_one(volatile atomic<_Tp>* __o) _NOEXCEPT
2150{
2151 __o->notify_one();
2152}
2153template <class _Tp>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002154_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002155void atomic_notify_one(atomic<_Tp>* __o) _NOEXCEPT
2156{
2157 __o->notify_one();
2158}
2159
2160// atomic_notify_one
2161
2162template <class _Tp>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002163_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002164void atomic_notify_all(volatile atomic<_Tp>* __o) _NOEXCEPT
2165{
2166 __o->notify_all();
2167}
2168template <class _Tp>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002169_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002170void atomic_notify_all(atomic<_Tp>* __o) _NOEXCEPT
2171{
2172 __o->notify_all();
2173}
2174
Howard Hinnant138f5922010-12-07 20:46:14 +00002175// atomic_fetch_add
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002176
2177template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002178_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002179typename enable_if
2180<
Olivier Girouxdf485172020-09-11 12:13:35 -07002181 is_integral<_Tp>::value && !is_same<_Tp, bool>::value && !is_const<_Tp>::value,
Howard Hinnant138f5922010-12-07 20:46:14 +00002182 _Tp
2183>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002184atomic_fetch_add(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002185{
Howard Hinnant138f5922010-12-07 20:46:14 +00002186 return __o->fetch_add(__op);
2187}
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002188
Howard Hinnant138f5922010-12-07 20:46:14 +00002189template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002190_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002191typename enable_if
2192<
Olivier Girouxdf485172020-09-11 12:13:35 -07002193 is_integral<_Tp>::value && !is_same<_Tp, bool>::value && !is_const<_Tp>::value,
Howard Hinnant138f5922010-12-07 20:46:14 +00002194 _Tp
2195>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002196atomic_fetch_add(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002197{
2198 return __o->fetch_add(__op);
2199}
2200
Olivier Girouxdf485172020-09-11 12:13:35 -07002201template <class _Tp>
2202_LIBCPP_INLINE_VISIBILITY
Louis Dionneb39adc52020-11-04 14:07:59 -05002203_Tp*
Olivier Girouxdf485172020-09-11 12:13:35 -07002204atomic_fetch_add(volatile atomic<_Tp*>* __o, typename atomic<_Tp*>::difference_type __op) _NOEXCEPT
2205{
2206 return __o->fetch_add(__op);
2207}
2208
2209template <class _Tp>
2210_LIBCPP_INLINE_VISIBILITY
Louis Dionneb39adc52020-11-04 14:07:59 -05002211_Tp*
Olivier Girouxdf485172020-09-11 12:13:35 -07002212atomic_fetch_add(atomic<_Tp*>* __o, typename atomic<_Tp*>::difference_type __op) _NOEXCEPT
2213{
2214 return __o->fetch_add(__op);
2215}
2216
Howard Hinnant138f5922010-12-07 20:46:14 +00002217// atomic_fetch_add_explicit
2218
2219template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002220_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002221typename enable_if
2222<
Olivier Girouxdf485172020-09-11 12:13:35 -07002223 is_integral<_Tp>::value && !is_same<_Tp, bool>::value && !is_const<_Tp>::value,
Howard Hinnant138f5922010-12-07 20:46:14 +00002224 _Tp
2225>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002226atomic_fetch_add_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002227{
2228 return __o->fetch_add(__op, __m);
2229}
2230
2231template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002232_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002233typename enable_if
2234<
Olivier Girouxdf485172020-09-11 12:13:35 -07002235 is_integral<_Tp>::value && !is_same<_Tp, bool>::value && !is_const<_Tp>::value,
Howard Hinnant138f5922010-12-07 20:46:14 +00002236 _Tp
2237>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002238atomic_fetch_add_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002239{
2240 return __o->fetch_add(__op, __m);
2241}
2242
Olivier Girouxdf485172020-09-11 12:13:35 -07002243template <class _Tp>
2244_LIBCPP_INLINE_VISIBILITY
2245_Tp*
2246atomic_fetch_add_explicit(volatile atomic<_Tp*>* __o, typename atomic<_Tp*>::difference_type __op, memory_order __m) _NOEXCEPT
2247{
2248 return __o->fetch_add(__op, __m);
2249}
2250
2251template <class _Tp>
2252_LIBCPP_INLINE_VISIBILITY
2253_Tp*
2254atomic_fetch_add_explicit(atomic<_Tp*>* __o, typename atomic<_Tp*>::difference_type __op, memory_order __m) _NOEXCEPT
2255{
2256 return __o->fetch_add(__op, __m);
2257}
2258
Howard Hinnant138f5922010-12-07 20:46:14 +00002259// atomic_fetch_sub
2260
2261template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002262_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002263typename enable_if
2264<
Olivier Girouxdf485172020-09-11 12:13:35 -07002265 is_integral<_Tp>::value && !is_same<_Tp, bool>::value && !is_const<_Tp>::value,
Howard Hinnant138f5922010-12-07 20:46:14 +00002266 _Tp
2267>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002268atomic_fetch_sub(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002269{
2270 return __o->fetch_sub(__op);
2271}
2272
2273template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002274_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002275typename enable_if
2276<
Olivier Girouxdf485172020-09-11 12:13:35 -07002277 is_integral<_Tp>::value && !is_same<_Tp, bool>::value && !is_const<_Tp>::value,
Howard Hinnant138f5922010-12-07 20:46:14 +00002278 _Tp
2279>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002280atomic_fetch_sub(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002281{
2282 return __o->fetch_sub(__op);
2283}
2284
Olivier Girouxdf485172020-09-11 12:13:35 -07002285template <class _Tp>
2286_LIBCPP_INLINE_VISIBILITY
2287_Tp*
2288atomic_fetch_sub(volatile atomic<_Tp*>* __o, typename atomic<_Tp*>::difference_type __op) _NOEXCEPT
2289{
2290 return __o->fetch_sub(__op);
2291}
2292
2293template <class _Tp>
2294_LIBCPP_INLINE_VISIBILITY
2295_Tp*
2296atomic_fetch_sub(atomic<_Tp*>* __o, typename atomic<_Tp*>::difference_type __op) _NOEXCEPT
2297{
2298 return __o->fetch_sub(__op);
2299}
2300
Howard Hinnant138f5922010-12-07 20:46:14 +00002301// atomic_fetch_sub_explicit
2302
2303template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002304_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002305typename enable_if
2306<
Olivier Girouxdf485172020-09-11 12:13:35 -07002307 is_integral<_Tp>::value && !is_same<_Tp, bool>::value && !is_const<_Tp>::value,
Howard Hinnant138f5922010-12-07 20:46:14 +00002308 _Tp
2309>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002310atomic_fetch_sub_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002311{
2312 return __o->fetch_sub(__op, __m);
2313}
2314
2315template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002316_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002317typename enable_if
2318<
Olivier Girouxdf485172020-09-11 12:13:35 -07002319 is_integral<_Tp>::value && !is_same<_Tp, bool>::value && !is_const<_Tp>::value,
Howard Hinnant138f5922010-12-07 20:46:14 +00002320 _Tp
2321>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002322atomic_fetch_sub_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002323{
2324 return __o->fetch_sub(__op, __m);
2325}
2326
Olivier Girouxdf485172020-09-11 12:13:35 -07002327template <class _Tp>
2328_LIBCPP_INLINE_VISIBILITY
2329_Tp*
2330atomic_fetch_sub_explicit(volatile atomic<_Tp*>* __o, typename atomic<_Tp*>::difference_type __op, memory_order __m) _NOEXCEPT
2331{
2332 return __o->fetch_sub(__op, __m);
2333}
2334
2335template <class _Tp>
2336_LIBCPP_INLINE_VISIBILITY
2337_Tp*
2338atomic_fetch_sub_explicit(atomic<_Tp*>* __o, typename atomic<_Tp*>::difference_type __op, memory_order __m) _NOEXCEPT
2339{
2340 return __o->fetch_sub(__op, __m);
2341}
2342
Howard Hinnant138f5922010-12-07 20:46:14 +00002343// atomic_fetch_and
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_and(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002353{
2354 return __o->fetch_and(__op);
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_and(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002365{
2366 return __o->fetch_and(__op);
2367}
2368
2369// atomic_fetch_and_explicit
2370
2371template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002372_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002373typename enable_if
2374<
2375 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2376 _Tp
2377>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002378atomic_fetch_and_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002379{
2380 return __o->fetch_and(__op, __m);
2381}
2382
2383template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002384_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002385typename enable_if
2386<
2387 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2388 _Tp
2389>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002390atomic_fetch_and_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002391{
2392 return __o->fetch_and(__op, __m);
2393}
2394
2395// atomic_fetch_or
2396
2397template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002398_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002399typename enable_if
2400<
2401 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2402 _Tp
2403>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002404atomic_fetch_or(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002405{
2406 return __o->fetch_or(__op);
2407}
2408
2409template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002410_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002411typename enable_if
2412<
2413 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2414 _Tp
2415>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002416atomic_fetch_or(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002417{
2418 return __o->fetch_or(__op);
2419}
2420
2421// atomic_fetch_or_explicit
2422
2423template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002424_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002425typename enable_if
2426<
2427 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2428 _Tp
2429>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002430atomic_fetch_or_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002431{
2432 return __o->fetch_or(__op, __m);
2433}
2434
2435template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002436_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002437typename enable_if
2438<
2439 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2440 _Tp
2441>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002442atomic_fetch_or_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002443{
2444 return __o->fetch_or(__op, __m);
2445}
2446
2447// atomic_fetch_xor
2448
2449template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002450_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002451typename enable_if
2452<
2453 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2454 _Tp
2455>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002456atomic_fetch_xor(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002457{
2458 return __o->fetch_xor(__op);
2459}
2460
2461template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002462_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002463typename enable_if
2464<
2465 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2466 _Tp
2467>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002468atomic_fetch_xor(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002469{
2470 return __o->fetch_xor(__op);
2471}
2472
2473// atomic_fetch_xor_explicit
2474
2475template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002476_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002477typename enable_if
2478<
2479 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2480 _Tp
2481>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002482atomic_fetch_xor_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002483{
2484 return __o->fetch_xor(__op, __m);
2485}
2486
2487template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002488_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002489typename enable_if
2490<
2491 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2492 _Tp
2493>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002494atomic_fetch_xor_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002495{
2496 return __o->fetch_xor(__op, __m);
2497}
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002498
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002499// flag type and operations
2500
2501typedef struct atomic_flag
2502{
Davide Italiano011f80a2019-03-05 18:40:49 +00002503 __cxx_atomic_impl<_LIBCPP_ATOMIC_FLAG_TYPE> __a_;
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002504
2505 _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002506 bool test(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
2507 {return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m);}
2508 _LIBCPP_INLINE_VISIBILITY
2509 bool test(memory_order __m = memory_order_seq_cst) const _NOEXCEPT
2510 {return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m);}
2511
2512 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00002513 bool test_and_set(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00002514 {return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);}
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002515 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00002516 bool test_and_set(memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00002517 {return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);}
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002518 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00002519 void clear(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00002520 {__cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);}
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002521 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00002522 void clear(memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00002523 {__cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);}
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002524
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002525 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002526 void wait(bool __v, memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
2527 {__cxx_atomic_wait(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002528 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002529 void wait(bool __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT
2530 {__cxx_atomic_wait(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002531 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002532 void notify_one() volatile _NOEXCEPT
2533 {__cxx_atomic_notify_one(&__a_);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002534 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002535 void notify_one() _NOEXCEPT
2536 {__cxx_atomic_notify_one(&__a_);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002537 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002538 void notify_all() volatile _NOEXCEPT
2539 {__cxx_atomic_notify_all(&__a_);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002540 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002541 void notify_all() _NOEXCEPT
2542 {__cxx_atomic_notify_all(&__a_);}
2543
2544 _LIBCPP_INLINE_VISIBILITY
Davide Italiano011f80a2019-03-05 18:40:49 +00002545 atomic_flag() _NOEXCEPT _LIBCPP_DEFAULT
Howard Hinnant3d284222013-05-02 20:18:43 +00002546
Marshall Clowcf990752018-04-25 14:27:29 +00002547 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
Eric Fiselierfec26a92016-05-03 02:12:26 +00002548 atomic_flag(bool __b) _NOEXCEPT : __a_(__b) {} // EXTENSION
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002549
Eric Fiselier2d8515f2017-01-06 20:58:25 +00002550#ifndef _LIBCPP_CXX03_LANG
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002551 atomic_flag(const atomic_flag&) = delete;
2552 atomic_flag& operator=(const atomic_flag&) = delete;
2553 atomic_flag& operator=(const atomic_flag&) volatile = delete;
Eric Fiselier2d8515f2017-01-06 20:58:25 +00002554#else
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002555private:
Olivier Giroux161e6e82020-02-18 09:58:34 -05002556 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002557 atomic_flag(const atomic_flag&);
Olivier Giroux161e6e82020-02-18 09:58:34 -05002558 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002559 atomic_flag& operator=(const atomic_flag&);
Olivier Giroux161e6e82020-02-18 09:58:34 -05002560 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002561 atomic_flag& operator=(const atomic_flag&) volatile;
Eric Fiselier2d8515f2017-01-06 20:58:25 +00002562#endif
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002563} atomic_flag;
2564
Olivier Giroux161e6e82020-02-18 09:58:34 -05002565
2566inline _LIBCPP_INLINE_VISIBILITY
2567bool
2568atomic_flag_test(const volatile atomic_flag* __o) _NOEXCEPT
2569{
2570 return __o->test();
2571}
2572
2573inline _LIBCPP_INLINE_VISIBILITY
2574bool
2575atomic_flag_test(const atomic_flag* __o) _NOEXCEPT
2576{
2577 return __o->test();
2578}
2579
2580inline _LIBCPP_INLINE_VISIBILITY
2581bool
2582atomic_flag_test_explicit(const volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
2583{
2584 return __o->test(__m);
2585}
2586
2587inline _LIBCPP_INLINE_VISIBILITY
2588bool
2589atomic_flag_test_explicit(const atomic_flag* __o, memory_order __m) _NOEXCEPT
2590{
2591 return __o->test(__m);
2592}
2593
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002594inline _LIBCPP_INLINE_VISIBILITY
2595bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00002596atomic_flag_test_and_set(volatile atomic_flag* __o) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002597{
2598 return __o->test_and_set();
2599}
2600
2601inline _LIBCPP_INLINE_VISIBILITY
2602bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00002603atomic_flag_test_and_set(atomic_flag* __o) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002604{
2605 return __o->test_and_set();
2606}
2607
2608inline _LIBCPP_INLINE_VISIBILITY
2609bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00002610atomic_flag_test_and_set_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002611{
2612 return __o->test_and_set(__m);
2613}
2614
2615inline _LIBCPP_INLINE_VISIBILITY
2616bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00002617atomic_flag_test_and_set_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002618{
2619 return __o->test_and_set(__m);
2620}
2621
2622inline _LIBCPP_INLINE_VISIBILITY
2623void
Howard Hinnanteee2c142012-04-11 20:14:21 +00002624atomic_flag_clear(volatile atomic_flag* __o) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002625{
2626 __o->clear();
2627}
2628
2629inline _LIBCPP_INLINE_VISIBILITY
2630void
Howard Hinnanteee2c142012-04-11 20:14:21 +00002631atomic_flag_clear(atomic_flag* __o) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002632{
2633 __o->clear();
2634}
2635
2636inline _LIBCPP_INLINE_VISIBILITY
2637void
Howard Hinnanteee2c142012-04-11 20:14:21 +00002638atomic_flag_clear_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002639{
2640 __o->clear(__m);
2641}
2642
2643inline _LIBCPP_INLINE_VISIBILITY
2644void
Howard Hinnanteee2c142012-04-11 20:14:21 +00002645atomic_flag_clear_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002646{
2647 __o->clear(__m);
2648}
2649
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002650inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
Olivier Giroux161e6e82020-02-18 09:58:34 -05002651void
2652atomic_flag_wait(const volatile atomic_flag* __o, bool __v) _NOEXCEPT
2653{
2654 __o->wait(__v);
2655}
2656
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002657inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
Olivier Giroux161e6e82020-02-18 09:58:34 -05002658void
2659atomic_flag_wait(const atomic_flag* __o, bool __v) _NOEXCEPT
2660{
2661 __o->wait(__v);
2662}
2663
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002664inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
Olivier Giroux161e6e82020-02-18 09:58:34 -05002665void
2666atomic_flag_wait_explicit(const volatile atomic_flag* __o,
2667 bool __v, memory_order __m) _NOEXCEPT
2668{
2669 __o->wait(__v, __m);
2670}
2671
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002672inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
Olivier Giroux161e6e82020-02-18 09:58:34 -05002673void
2674atomic_flag_wait_explicit(const atomic_flag* __o,
2675 bool __v, memory_order __m) _NOEXCEPT
2676{
2677 __o->wait(__v, __m);
2678}
2679
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002680inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
Olivier Giroux161e6e82020-02-18 09:58:34 -05002681void
2682atomic_flag_notify_one(volatile atomic_flag* __o) _NOEXCEPT
2683{
2684 __o->notify_one();
2685}
2686
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002687inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
Olivier Giroux161e6e82020-02-18 09:58:34 -05002688void
2689atomic_flag_notify_one(atomic_flag* __o) _NOEXCEPT
2690{
2691 __o->notify_one();
2692}
2693
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002694inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
Olivier Giroux161e6e82020-02-18 09:58:34 -05002695void
2696atomic_flag_notify_all(volatile atomic_flag* __o) _NOEXCEPT
2697{
2698 __o->notify_all();
2699}
2700
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002701inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
Olivier Giroux161e6e82020-02-18 09:58:34 -05002702void
2703atomic_flag_notify_all(atomic_flag* __o) _NOEXCEPT
2704{
2705 __o->notify_all();
2706}
2707
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002708// fences
2709
2710inline _LIBCPP_INLINE_VISIBILITY
2711void
Howard Hinnanteee2c142012-04-11 20:14:21 +00002712atomic_thread_fence(memory_order __m) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002713{
Davide Italiano011f80a2019-03-05 18:40:49 +00002714 __cxx_atomic_thread_fence(__m);
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002715}
2716
2717inline _LIBCPP_INLINE_VISIBILITY
2718void
Howard Hinnanteee2c142012-04-11 20:14:21 +00002719atomic_signal_fence(memory_order __m) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002720{
Davide Italiano011f80a2019-03-05 18:40:49 +00002721 __cxx_atomic_signal_fence(__m);
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002722}
2723
Howard Hinnant96e4cd62010-12-07 23:24:41 +00002724// Atomics for standard typedef types
2725
Howard Hinnantf0af8d92013-01-04 18:58:50 +00002726typedef atomic<bool> atomic_bool;
Howard Hinnant96e4cd62010-12-07 23:24:41 +00002727typedef atomic<char> atomic_char;
2728typedef atomic<signed char> atomic_schar;
2729typedef atomic<unsigned char> atomic_uchar;
2730typedef atomic<short> atomic_short;
2731typedef atomic<unsigned short> atomic_ushort;
2732typedef atomic<int> atomic_int;
2733typedef atomic<unsigned int> atomic_uint;
2734typedef atomic<long> atomic_long;
2735typedef atomic<unsigned long> atomic_ulong;
2736typedef atomic<long long> atomic_llong;
2737typedef atomic<unsigned long long> atomic_ullong;
Arthur O'Dwyerafa5d5f2021-04-18 21:47:08 -04002738#ifndef _LIBCPP_HAS_NO_CHAR8_T
Marek Kurdej91bebaa2020-11-24 21:07:06 +01002739typedef atomic<char8_t> atomic_char8_t;
2740#endif
Howard Hinnant96e4cd62010-12-07 23:24:41 +00002741typedef atomic<char16_t> atomic_char16_t;
2742typedef atomic<char32_t> atomic_char32_t;
2743typedef atomic<wchar_t> atomic_wchar_t;
2744
2745typedef atomic<int_least8_t> atomic_int_least8_t;
2746typedef atomic<uint_least8_t> atomic_uint_least8_t;
2747typedef atomic<int_least16_t> atomic_int_least16_t;
2748typedef atomic<uint_least16_t> atomic_uint_least16_t;
2749typedef atomic<int_least32_t> atomic_int_least32_t;
2750typedef atomic<uint_least32_t> atomic_uint_least32_t;
2751typedef atomic<int_least64_t> atomic_int_least64_t;
2752typedef atomic<uint_least64_t> atomic_uint_least64_t;
2753
2754typedef atomic<int_fast8_t> atomic_int_fast8_t;
2755typedef atomic<uint_fast8_t> atomic_uint_fast8_t;
2756typedef atomic<int_fast16_t> atomic_int_fast16_t;
2757typedef atomic<uint_fast16_t> atomic_uint_fast16_t;
2758typedef atomic<int_fast32_t> atomic_int_fast32_t;
2759typedef atomic<uint_fast32_t> atomic_uint_fast32_t;
2760typedef atomic<int_fast64_t> atomic_int_fast64_t;
2761typedef atomic<uint_fast64_t> atomic_uint_fast64_t;
2762
Marshall Clowf710afc2016-06-30 15:28:38 +00002763typedef atomic< int8_t> atomic_int8_t;
2764typedef atomic<uint8_t> atomic_uint8_t;
2765typedef atomic< int16_t> atomic_int16_t;
2766typedef atomic<uint16_t> atomic_uint16_t;
2767typedef atomic< int32_t> atomic_int32_t;
2768typedef atomic<uint32_t> atomic_uint32_t;
2769typedef atomic< int64_t> atomic_int64_t;
2770typedef atomic<uint64_t> atomic_uint64_t;
2771
Howard Hinnant96e4cd62010-12-07 23:24:41 +00002772typedef atomic<intptr_t> atomic_intptr_t;
2773typedef atomic<uintptr_t> atomic_uintptr_t;
2774typedef atomic<size_t> atomic_size_t;
2775typedef atomic<ptrdiff_t> atomic_ptrdiff_t;
2776typedef atomic<intmax_t> atomic_intmax_t;
2777typedef atomic<uintmax_t> atomic_uintmax_t;
2778
Olivier Giroux161e6e82020-02-18 09:58:34 -05002779// atomic_*_lock_free : prefer the contention type most highly, then the largest lock-free type
2780
2781#ifdef __cpp_lib_atomic_is_always_lock_free
2782# define _LIBCPP_CONTENTION_LOCK_FREE __atomic_always_lock_free(sizeof(__cxx_contention_t), 0)
2783#else
2784# define _LIBCPP_CONTENTION_LOCK_FREE false
2785#endif
2786
2787#if ATOMIC_LLONG_LOCK_FREE == 2
2788typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, long long>::type __libcpp_signed_lock_free;
2789typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned long long>::type __libcpp_unsigned_lock_free;
2790#elif ATOMIC_INT_LOCK_FREE == 2
2791typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, int>::type __libcpp_signed_lock_free;
2792typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned int>::type __libcpp_unsigned_lock_free;
2793#elif ATOMIC_SHORT_LOCK_FREE == 2
2794typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, short>::type __libcpp_signed_lock_free;
2795typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned short>::type __libcpp_unsigned_lock_free;
2796#elif ATOMIC_CHAR_LOCK_FREE == 2
2797typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, char>::type __libcpp_signed_lock_free;
2798typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned char>::type __libcpp_unsigned_lock_free;
2799#else
2800 // No signed/unsigned lock-free types
2801#endif
2802
2803typedef atomic<__libcpp_signed_lock_free> atomic_signed_lock_free;
2804typedef atomic<__libcpp_unsigned_lock_free> atomic_unsigned_lock_free;
2805
Howard Hinnantf1f066a2010-09-29 21:20:03 +00002806#define ATOMIC_FLAG_INIT {false}
Howard Hinnant953c31d2010-10-04 18:52:54 +00002807#define ATOMIC_VAR_INIT(__v) {__v}
2808
Howard Hinnant71be7292010-09-27 21:17:38 +00002809_LIBCPP_END_NAMESPACE_STD
2810
Louis Dionne2b1ceaa2021-04-20 12:03:32 -04002811#endif // _LIBCPP_ATOMIC