blob: c25bea81d6f2c895706e9d015ea0f4ca7e57975a [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
JF Bastienfdb42c22016-03-25 15:48:21 +000019// feature test macro
20
21#define __cpp_lib_atomic_is_always_lock_free // as specified by SG10
22
Davide Italiano011f80a2019-03-05 18:40:49 +000023 // order and consistency
Howard Hinnant71be7292010-09-27 21:17:38 +000024
Davide Italiano011f80a2019-03-05 18:40:49 +000025 enum memory_order: unspecified // enum class in C++20
26 {
27 relaxed,
28 consume, // load-consume
29 acquire, // load-acquire
30 release, // store-release
31 acq_rel, // store-release load-acquire
32 seq_cst // store-release load-acquire
33 };
34
35 inline constexpr auto memory_order_relaxed = memory_order::relaxed;
36 inline constexpr auto memory_order_consume = memory_order::consume;
37 inline constexpr auto memory_order_acquire = memory_order::acquire;
38 inline constexpr auto memory_order_release = memory_order::release;
39 inline constexpr auto memory_order_acq_rel = memory_order::acq_rel;
40 inline constexpr auto memory_order_seq_cst = memory_order::seq_cst;
Howard Hinnant71be7292010-09-27 21:17:38 +000041
Howard Hinnanteee2c142012-04-11 20:14:21 +000042template <class T> T kill_dependency(T y) noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +000043
44// lock-free property
45
Howard Hinnant931e3402013-01-21 20:39:41 +000046#define ATOMIC_BOOL_LOCK_FREE unspecified
Howard Hinnant71be7292010-09-27 21:17:38 +000047#define ATOMIC_CHAR_LOCK_FREE unspecified
48#define ATOMIC_CHAR16_T_LOCK_FREE unspecified
49#define ATOMIC_CHAR32_T_LOCK_FREE unspecified
50#define ATOMIC_WCHAR_T_LOCK_FREE unspecified
51#define ATOMIC_SHORT_LOCK_FREE unspecified
52#define ATOMIC_INT_LOCK_FREE unspecified
53#define ATOMIC_LONG_LOCK_FREE unspecified
54#define ATOMIC_LLONG_LOCK_FREE unspecified
Howard Hinnant931e3402013-01-21 20:39:41 +000055#define ATOMIC_POINTER_LOCK_FREE unspecified
Howard Hinnant71be7292010-09-27 21:17:38 +000056
Howard Hinnant71be7292010-09-27 21:17:38 +000057// flag type and operations
58
59typedef struct atomic_flag
60{
Howard Hinnanteee2c142012-04-11 20:14:21 +000061 bool test_and_set(memory_order m = memory_order_seq_cst) volatile noexcept;
62 bool test_and_set(memory_order m = memory_order_seq_cst) noexcept;
63 void clear(memory_order m = memory_order_seq_cst) volatile noexcept;
64 void clear(memory_order m = memory_order_seq_cst) noexcept;
65 atomic_flag() noexcept = default;
Howard Hinnant71be7292010-09-27 21:17:38 +000066 atomic_flag(const atomic_flag&) = delete;
67 atomic_flag& operator=(const atomic_flag&) = delete;
68 atomic_flag& operator=(const atomic_flag&) volatile = delete;
69} atomic_flag;
70
Howard Hinnant7bfaeb82010-12-06 23:10:08 +000071bool
Howard Hinnanteee2c142012-04-11 20:14:21 +000072 atomic_flag_test_and_set(volatile atomic_flag* obj) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +000073
74bool
Howard Hinnanteee2c142012-04-11 20:14:21 +000075 atomic_flag_test_and_set(atomic_flag* obj) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +000076
77bool
78 atomic_flag_test_and_set_explicit(volatile atomic_flag* obj,
Howard Hinnanteee2c142012-04-11 20:14:21 +000079 memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +000080
81bool
Howard Hinnanteee2c142012-04-11 20:14:21 +000082 atomic_flag_test_and_set_explicit(atomic_flag* obj, memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +000083
84void
Howard Hinnanteee2c142012-04-11 20:14:21 +000085 atomic_flag_clear(volatile atomic_flag* obj) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +000086
87void
Howard Hinnanteee2c142012-04-11 20:14:21 +000088 atomic_flag_clear(atomic_flag* obj) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +000089
90void
Howard Hinnanteee2c142012-04-11 20:14:21 +000091 atomic_flag_clear_explicit(volatile atomic_flag* obj, memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +000092
93void
Howard Hinnanteee2c142012-04-11 20:14:21 +000094 atomic_flag_clear_explicit(atomic_flag* obj, memory_order m) noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +000095
96#define ATOMIC_FLAG_INIT see below
Howard Hinnant493d1d92010-10-19 16:51:18 +000097#define ATOMIC_VAR_INIT(value) see below
Howard Hinnant71be7292010-09-27 21:17:38 +000098
Howard Hinnant71be7292010-09-27 21:17:38 +000099template <class T>
100struct atomic
101{
JF Bastienfdb42c22016-03-25 15:48:21 +0000102 static constexpr bool is_always_lock_free;
Howard Hinnanteee2c142012-04-11 20:14:21 +0000103 bool is_lock_free() const volatile noexcept;
104 bool is_lock_free() const noexcept;
105 void store(T desr, memory_order m = memory_order_seq_cst) volatile noexcept;
106 void store(T desr, memory_order m = memory_order_seq_cst) noexcept;
107 T load(memory_order m = memory_order_seq_cst) const volatile noexcept;
108 T load(memory_order m = memory_order_seq_cst) const noexcept;
109 operator T() const volatile noexcept;
110 operator T() const noexcept;
111 T exchange(T desr, memory_order m = memory_order_seq_cst) volatile noexcept;
112 T exchange(T desr, memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000113 bool compare_exchange_weak(T& expc, T desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000114 memory_order s, memory_order f) volatile noexcept;
115 bool compare_exchange_weak(T& expc, T desr, memory_order s, memory_order f) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000116 bool compare_exchange_strong(T& expc, T desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000117 memory_order s, memory_order f) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000118 bool compare_exchange_strong(T& expc, T desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000119 memory_order s, memory_order f) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000120 bool compare_exchange_weak(T& expc, T desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000121 memory_order m = memory_order_seq_cst) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000122 bool compare_exchange_weak(T& expc, T desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000123 memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000124 bool compare_exchange_strong(T& expc, T desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000125 memory_order m = memory_order_seq_cst) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000126 bool compare_exchange_strong(T& expc, T desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000127 memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +0000128
Howard Hinnanteee2c142012-04-11 20:14:21 +0000129 atomic() noexcept = default;
130 constexpr atomic(T desr) noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +0000131 atomic(const atomic&) = delete;
132 atomic& operator=(const atomic&) = delete;
133 atomic& operator=(const atomic&) volatile = delete;
Howard Hinnanteee2c142012-04-11 20:14:21 +0000134 T operator=(T) volatile noexcept;
135 T operator=(T) noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +0000136};
137
138template <>
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000139struct atomic<integral>
Howard Hinnant71be7292010-09-27 21:17:38 +0000140{
JF Bastienfdb42c22016-03-25 15:48:21 +0000141 static constexpr bool is_always_lock_free;
Howard Hinnanteee2c142012-04-11 20:14:21 +0000142 bool is_lock_free() const volatile noexcept;
143 bool is_lock_free() const noexcept;
144 void store(integral desr, memory_order m = memory_order_seq_cst) volatile noexcept;
145 void store(integral desr, memory_order m = memory_order_seq_cst) noexcept;
146 integral load(memory_order m = memory_order_seq_cst) const volatile noexcept;
147 integral load(memory_order m = memory_order_seq_cst) const noexcept;
148 operator integral() const volatile noexcept;
149 operator integral() const noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000150 integral exchange(integral desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000151 memory_order m = memory_order_seq_cst) volatile noexcept;
152 integral exchange(integral desr, memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000153 bool compare_exchange_weak(integral& expc, integral desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000154 memory_order s, memory_order f) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000155 bool compare_exchange_weak(integral& expc, integral desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000156 memory_order s, memory_order f) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000157 bool compare_exchange_strong(integral& expc, integral desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000158 memory_order s, memory_order f) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000159 bool compare_exchange_strong(integral& expc, integral desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000160 memory_order s, memory_order f) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000161 bool compare_exchange_weak(integral& expc, integral desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000162 memory_order m = memory_order_seq_cst) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000163 bool compare_exchange_weak(integral& expc, integral desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000164 memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000165 bool compare_exchange_strong(integral& expc, integral desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000166 memory_order m = memory_order_seq_cst) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000167 bool compare_exchange_strong(integral& expc, integral desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000168 memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +0000169
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000170 integral
Howard Hinnanteee2c142012-04-11 20:14:21 +0000171 fetch_add(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
172 integral fetch_add(integral op, memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000173 integral
Howard Hinnanteee2c142012-04-11 20:14:21 +0000174 fetch_sub(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
175 integral fetch_sub(integral op, memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000176 integral
Howard Hinnanteee2c142012-04-11 20:14:21 +0000177 fetch_and(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
178 integral fetch_and(integral op, memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000179 integral
Howard Hinnanteee2c142012-04-11 20:14:21 +0000180 fetch_or(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
181 integral fetch_or(integral op, memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000182 integral
Howard Hinnanteee2c142012-04-11 20:14:21 +0000183 fetch_xor(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
184 integral fetch_xor(integral op, memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +0000185
Howard Hinnanteee2c142012-04-11 20:14:21 +0000186 atomic() noexcept = default;
187 constexpr atomic(integral desr) noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +0000188 atomic(const atomic&) = delete;
189 atomic& operator=(const atomic&) = delete;
190 atomic& operator=(const atomic&) volatile = delete;
Howard Hinnanteee2c142012-04-11 20:14:21 +0000191 integral operator=(integral desr) volatile noexcept;
192 integral operator=(integral desr) noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +0000193
Howard Hinnanteee2c142012-04-11 20:14:21 +0000194 integral operator++(int) volatile noexcept;
195 integral operator++(int) noexcept;
196 integral operator--(int) volatile noexcept;
197 integral operator--(int) noexcept;
198 integral operator++() volatile noexcept;
199 integral operator++() noexcept;
200 integral operator--() volatile noexcept;
201 integral operator--() noexcept;
202 integral operator+=(integral op) volatile noexcept;
203 integral operator+=(integral op) noexcept;
204 integral operator-=(integral op) volatile noexcept;
205 integral operator-=(integral op) noexcept;
206 integral operator&=(integral op) volatile noexcept;
207 integral operator&=(integral op) noexcept;
208 integral operator|=(integral op) volatile noexcept;
209 integral operator|=(integral op) noexcept;
210 integral operator^=(integral op) volatile noexcept;
211 integral operator^=(integral op) noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +0000212};
213
214template <class T>
215struct atomic<T*>
Howard Hinnant71be7292010-09-27 21:17:38 +0000216{
JF Bastienfdb42c22016-03-25 15:48:21 +0000217 static constexpr bool is_always_lock_free;
Howard Hinnanteee2c142012-04-11 20:14:21 +0000218 bool is_lock_free() const volatile noexcept;
219 bool is_lock_free() const noexcept;
220 void store(T* desr, memory_order m = memory_order_seq_cst) volatile noexcept;
221 void store(T* desr, memory_order m = memory_order_seq_cst) noexcept;
222 T* load(memory_order m = memory_order_seq_cst) const volatile noexcept;
223 T* load(memory_order m = memory_order_seq_cst) const noexcept;
224 operator T*() const volatile noexcept;
225 operator T*() const noexcept;
226 T* exchange(T* desr, memory_order m = memory_order_seq_cst) volatile noexcept;
227 T* exchange(T* desr, memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000228 bool compare_exchange_weak(T*& expc, T* desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000229 memory_order s, memory_order f) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000230 bool compare_exchange_weak(T*& expc, T* desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000231 memory_order s, memory_order f) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000232 bool compare_exchange_strong(T*& expc, T* desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000233 memory_order s, memory_order f) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000234 bool compare_exchange_strong(T*& expc, T* desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000235 memory_order s, memory_order f) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000236 bool compare_exchange_weak(T*& expc, T* desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000237 memory_order m = memory_order_seq_cst) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000238 bool compare_exchange_weak(T*& expc, T* desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000239 memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000240 bool compare_exchange_strong(T*& expc, T* desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000241 memory_order m = memory_order_seq_cst) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000242 bool compare_exchange_strong(T*& expc, T* desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000243 memory_order m = memory_order_seq_cst) noexcept;
244 T* fetch_add(ptrdiff_t op, memory_order m = memory_order_seq_cst) volatile noexcept;
245 T* fetch_add(ptrdiff_t op, memory_order m = memory_order_seq_cst) noexcept;
246 T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst) volatile noexcept;
247 T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000248
Howard Hinnanteee2c142012-04-11 20:14:21 +0000249 atomic() noexcept = default;
250 constexpr atomic(T* desr) noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +0000251 atomic(const atomic&) = delete;
252 atomic& operator=(const atomic&) = delete;
253 atomic& operator=(const atomic&) volatile = delete;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000254
Howard Hinnanteee2c142012-04-11 20:14:21 +0000255 T* operator=(T*) volatile noexcept;
256 T* operator=(T*) noexcept;
257 T* operator++(int) volatile noexcept;
258 T* operator++(int) noexcept;
259 T* operator--(int) volatile noexcept;
260 T* operator--(int) noexcept;
261 T* operator++() volatile noexcept;
262 T* operator++() noexcept;
263 T* operator--() volatile noexcept;
264 T* operator--() noexcept;
265 T* operator+=(ptrdiff_t op) volatile noexcept;
266 T* operator+=(ptrdiff_t op) noexcept;
267 T* operator-=(ptrdiff_t op) volatile noexcept;
268 T* operator-=(ptrdiff_t op) noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +0000269};
270
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000271
272template <class T>
273 bool
Howard Hinnanteee2c142012-04-11 20:14:21 +0000274 atomic_is_lock_free(const volatile atomic<T>* obj) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000275
276template <class T>
277 bool
Howard Hinnanteee2c142012-04-11 20:14:21 +0000278 atomic_is_lock_free(const atomic<T>* obj) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000279
280template <class T>
281 void
Howard Hinnanteee2c142012-04-11 20:14:21 +0000282 atomic_init(volatile atomic<T>* obj, T desr) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000283
284template <class T>
285 void
Howard Hinnanteee2c142012-04-11 20:14:21 +0000286 atomic_init(atomic<T>* obj, T desr) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000287
288template <class T>
289 void
Howard Hinnanteee2c142012-04-11 20:14:21 +0000290 atomic_store(volatile atomic<T>* obj, T desr) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000291
292template <class T>
293 void
Howard Hinnanteee2c142012-04-11 20:14:21 +0000294 atomic_store(atomic<T>* obj, T desr) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000295
296template <class T>
297 void
Howard Hinnanteee2c142012-04-11 20:14:21 +0000298 atomic_store_explicit(volatile atomic<T>* obj, T desr, memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000299
300template <class T>
301 void
Howard Hinnanteee2c142012-04-11 20:14:21 +0000302 atomic_store_explicit(atomic<T>* obj, T desr, memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000303
304template <class T>
305 T
Howard Hinnanteee2c142012-04-11 20:14:21 +0000306 atomic_load(const volatile atomic<T>* obj) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000307
308template <class T>
309 T
Howard Hinnanteee2c142012-04-11 20:14:21 +0000310 atomic_load(const atomic<T>* obj) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000311
312template <class T>
313 T
Howard Hinnanteee2c142012-04-11 20:14:21 +0000314 atomic_load_explicit(const volatile atomic<T>* obj, memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000315
316template <class T>
317 T
Howard Hinnanteee2c142012-04-11 20:14:21 +0000318 atomic_load_explicit(const atomic<T>* obj, memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000319
320template <class T>
321 T
Howard Hinnanteee2c142012-04-11 20:14:21 +0000322 atomic_exchange(volatile atomic<T>* obj, T desr) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000323
324template <class T>
325 T
Howard Hinnanteee2c142012-04-11 20:14:21 +0000326 atomic_exchange(atomic<T>* obj, T desr) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000327
328template <class T>
329 T
Howard Hinnanteee2c142012-04-11 20:14:21 +0000330 atomic_exchange_explicit(volatile atomic<T>* obj, T desr, memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000331
332template <class T>
333 T
Howard Hinnanteee2c142012-04-11 20:14:21 +0000334 atomic_exchange_explicit(atomic<T>* obj, T desr, memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000335
336template <class T>
337 bool
Howard Hinnanteee2c142012-04-11 20:14:21 +0000338 atomic_compare_exchange_weak(volatile atomic<T>* obj, T* expc, T desr) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000339
340template <class T>
341 bool
Howard Hinnanteee2c142012-04-11 20:14:21 +0000342 atomic_compare_exchange_weak(atomic<T>* obj, T* expc, T desr) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000343
344template <class T>
345 bool
Howard Hinnanteee2c142012-04-11 20:14:21 +0000346 atomic_compare_exchange_strong(volatile atomic<T>* obj, T* expc, T desr) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000347
348template <class T>
349 bool
Howard Hinnanteee2c142012-04-11 20:14:21 +0000350 atomic_compare_exchange_strong(atomic<T>* obj, T* expc, T desr) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000351
352template <class T>
353 bool
354 atomic_compare_exchange_weak_explicit(volatile atomic<T>* obj, T* expc,
355 T desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000356 memory_order s, memory_order f) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000357
358template <class T>
359 bool
360 atomic_compare_exchange_weak_explicit(atomic<T>* obj, T* expc, T desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000361 memory_order s, memory_order f) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000362
363template <class T>
364 bool
365 atomic_compare_exchange_strong_explicit(volatile atomic<T>* obj,
366 T* expc, T desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000367 memory_order s, memory_order f) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000368
369template <class T>
370 bool
371 atomic_compare_exchange_strong_explicit(atomic<T>* obj, T* expc,
372 T desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000373 memory_order s, memory_order f) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000374
375template <class Integral>
376 Integral
Howard Hinnanteee2c142012-04-11 20:14:21 +0000377 atomic_fetch_add(volatile atomic<Integral>* obj, Integral op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000378
379template <class Integral>
380 Integral
Howard Hinnanteee2c142012-04-11 20:14:21 +0000381 atomic_fetch_add(atomic<Integral>* obj, Integral op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000382
383template <class Integral>
384 Integral
385 atomic_fetch_add_explicit(volatile atomic<Integral>* obj, Integral op,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000386 memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000387template <class Integral>
388 Integral
389 atomic_fetch_add_explicit(atomic<Integral>* obj, Integral op,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000390 memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000391template <class Integral>
392 Integral
Howard Hinnanteee2c142012-04-11 20:14:21 +0000393 atomic_fetch_sub(volatile atomic<Integral>* obj, Integral op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000394
395template <class Integral>
396 Integral
Howard Hinnanteee2c142012-04-11 20:14:21 +0000397 atomic_fetch_sub(atomic<Integral>* obj, Integral op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000398
399template <class Integral>
400 Integral
401 atomic_fetch_sub_explicit(volatile atomic<Integral>* obj, Integral op,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000402 memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000403template <class Integral>
404 Integral
405 atomic_fetch_sub_explicit(atomic<Integral>* obj, Integral op,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000406 memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000407template <class Integral>
408 Integral
Howard Hinnanteee2c142012-04-11 20:14:21 +0000409 atomic_fetch_and(volatile atomic<Integral>* obj, Integral op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000410
411template <class Integral>
412 Integral
Howard Hinnanteee2c142012-04-11 20:14:21 +0000413 atomic_fetch_and(atomic<Integral>* obj, Integral op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000414
415template <class Integral>
416 Integral
417 atomic_fetch_and_explicit(volatile atomic<Integral>* obj, Integral op,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000418 memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000419template <class Integral>
420 Integral
421 atomic_fetch_and_explicit(atomic<Integral>* obj, Integral op,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000422 memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000423template <class Integral>
424 Integral
Howard Hinnanteee2c142012-04-11 20:14:21 +0000425 atomic_fetch_or(volatile atomic<Integral>* obj, Integral op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000426
427template <class Integral>
428 Integral
Howard Hinnanteee2c142012-04-11 20:14:21 +0000429 atomic_fetch_or(atomic<Integral>* obj, Integral op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000430
431template <class Integral>
432 Integral
433 atomic_fetch_or_explicit(volatile atomic<Integral>* obj, Integral op,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000434 memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000435template <class Integral>
436 Integral
437 atomic_fetch_or_explicit(atomic<Integral>* obj, Integral op,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000438 memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000439template <class Integral>
440 Integral
Howard Hinnanteee2c142012-04-11 20:14:21 +0000441 atomic_fetch_xor(volatile atomic<Integral>* obj, Integral op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000442
443template <class Integral>
444 Integral
Howard Hinnanteee2c142012-04-11 20:14:21 +0000445 atomic_fetch_xor(atomic<Integral>* obj, Integral op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000446
447template <class Integral>
448 Integral
449 atomic_fetch_xor_explicit(volatile atomic<Integral>* obj, Integral op,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000450 memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000451template <class Integral>
452 Integral
453 atomic_fetch_xor_explicit(atomic<Integral>* obj, Integral op,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000454 memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000455
456template <class T>
457 T*
Howard Hinnanteee2c142012-04-11 20:14:21 +0000458 atomic_fetch_add(volatile atomic<T*>* obj, ptrdiff_t op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000459
460template <class T>
461 T*
Howard Hinnanteee2c142012-04-11 20:14:21 +0000462 atomic_fetch_add(atomic<T*>* obj, ptrdiff_t op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000463
464template <class T>
465 T*
466 atomic_fetch_add_explicit(volatile atomic<T*>* obj, ptrdiff_t op,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000467 memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000468template <class T>
469 T*
Howard Hinnanteee2c142012-04-11 20:14:21 +0000470 atomic_fetch_add_explicit(atomic<T*>* obj, ptrdiff_t op, memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000471
472template <class T>
473 T*
Howard Hinnanteee2c142012-04-11 20:14:21 +0000474 atomic_fetch_sub(volatile atomic<T*>* obj, ptrdiff_t op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000475
476template <class T>
477 T*
Howard Hinnanteee2c142012-04-11 20:14:21 +0000478 atomic_fetch_sub(atomic<T*>* obj, ptrdiff_t op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000479
480template <class T>
481 T*
482 atomic_fetch_sub_explicit(volatile atomic<T*>* obj, ptrdiff_t op,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000483 memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000484template <class T>
485 T*
Howard Hinnanteee2c142012-04-11 20:14:21 +0000486 atomic_fetch_sub_explicit(atomic<T*>* obj, ptrdiff_t op, memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000487
488// Atomics for standard typedef types
489
Howard Hinnantf0af8d92013-01-04 18:58:50 +0000490typedef atomic<bool> atomic_bool;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000491typedef atomic<char> atomic_char;
492typedef atomic<signed char> atomic_schar;
493typedef atomic<unsigned char> atomic_uchar;
494typedef atomic<short> atomic_short;
495typedef atomic<unsigned short> atomic_ushort;
496typedef atomic<int> atomic_int;
497typedef atomic<unsigned int> atomic_uint;
498typedef atomic<long> atomic_long;
499typedef atomic<unsigned long> atomic_ulong;
500typedef atomic<long long> atomic_llong;
501typedef atomic<unsigned long long> atomic_ullong;
502typedef atomic<char16_t> atomic_char16_t;
503typedef atomic<char32_t> atomic_char32_t;
504typedef atomic<wchar_t> atomic_wchar_t;
505
506typedef atomic<int_least8_t> atomic_int_least8_t;
507typedef atomic<uint_least8_t> atomic_uint_least8_t;
508typedef atomic<int_least16_t> atomic_int_least16_t;
509typedef atomic<uint_least16_t> atomic_uint_least16_t;
510typedef atomic<int_least32_t> atomic_int_least32_t;
511typedef atomic<uint_least32_t> atomic_uint_least32_t;
512typedef atomic<int_least64_t> atomic_int_least64_t;
513typedef atomic<uint_least64_t> atomic_uint_least64_t;
514
515typedef atomic<int_fast8_t> atomic_int_fast8_t;
516typedef atomic<uint_fast8_t> atomic_uint_fast8_t;
517typedef atomic<int_fast16_t> atomic_int_fast16_t;
518typedef atomic<uint_fast16_t> atomic_uint_fast16_t;
519typedef atomic<int_fast32_t> atomic_int_fast32_t;
520typedef atomic<uint_fast32_t> atomic_uint_fast32_t;
521typedef atomic<int_fast64_t> atomic_int_fast64_t;
522typedef atomic<uint_fast64_t> atomic_uint_fast64_t;
523
Marshall Clowf710afc2016-06-30 15:28:38 +0000524typedef atomic<int8_t> atomic_int8_t;
525typedef atomic<uint8_t> atomic_uint8_t;
526typedef atomic<int16_t> atomic_int16_t;
527typedef atomic<uint16_t> atomic_uint16_t;
528typedef atomic<int32_t> atomic_int32_t;
529typedef atomic<uint32_t> atomic_uint32_t;
530typedef atomic<int64_t> atomic_int64_t;
531typedef atomic<uint64_t> atomic_uint64_t;
532
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000533typedef atomic<intptr_t> atomic_intptr_t;
534typedef atomic<uintptr_t> atomic_uintptr_t;
535typedef atomic<size_t> atomic_size_t;
536typedef atomic<ptrdiff_t> atomic_ptrdiff_t;
537typedef atomic<intmax_t> atomic_intmax_t;
538typedef atomic<uintmax_t> atomic_uintmax_t;
539
Howard Hinnant71be7292010-09-27 21:17:38 +0000540// fences
541
Howard Hinnanteee2c142012-04-11 20:14:21 +0000542void atomic_thread_fence(memory_order m) noexcept;
543void atomic_signal_fence(memory_order m) noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +0000544
545} // std
546
547*/
548
549#include <__config>
Olivier Giroux161e6e82020-02-18 09:58:34 -0500550#include <__threading_support>
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000551#include <cstddef>
552#include <cstdint>
Olivier Giroux161e6e82020-02-18 09:58:34 -0500553#include <cstring>
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000554#include <type_traits>
Marshall Clow0a1e7502018-09-12 19:41:40 +0000555#include <version>
Howard Hinnant71be7292010-09-27 21:17:38 +0000556
Howard Hinnantaaaa52b2011-10-17 20:05:10 +0000557#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
Howard Hinnant71be7292010-09-27 21:17:38 +0000558#pragma GCC system_header
Howard Hinnantaaaa52b2011-10-17 20:05:10 +0000559#endif
Howard Hinnant71be7292010-09-27 21:17:38 +0000560
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000561#ifdef _LIBCPP_HAS_NO_THREADS
Davide Italiano011f80a2019-03-05 18:40:49 +0000562# error <atomic> is not supported on this single threaded system
Eric Fiselier8020b6c2015-08-19 17:21:46 +0000563#endif
Davide Italiano011f80a2019-03-05 18:40:49 +0000564#ifdef _LIBCPP_HAS_NO_ATOMIC_HEADER
565# error <atomic> is not implemented
Eric Fiselier8020b6c2015-08-19 17:21:46 +0000566#endif
Volodymyr Sapsaif3ed1fd2018-05-15 22:38:31 +0000567#ifdef kill_dependency
Davide Italiano011f80a2019-03-05 18:40:49 +0000568# error C++ standard library is incompatible with <stdatomic.h>
Volodymyr Sapsaif3ed1fd2018-05-15 22:38:31 +0000569#endif
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000570
Eric Fiselierb5ab51d2017-01-13 23:45:39 +0000571#define _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) \
572 _LIBCPP_DIAGNOSE_WARNING(__m == memory_order_consume || \
573 __m == memory_order_acquire || \
574 __m == memory_order_acq_rel, \
575 "memory order argument to atomic operation is invalid")
576
577#define _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) \
578 _LIBCPP_DIAGNOSE_WARNING(__m == memory_order_release || \
579 __m == memory_order_acq_rel, \
580 "memory order argument to atomic operation is invalid")
581
582#define _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__m, __f) \
583 _LIBCPP_DIAGNOSE_WARNING(__f == memory_order_release || \
584 __f == memory_order_acq_rel, \
585 "memory order argument to atomic operation is invalid")
586
Howard Hinnant71be7292010-09-27 21:17:38 +0000587_LIBCPP_BEGIN_NAMESPACE_STD
588
Eric Fiselierd4e3e5b2019-03-08 23:15:54 +0000589// Figure out what the underlying type for `memory_order` would be if it were
590// declared as an unscoped enum (accounting for -fshort-enums). Use this result
591// to pin the underlying type in C++20.
592enum __legacy_memory_order {
593 __mo_relaxed,
594 __mo_consume,
595 __mo_acquire,
596 __mo_release,
597 __mo_acq_rel,
598 __mo_seq_cst
599};
600
601typedef underlying_type<__legacy_memory_order>::type __memory_order_underlying_t;
602
Davide Italiano011f80a2019-03-05 18:40:49 +0000603#if _LIBCPP_STD_VER > 17
604
Eric Fiselierd4e3e5b2019-03-08 23:15:54 +0000605enum class memory_order : __memory_order_underlying_t {
606 relaxed = __mo_relaxed,
607 consume = __mo_consume,
608 acquire = __mo_acquire,
609 release = __mo_release,
610 acq_rel = __mo_acq_rel,
611 seq_cst = __mo_seq_cst
Davide Italiano011f80a2019-03-05 18:40:49 +0000612};
613
614inline constexpr auto memory_order_relaxed = memory_order::relaxed;
615inline constexpr auto memory_order_consume = memory_order::consume;
616inline constexpr auto memory_order_acquire = memory_order::acquire;
617inline constexpr auto memory_order_release = memory_order::release;
618inline constexpr auto memory_order_acq_rel = memory_order::acq_rel;
619inline constexpr auto memory_order_seq_cst = memory_order::seq_cst;
620
Davide Italiano011f80a2019-03-05 18:40:49 +0000621#else
622
623typedef enum memory_order {
Eric Fiselierd4e3e5b2019-03-08 23:15:54 +0000624 memory_order_relaxed = __mo_relaxed,
625 memory_order_consume = __mo_consume,
626 memory_order_acquire = __mo_acquire,
627 memory_order_release = __mo_release,
628 memory_order_acq_rel = __mo_acq_rel,
629 memory_order_seq_cst = __mo_seq_cst,
Howard Hinnantdca6e712010-09-28 17:13:38 +0000630} memory_order;
631
Davide Italiano011f80a2019-03-05 18:40:49 +0000632#endif // _LIBCPP_STD_VER > 17
633
Olivier Giroux161e6e82020-02-18 09:58:34 -0500634template <typename _Tp> _LIBCPP_INLINE_VISIBILITY
635bool __cxx_nonatomic_compare_equal(_Tp const& __lhs, _Tp const& __rhs) {
636 return memcmp(&__lhs, &__rhs, sizeof(_Tp)) == 0;
637}
638
Eric Fiselier51525172019-03-08 23:30:26 +0000639static_assert((is_same<underlying_type<memory_order>::type, __memory_order_underlying_t>::value),
Eric Fiselierd4e3e5b2019-03-08 23:15:54 +0000640 "unexpected underlying type for std::memory_order");
Davide Italiano011f80a2019-03-05 18:40:49 +0000641
642#if defined(_LIBCPP_HAS_GCC_ATOMIC_IMP) || \
643 defined(_LIBCPP_ATOMIC_ONLY_USE_BUILTINS)
644
645// [atomics.types.generic]p1 guarantees _Tp is trivially copyable. Because
646// the default operator= in an object is not volatile, a byte-by-byte copy
647// is required.
648template <typename _Tp, typename _Tv> _LIBCPP_INLINE_VISIBILITY
649typename enable_if<is_assignable<_Tp&, _Tv>::value>::type
650__cxx_atomic_assign_volatile(_Tp& __a_value, _Tv const& __val) {
651 __a_value = __val;
652}
653template <typename _Tp, typename _Tv> _LIBCPP_INLINE_VISIBILITY
654typename enable_if<is_assignable<_Tp&, _Tv>::value>::type
655__cxx_atomic_assign_volatile(_Tp volatile& __a_value, _Tv volatile const& __val) {
656 volatile char* __to = reinterpret_cast<volatile char*>(&__a_value);
657 volatile char* __end = __to + sizeof(_Tp);
658 volatile const char* __from = reinterpret_cast<volatile const char*>(&__val);
659 while (__to != __end)
660 *__to++ = *__from++;
661}
662
Davide Italiano31f218a2019-03-05 17:38:33 +0000663#endif
Louis Dionnea1ae0032019-03-04 15:26:27 +0000664
Davide Italiano011f80a2019-03-05 18:40:49 +0000665#if defined(_LIBCPP_HAS_GCC_ATOMIC_IMP)
666
667template <typename _Tp>
668struct __cxx_atomic_base_impl {
669
Eric Fiselier684aaca2015-10-14 08:36:22 +0000670 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier07b2b552016-11-18 06:42:17 +0000671#ifndef _LIBCPP_CXX03_LANG
Davide Italiano011f80a2019-03-05 18:40:49 +0000672 __cxx_atomic_base_impl() _NOEXCEPT = default;
Eric Fiselier684aaca2015-10-14 08:36:22 +0000673#else
Davide Italiano011f80a2019-03-05 18:40:49 +0000674 __cxx_atomic_base_impl() _NOEXCEPT : __a_value() {}
Eric Fiselier07b2b552016-11-18 06:42:17 +0000675#endif // _LIBCPP_CXX03_LANG
Davide Italiano011f80a2019-03-05 18:40:49 +0000676 _LIBCPP_CONSTEXPR explicit __cxx_atomic_base_impl(_Tp value) _NOEXCEPT
Eric Fiselier719e0442015-07-14 17:50:27 +0000677 : __a_value(value) {}
Marshall Clow290eb3f2015-01-11 06:15:59 +0000678 _Tp __a_value;
Dan Albert7b65ace2014-08-09 23:51:51 +0000679};
Dan Albert7b65ace2014-08-09 23:51:51 +0000680
Davide Italiano011f80a2019-03-05 18:40:49 +0000681_LIBCPP_INLINE_VISIBILITY inline _LIBCPP_CONSTEXPR int __to_gcc_order(memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000682 // Avoid switch statement to make this a constexpr.
683 return __order == memory_order_relaxed ? __ATOMIC_RELAXED:
684 (__order == memory_order_acquire ? __ATOMIC_ACQUIRE:
685 (__order == memory_order_release ? __ATOMIC_RELEASE:
686 (__order == memory_order_seq_cst ? __ATOMIC_SEQ_CST:
687 (__order == memory_order_acq_rel ? __ATOMIC_ACQ_REL:
688 __ATOMIC_CONSUME))));
689}
690
Davide Italiano011f80a2019-03-05 18:40:49 +0000691_LIBCPP_INLINE_VISIBILITY inline _LIBCPP_CONSTEXPR int __to_gcc_failure_order(memory_order __order) {
Dan Albert48815f22015-01-06 18:39:37 +0000692 // Avoid switch statement to make this a constexpr.
693 return __order == memory_order_relaxed ? __ATOMIC_RELAXED:
694 (__order == memory_order_acquire ? __ATOMIC_ACQUIRE:
695 (__order == memory_order_release ? __ATOMIC_RELAXED:
696 (__order == memory_order_seq_cst ? __ATOMIC_SEQ_CST:
697 (__order == memory_order_acq_rel ? __ATOMIC_ACQUIRE:
698 __ATOMIC_CONSUME))));
699}
700
Davide Italiano011f80a2019-03-05 18:40:49 +0000701template <typename _Tp>
702_LIBCPP_INLINE_VISIBILITY
703void __cxx_atomic_init(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __val) {
704 __cxx_atomic_assign_volatile(__a->__a_value, __val);
705}
Dan Albert7b65ace2014-08-09 23:51:51 +0000706
707template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000708_LIBCPP_INLINE_VISIBILITY
709void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp>* __a, _Tp __val) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000710 __a->__a_value = __val;
711}
712
Davide Italiano011f80a2019-03-05 18:40:49 +0000713_LIBCPP_INLINE_VISIBILITY inline
714void __cxx_atomic_thread_fence(memory_order __order) {
715 __atomic_thread_fence(__to_gcc_order(__order));
716}
717
718_LIBCPP_INLINE_VISIBILITY inline
719void __cxx_atomic_signal_fence(memory_order __order) {
720 __atomic_signal_fence(__to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000721}
722
723template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000724_LIBCPP_INLINE_VISIBILITY
725void __cxx_atomic_store(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __val,
726 memory_order __order) {
Dan Albert48815f22015-01-06 18:39:37 +0000727 __atomic_store(&__a->__a_value, &__val,
Davide Italiano011f80a2019-03-05 18:40:49 +0000728 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000729}
730
731template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000732_LIBCPP_INLINE_VISIBILITY
733void __cxx_atomic_store(__cxx_atomic_base_impl<_Tp>* __a, _Tp __val,
734 memory_order __order) {
735 __atomic_store(&__a->__a_value, &__val,
736 __to_gcc_order(__order));
737}
738
739template <typename _Tp>
740_LIBCPP_INLINE_VISIBILITY
741_Tp __cxx_atomic_load(const volatile __cxx_atomic_base_impl<_Tp>* __a,
742 memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000743 _Tp __ret;
744 __atomic_load(&__a->__a_value, &__ret,
Davide Italiano011f80a2019-03-05 18:40:49 +0000745 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000746 return __ret;
747}
748
749template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000750_LIBCPP_INLINE_VISIBILITY
751_Tp __cxx_atomic_load(const __cxx_atomic_base_impl<_Tp>* __a, memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000752 _Tp __ret;
753 __atomic_load(&__a->__a_value, &__ret,
Davide Italiano011f80a2019-03-05 18:40:49 +0000754 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000755 return __ret;
756}
757
758template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000759_LIBCPP_INLINE_VISIBILITY
760_Tp __cxx_atomic_exchange(volatile __cxx_atomic_base_impl<_Tp>* __a,
761 _Tp __value, memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000762 _Tp __ret;
763 __atomic_exchange(&__a->__a_value, &__value, &__ret,
Davide Italiano011f80a2019-03-05 18:40:49 +0000764 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000765 return __ret;
766}
767
768template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000769_LIBCPP_INLINE_VISIBILITY
770_Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp>* __a, _Tp __value,
771 memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000772 _Tp __ret;
773 __atomic_exchange(&__a->__a_value, &__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
780bool __cxx_atomic_compare_exchange_strong(
781 volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value,
JF Bastien6e412d92018-05-26 19:44:45 +0000782 memory_order __success, memory_order __failure) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000783 return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
784 false,
Davide Italiano011f80a2019-03-05 18:40:49 +0000785 __to_gcc_order(__success),
786 __to_gcc_failure_order(__failure));
Dan Albert7b65ace2014-08-09 23:51:51 +0000787}
788
789template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000790_LIBCPP_INLINE_VISIBILITY
791bool __cxx_atomic_compare_exchange_strong(
792 __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success,
JF Bastien6e412d92018-05-26 19:44:45 +0000793 memory_order __failure) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000794 return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
795 false,
Davide Italiano011f80a2019-03-05 18:40:49 +0000796 __to_gcc_order(__success),
797 __to_gcc_failure_order(__failure));
Dan Albert7b65ace2014-08-09 23:51:51 +0000798}
799
800template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000801_LIBCPP_INLINE_VISIBILITY
802bool __cxx_atomic_compare_exchange_weak(
803 volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value,
JF Bastien6e412d92018-05-26 19:44:45 +0000804 memory_order __success, memory_order __failure) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000805 return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
806 true,
Davide Italiano011f80a2019-03-05 18:40:49 +0000807 __to_gcc_order(__success),
808 __to_gcc_failure_order(__failure));
Dan Albert7b65ace2014-08-09 23:51:51 +0000809}
810
811template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000812_LIBCPP_INLINE_VISIBILITY
813bool __cxx_atomic_compare_exchange_weak(
814 __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success,
JF Bastien6e412d92018-05-26 19:44:45 +0000815 memory_order __failure) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000816 return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
817 true,
Davide Italiano011f80a2019-03-05 18:40:49 +0000818 __to_gcc_order(__success),
819 __to_gcc_failure_order(__failure));
Dan Albert7b65ace2014-08-09 23:51:51 +0000820}
821
822template <typename _Tp>
823struct __skip_amt { enum {value = 1}; };
824
825template <typename _Tp>
826struct __skip_amt<_Tp*> { enum {value = sizeof(_Tp)}; };
827
828// FIXME: Haven't figured out what the spec says about using arrays with
829// atomic_fetch_add. Force a failure rather than creating bad behavior.
830template <typename _Tp>
831struct __skip_amt<_Tp[]> { };
832template <typename _Tp, int n>
833struct __skip_amt<_Tp[n]> { };
834
835template <typename _Tp, typename _Td>
Davide Italiano011f80a2019-03-05 18:40:49 +0000836_LIBCPP_INLINE_VISIBILITY
837_Tp __cxx_atomic_fetch_add(volatile __cxx_atomic_base_impl<_Tp>* __a,
838 _Td __delta, memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000839 return __atomic_fetch_add(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
Davide Italiano011f80a2019-03-05 18:40:49 +0000840 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000841}
842
843template <typename _Tp, typename _Td>
Davide Italiano011f80a2019-03-05 18:40:49 +0000844_LIBCPP_INLINE_VISIBILITY
845_Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp>* __a, _Td __delta,
846 memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000847 return __atomic_fetch_add(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
Davide Italiano011f80a2019-03-05 18:40:49 +0000848 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000849}
850
851template <typename _Tp, typename _Td>
Davide Italiano011f80a2019-03-05 18:40:49 +0000852_LIBCPP_INLINE_VISIBILITY
853_Tp __cxx_atomic_fetch_sub(volatile __cxx_atomic_base_impl<_Tp>* __a,
854 _Td __delta, memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000855 return __atomic_fetch_sub(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
Davide Italiano011f80a2019-03-05 18:40:49 +0000856 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000857}
858
859template <typename _Tp, typename _Td>
Davide Italiano011f80a2019-03-05 18:40:49 +0000860_LIBCPP_INLINE_VISIBILITY
861_Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp>* __a, _Td __delta,
862 memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000863 return __atomic_fetch_sub(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
Davide Italiano011f80a2019-03-05 18:40:49 +0000864 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000865}
866
867template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000868_LIBCPP_INLINE_VISIBILITY
869_Tp __cxx_atomic_fetch_and(volatile __cxx_atomic_base_impl<_Tp>* __a,
870 _Tp __pattern, memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000871 return __atomic_fetch_and(&__a->__a_value, __pattern,
Davide Italiano011f80a2019-03-05 18:40:49 +0000872 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000873}
874
875template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000876_LIBCPP_INLINE_VISIBILITY
877_Tp __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp>* __a,
878 _Tp __pattern, memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000879 return __atomic_fetch_and(&__a->__a_value, __pattern,
Davide Italiano011f80a2019-03-05 18:40:49 +0000880 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000881}
882
883template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000884_LIBCPP_INLINE_VISIBILITY
885_Tp __cxx_atomic_fetch_or(volatile __cxx_atomic_base_impl<_Tp>* __a,
886 _Tp __pattern, memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000887 return __atomic_fetch_or(&__a->__a_value, __pattern,
Davide Italiano011f80a2019-03-05 18:40:49 +0000888 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000889}
890
891template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000892_LIBCPP_INLINE_VISIBILITY
893_Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern,
894 memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000895 return __atomic_fetch_or(&__a->__a_value, __pattern,
Davide Italiano011f80a2019-03-05 18:40:49 +0000896 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000897}
898
899template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000900_LIBCPP_INLINE_VISIBILITY
901_Tp __cxx_atomic_fetch_xor(volatile __cxx_atomic_base_impl<_Tp>* __a,
902 _Tp __pattern, memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000903 return __atomic_fetch_xor(&__a->__a_value, __pattern,
Davide Italiano011f80a2019-03-05 18:40:49 +0000904 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000905}
906
907template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000908_LIBCPP_INLINE_VISIBILITY
909_Tp __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern,
910 memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000911 return __atomic_fetch_xor(&__a->__a_value, __pattern,
Davide Italiano011f80a2019-03-05 18:40:49 +0000912 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000913}
Davide Italiano011f80a2019-03-05 18:40:49 +0000914
915#define __cxx_atomic_is_lock_free(__s) __atomic_is_lock_free(__s, 0)
916
917#elif defined(_LIBCPP_HAS_C_ATOMIC_IMP)
918
919template <typename _Tp>
920struct __cxx_atomic_base_impl {
921
922 _LIBCPP_INLINE_VISIBILITY
923#ifndef _LIBCPP_CXX03_LANG
924 __cxx_atomic_base_impl() _NOEXCEPT = default;
925#else
926 __cxx_atomic_base_impl() _NOEXCEPT : __a_value() {}
927#endif // _LIBCPP_CXX03_LANG
928 _LIBCPP_CONSTEXPR explicit __cxx_atomic_base_impl(_Tp value) _NOEXCEPT
929 : __a_value(value) {}
Louis Dionnefaa17452019-09-04 12:44:19 +0000930 _LIBCPP_DISABLE_EXTENSION_WARNING _Atomic(_Tp) __a_value;
Davide Italiano011f80a2019-03-05 18:40:49 +0000931};
932
933#define __cxx_atomic_is_lock_free(__s) __c11_atomic_is_lock_free(__s)
934
935_LIBCPP_INLINE_VISIBILITY inline
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000936void __cxx_atomic_thread_fence(memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +0000937 __c11_atomic_thread_fence(static_cast<__memory_order_underlying_t>(__order));
938}
939
940_LIBCPP_INLINE_VISIBILITY inline
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000941void __cxx_atomic_signal_fence(memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +0000942 __c11_atomic_signal_fence(static_cast<__memory_order_underlying_t>(__order));
943}
944
945template<class _Tp>
946_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000947void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __val) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +0000948 __c11_atomic_init(&__a->__a_value, __val);
949}
950template<class _Tp>
951_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000952void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp> * __a, _Tp __val) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +0000953 __c11_atomic_init(&__a->__a_value, __val);
954}
955
956template<class _Tp>
957_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000958void __cxx_atomic_store(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __val, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +0000959 __c11_atomic_store(&__a->__a_value, __val, static_cast<__memory_order_underlying_t>(__order));
960}
961template<class _Tp>
962_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000963void __cxx_atomic_store(__cxx_atomic_base_impl<_Tp> * __a, _Tp __val, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +0000964 __c11_atomic_store(&__a->__a_value, __val, static_cast<__memory_order_underlying_t>(__order));
965}
966
967template<class _Tp>
968_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000969_Tp __cxx_atomic_load(__cxx_atomic_base_impl<_Tp> const volatile* __a, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +0000970 using __ptr_type = typename remove_const<decltype(__a->__a_value)>::type*;
971 return __c11_atomic_load(const_cast<__ptr_type>(&__a->__a_value), static_cast<__memory_order_underlying_t>(__order));
972}
973template<class _Tp>
974_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000975_Tp __cxx_atomic_load(__cxx_atomic_base_impl<_Tp> const* __a, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +0000976 using __ptr_type = typename remove_const<decltype(__a->__a_value)>::type*;
977 return __c11_atomic_load(const_cast<__ptr_type>(&__a->__a_value), static_cast<__memory_order_underlying_t>(__order));
978}
979
980template<class _Tp>
981_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000982_Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __value, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +0000983 return __c11_atomic_exchange(&__a->__a_value, __value, static_cast<__memory_order_underlying_t>(__order));
984}
985template<class _Tp>
986_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000987_Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp> * __a, _Tp __value, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +0000988 return __c11_atomic_exchange(&__a->__a_value, __value, static_cast<__memory_order_underlying_t>(__order));
989}
990
991template<class _Tp>
992_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000993bool __cxx_atomic_compare_exchange_strong(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +0000994 return __c11_atomic_compare_exchange_strong(&__a->__a_value, __expected, __value, static_cast<__memory_order_underlying_t>(__success), static_cast<__memory_order_underlying_t>(__failure));
995}
996template<class _Tp>
997_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000998bool __cxx_atomic_compare_exchange_strong(__cxx_atomic_base_impl<_Tp> * __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +0000999 return __c11_atomic_compare_exchange_strong(&__a->__a_value, __expected, __value, static_cast<__memory_order_underlying_t>(__success), static_cast<__memory_order_underlying_t>(__failure));
1000}
1001
1002template<class _Tp>
1003_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001004bool __cxx_atomic_compare_exchange_weak(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +00001005 return __c11_atomic_compare_exchange_weak(&__a->__a_value, __expected, __value, static_cast<__memory_order_underlying_t>(__success), static_cast<__memory_order_underlying_t>(__failure));
1006}
1007template<class _Tp>
1008_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001009bool __cxx_atomic_compare_exchange_weak(__cxx_atomic_base_impl<_Tp> * __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +00001010 return __c11_atomic_compare_exchange_weak(&__a->__a_value, __expected, __value, static_cast<__memory_order_underlying_t>(__success), static_cast<__memory_order_underlying_t>(__failure));
1011}
1012
1013template<class _Tp>
1014_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001015_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 +00001016 return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
1017}
1018template<class _Tp>
1019_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001020_Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp> * __a, _Tp __delta, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +00001021 return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
1022}
1023
1024template<class _Tp>
1025_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001026_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 +00001027 return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
1028}
1029template<class _Tp>
1030_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001031_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 +00001032 return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
1033}
1034
1035template<class _Tp>
1036_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001037_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 +00001038 return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
1039}
1040template<class _Tp>
1041_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001042_Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp> * __a, _Tp __delta, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +00001043 return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
1044}
1045template<class _Tp>
1046_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001047_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 +00001048 return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
1049}
1050template<class _Tp>
1051_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001052_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 +00001053 return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
1054}
1055
1056template<class _Tp>
1057_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001058_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 +00001059 return __c11_atomic_fetch_and(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
1060}
1061template<class _Tp>
1062_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001063_Tp __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +00001064 return __c11_atomic_fetch_and(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
1065}
1066
1067template<class _Tp>
1068_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001069_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 +00001070 return __c11_atomic_fetch_or(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
1071}
1072template<class _Tp>
1073_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001074_Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +00001075 return __c11_atomic_fetch_or(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
1076}
1077
1078template<class _Tp>
1079_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001080_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 +00001081 return __c11_atomic_fetch_xor(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
1082}
1083template<class _Tp>
1084_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001085_Tp __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +00001086 return __c11_atomic_fetch_xor(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
1087}
1088
1089#endif // _LIBCPP_HAS_GCC_ATOMIC_IMP, _LIBCPP_HAS_C_ATOMIC_IMP
Dan Albert7b65ace2014-08-09 23:51:51 +00001090
Howard Hinnantdca6e712010-09-28 17:13:38 +00001091template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001092_LIBCPP_INLINE_VISIBILITY
1093_Tp kill_dependency(_Tp __y) _NOEXCEPT
Howard Hinnantdca6e712010-09-28 17:13:38 +00001094{
1095 return __y;
1096}
Howard Hinnant71be7292010-09-27 21:17:38 +00001097
Eric Fiselierbed42df2017-04-20 23:22:46 +00001098#if defined(__CLANG_ATOMIC_BOOL_LOCK_FREE)
1099# define ATOMIC_BOOL_LOCK_FREE __CLANG_ATOMIC_BOOL_LOCK_FREE
1100# define ATOMIC_CHAR_LOCK_FREE __CLANG_ATOMIC_CHAR_LOCK_FREE
1101# define ATOMIC_CHAR16_T_LOCK_FREE __CLANG_ATOMIC_CHAR16_T_LOCK_FREE
1102# define ATOMIC_CHAR32_T_LOCK_FREE __CLANG_ATOMIC_CHAR32_T_LOCK_FREE
1103# define ATOMIC_WCHAR_T_LOCK_FREE __CLANG_ATOMIC_WCHAR_T_LOCK_FREE
1104# define ATOMIC_SHORT_LOCK_FREE __CLANG_ATOMIC_SHORT_LOCK_FREE
1105# define ATOMIC_INT_LOCK_FREE __CLANG_ATOMIC_INT_LOCK_FREE
1106# define ATOMIC_LONG_LOCK_FREE __CLANG_ATOMIC_LONG_LOCK_FREE
1107# define ATOMIC_LLONG_LOCK_FREE __CLANG_ATOMIC_LLONG_LOCK_FREE
1108# define ATOMIC_POINTER_LOCK_FREE __CLANG_ATOMIC_POINTER_LOCK_FREE
Davide Italiano011f80a2019-03-05 18:40:49 +00001109#elif defined(__GCC_ATOMIC_BOOL_LOCK_FREE)
Eric Fiselierbed42df2017-04-20 23:22:46 +00001110# define ATOMIC_BOOL_LOCK_FREE __GCC_ATOMIC_BOOL_LOCK_FREE
1111# define ATOMIC_CHAR_LOCK_FREE __GCC_ATOMIC_CHAR_LOCK_FREE
1112# define ATOMIC_CHAR16_T_LOCK_FREE __GCC_ATOMIC_CHAR16_T_LOCK_FREE
1113# define ATOMIC_CHAR32_T_LOCK_FREE __GCC_ATOMIC_CHAR32_T_LOCK_FREE
1114# define ATOMIC_WCHAR_T_LOCK_FREE __GCC_ATOMIC_WCHAR_T_LOCK_FREE
1115# define ATOMIC_SHORT_LOCK_FREE __GCC_ATOMIC_SHORT_LOCK_FREE
1116# define ATOMIC_INT_LOCK_FREE __GCC_ATOMIC_INT_LOCK_FREE
1117# define ATOMIC_LONG_LOCK_FREE __GCC_ATOMIC_LONG_LOCK_FREE
1118# define ATOMIC_LLONG_LOCK_FREE __GCC_ATOMIC_LLONG_LOCK_FREE
1119# define ATOMIC_POINTER_LOCK_FREE __GCC_ATOMIC_POINTER_LOCK_FREE
1120#endif
JF Bastienfdb42c22016-03-25 15:48:21 +00001121
Davide Italiano011f80a2019-03-05 18:40:49 +00001122#ifdef _LIBCPP_ATOMIC_ONLY_USE_BUILTINS
1123
1124template<typename _Tp>
1125struct __cxx_atomic_lock_impl {
1126
1127 _LIBCPP_INLINE_VISIBILITY
1128 __cxx_atomic_lock_impl() _NOEXCEPT
1129 : __a_value(), __a_lock(0) {}
1130 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR explicit
1131 __cxx_atomic_lock_impl(_Tp value) _NOEXCEPT
1132 : __a_value(value), __a_lock(0) {}
1133
1134 _Tp __a_value;
1135 mutable __cxx_atomic_base_impl<_LIBCPP_ATOMIC_FLAG_TYPE> __a_lock;
1136
1137 _LIBCPP_INLINE_VISIBILITY void __lock() const volatile {
1138 while(1 == __cxx_atomic_exchange(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(true), memory_order_acquire))
1139 /*spin*/;
1140 }
1141 _LIBCPP_INLINE_VISIBILITY void __lock() const {
1142 while(1 == __cxx_atomic_exchange(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(true), memory_order_acquire))
1143 /*spin*/;
1144 }
1145 _LIBCPP_INLINE_VISIBILITY void __unlock() const volatile {
1146 __cxx_atomic_store(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(false), memory_order_release);
1147 }
1148 _LIBCPP_INLINE_VISIBILITY void __unlock() const {
1149 __cxx_atomic_store(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(false), memory_order_release);
1150 }
1151 _LIBCPP_INLINE_VISIBILITY _Tp __read() const volatile {
1152 __lock();
1153 _Tp __old;
1154 __cxx_atomic_assign_volatile(__old, __a_value);
1155 __unlock();
1156 return __old;
1157 }
1158 _LIBCPP_INLINE_VISIBILITY _Tp __read() const {
1159 __lock();
1160 _Tp __old = __a_value;
1161 __unlock();
1162 return __old;
1163 }
1164};
1165
1166template <typename _Tp>
1167_LIBCPP_INLINE_VISIBILITY
1168void __cxx_atomic_init(volatile __cxx_atomic_lock_impl<_Tp>* __a, _Tp __val) {
1169 __cxx_atomic_assign_volatile(__a->__a_value, __val);
1170}
1171template <typename _Tp>
1172_LIBCPP_INLINE_VISIBILITY
1173void __cxx_atomic_init(__cxx_atomic_lock_impl<_Tp>* __a, _Tp __val) {
1174 __a->__a_value = __val;
1175}
1176
1177template <typename _Tp>
1178_LIBCPP_INLINE_VISIBILITY
1179void __cxx_atomic_store(volatile __cxx_atomic_lock_impl<_Tp>* __a, _Tp __val, memory_order) {
1180 __a->__lock();
1181 __cxx_atomic_assign_volatile(__a->__a_value, __val);
1182 __a->__unlock();
1183}
1184template <typename _Tp>
1185_LIBCPP_INLINE_VISIBILITY
1186void __cxx_atomic_store(__cxx_atomic_lock_impl<_Tp>* __a, _Tp __val, memory_order) {
1187 __a->__lock();
1188 __a->__a_value = __val;
1189 __a->__unlock();
1190}
1191
1192template <typename _Tp>
1193_LIBCPP_INLINE_VISIBILITY
1194_Tp __cxx_atomic_load(const volatile __cxx_atomic_lock_impl<_Tp>* __a, memory_order) {
1195 return __a->__read();
1196}
1197template <typename _Tp>
1198_LIBCPP_INLINE_VISIBILITY
1199_Tp __cxx_atomic_load(const __cxx_atomic_lock_impl<_Tp>* __a, memory_order) {
1200 return __a->__read();
1201}
1202
1203template <typename _Tp>
1204_LIBCPP_INLINE_VISIBILITY
1205_Tp __cxx_atomic_exchange(volatile __cxx_atomic_lock_impl<_Tp>* __a, _Tp __value, memory_order) {
1206 __a->__lock();
1207 _Tp __old;
1208 __cxx_atomic_assign_volatile(__old, __a->__a_value);
1209 __cxx_atomic_assign_volatile(__a->__a_value, __value);
1210 __a->__unlock();
1211 return __old;
1212}
1213template <typename _Tp>
1214_LIBCPP_INLINE_VISIBILITY
1215_Tp __cxx_atomic_exchange(__cxx_atomic_lock_impl<_Tp>* __a, _Tp __value, memory_order) {
1216 __a->__lock();
1217 _Tp __old = __a->__a_value;
1218 __a->__a_value = __value;
1219 __a->__unlock();
1220 return __old;
1221}
1222
1223template <typename _Tp>
1224_LIBCPP_INLINE_VISIBILITY
1225bool __cxx_atomic_compare_exchange_strong(volatile __cxx_atomic_lock_impl<_Tp>* __a,
1226 _Tp* __expected, _Tp __value, memory_order, memory_order) {
1227 __a->__lock();
Olivier Giroux161e6e82020-02-18 09:58:34 -05001228 _Tp __temp;
1229 __cxx_atomic_assign_volatile(__temp, __a->__a_value);
1230 bool __ret = __temp == *__expected;
Davide Italiano011f80a2019-03-05 18:40:49 +00001231 if(__ret)
1232 __cxx_atomic_assign_volatile(__a->__a_value, __value);
1233 else
1234 __cxx_atomic_assign_volatile(*__expected, __a->__a_value);
1235 __a->__unlock();
1236 return __ret;
1237}
1238template <typename _Tp>
1239_LIBCPP_INLINE_VISIBILITY
1240bool __cxx_atomic_compare_exchange_strong(__cxx_atomic_lock_impl<_Tp>* __a,
1241 _Tp* __expected, _Tp __value, memory_order, memory_order) {
1242 __a->__lock();
1243 bool __ret = __a->__a_value == *__expected;
1244 if(__ret)
1245 __a->__a_value = __value;
1246 else
1247 *__expected = __a->__a_value;
1248 __a->__unlock();
1249 return __ret;
1250}
1251
1252template <typename _Tp>
1253_LIBCPP_INLINE_VISIBILITY
1254bool __cxx_atomic_compare_exchange_weak(volatile __cxx_atomic_lock_impl<_Tp>* __a,
1255 _Tp* __expected, _Tp __value, memory_order, memory_order) {
1256 __a->__lock();
Olivier Giroux161e6e82020-02-18 09:58:34 -05001257 _Tp __temp;
1258 __cxx_atomic_assign_volatile(__temp, __a->__a_value);
1259 bool __ret = __temp == *__expected;
Davide Italiano011f80a2019-03-05 18:40:49 +00001260 if(__ret)
1261 __cxx_atomic_assign_volatile(__a->__a_value, __value);
1262 else
1263 __cxx_atomic_assign_volatile(*__expected, __a->__a_value);
1264 __a->__unlock();
1265 return __ret;
1266}
1267template <typename _Tp>
1268_LIBCPP_INLINE_VISIBILITY
1269bool __cxx_atomic_compare_exchange_weak(__cxx_atomic_lock_impl<_Tp>* __a,
1270 _Tp* __expected, _Tp __value, memory_order, memory_order) {
1271 __a->__lock();
1272 bool __ret = __a->__a_value == *__expected;
1273 if(__ret)
1274 __a->__a_value = __value;
1275 else
1276 *__expected = __a->__a_value;
1277 __a->__unlock();
1278 return __ret;
1279}
1280
1281template <typename _Tp, typename _Td>
1282_LIBCPP_INLINE_VISIBILITY
1283_Tp __cxx_atomic_fetch_add(volatile __cxx_atomic_lock_impl<_Tp>* __a,
1284 _Td __delta, memory_order) {
1285 __a->__lock();
1286 _Tp __old;
1287 __cxx_atomic_assign_volatile(__old, __a->__a_value);
1288 __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old + __delta));
1289 __a->__unlock();
1290 return __old;
1291}
1292template <typename _Tp, typename _Td>
1293_LIBCPP_INLINE_VISIBILITY
1294_Tp __cxx_atomic_fetch_add(__cxx_atomic_lock_impl<_Tp>* __a,
1295 _Td __delta, memory_order) {
1296 __a->__lock();
1297 _Tp __old = __a->__a_value;
1298 __a->__a_value += __delta;
1299 __a->__unlock();
1300 return __old;
1301}
1302
1303template <typename _Tp, typename _Td>
1304_LIBCPP_INLINE_VISIBILITY
1305_Tp* __cxx_atomic_fetch_add(volatile __cxx_atomic_lock_impl<_Tp*>* __a,
1306 ptrdiff_t __delta, memory_order) {
1307 __a->__lock();
1308 _Tp* __old;
1309 __cxx_atomic_assign_volatile(__old, __a->__a_value);
1310 __cxx_atomic_assign_volatile(__a->__a_value, __old + __delta);
1311 __a->__unlock();
1312 return __old;
1313}
1314template <typename _Tp, typename _Td>
1315_LIBCPP_INLINE_VISIBILITY
1316_Tp* __cxx_atomic_fetch_add(__cxx_atomic_lock_impl<_Tp*>* __a,
1317 ptrdiff_t __delta, memory_order) {
1318 __a->__lock();
1319 _Tp* __old = __a->__a_value;
1320 __a->__a_value += __delta;
1321 __a->__unlock();
1322 return __old;
1323}
1324
1325template <typename _Tp, typename _Td>
1326_LIBCPP_INLINE_VISIBILITY
1327_Tp __cxx_atomic_fetch_sub(volatile __cxx_atomic_lock_impl<_Tp>* __a,
1328 _Td __delta, memory_order) {
1329 __a->__lock();
1330 _Tp __old;
1331 __cxx_atomic_assign_volatile(__old, __a->__a_value);
1332 __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old - __delta));
1333 __a->__unlock();
1334 return __old;
1335}
1336template <typename _Tp, typename _Td>
1337_LIBCPP_INLINE_VISIBILITY
1338_Tp __cxx_atomic_fetch_sub(__cxx_atomic_lock_impl<_Tp>* __a,
1339 _Td __delta, memory_order) {
1340 __a->__lock();
1341 _Tp __old = __a->__a_value;
1342 __a->__a_value -= __delta;
1343 __a->__unlock();
1344 return __old;
1345}
1346
1347template <typename _Tp>
1348_LIBCPP_INLINE_VISIBILITY
1349_Tp __cxx_atomic_fetch_and(volatile __cxx_atomic_lock_impl<_Tp>* __a,
1350 _Tp __pattern, memory_order) {
1351 __a->__lock();
1352 _Tp __old;
1353 __cxx_atomic_assign_volatile(__old, __a->__a_value);
1354 __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old & __pattern));
1355 __a->__unlock();
1356 return __old;
1357}
1358template <typename _Tp>
1359_LIBCPP_INLINE_VISIBILITY
1360_Tp __cxx_atomic_fetch_and(__cxx_atomic_lock_impl<_Tp>* __a,
1361 _Tp __pattern, memory_order) {
1362 __a->__lock();
1363 _Tp __old = __a->__a_value;
1364 __a->__a_value &= __pattern;
1365 __a->__unlock();
1366 return __old;
1367}
1368
1369template <typename _Tp>
1370_LIBCPP_INLINE_VISIBILITY
1371_Tp __cxx_atomic_fetch_or(volatile __cxx_atomic_lock_impl<_Tp>* __a,
1372 _Tp __pattern, memory_order) {
1373 __a->__lock();
1374 _Tp __old;
1375 __cxx_atomic_assign_volatile(__old, __a->__a_value);
1376 __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old | __pattern));
1377 __a->__unlock();
1378 return __old;
1379}
1380template <typename _Tp>
1381_LIBCPP_INLINE_VISIBILITY
1382_Tp __cxx_atomic_fetch_or(__cxx_atomic_lock_impl<_Tp>* __a,
1383 _Tp __pattern, memory_order) {
1384 __a->__lock();
1385 _Tp __old = __a->__a_value;
1386 __a->__a_value |= __pattern;
1387 __a->__unlock();
1388 return __old;
1389}
1390
1391template <typename _Tp>
1392_LIBCPP_INLINE_VISIBILITY
1393_Tp __cxx_atomic_fetch_xor(volatile __cxx_atomic_lock_impl<_Tp>* __a,
1394 _Tp __pattern, memory_order) {
1395 __a->__lock();
1396 _Tp __old;
1397 __cxx_atomic_assign_volatile(__old, __a->__a_value);
1398 __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old ^ __pattern));
1399 __a->__unlock();
1400 return __old;
1401}
1402template <typename _Tp>
1403_LIBCPP_INLINE_VISIBILITY
1404_Tp __cxx_atomic_fetch_xor(__cxx_atomic_lock_impl<_Tp>* __a,
1405 _Tp __pattern, memory_order) {
1406 __a->__lock();
1407 _Tp __old = __a->__a_value;
1408 __a->__a_value ^= __pattern;
1409 __a->__unlock();
1410 return __old;
1411}
1412
1413#ifdef __cpp_lib_atomic_is_always_lock_free
1414
1415template<typename _Tp> struct __cxx_is_always_lock_free {
1416 enum { __value = __atomic_always_lock_free(sizeof(_Tp), 0) }; };
1417
1418#else
1419
1420template<typename _Tp> struct __cxx_is_always_lock_free { enum { __value = false }; };
1421// Implementations must match the C ATOMIC_*_LOCK_FREE macro values.
1422template<> struct __cxx_is_always_lock_free<bool> { enum { __value = 2 == ATOMIC_BOOL_LOCK_FREE }; };
1423template<> struct __cxx_is_always_lock_free<char> { enum { __value = 2 == ATOMIC_CHAR_LOCK_FREE }; };
1424template<> struct __cxx_is_always_lock_free<signed char> { enum { __value = 2 == ATOMIC_CHAR_LOCK_FREE }; };
1425template<> struct __cxx_is_always_lock_free<unsigned char> { enum { __value = 2 == ATOMIC_CHAR_LOCK_FREE }; };
1426template<> struct __cxx_is_always_lock_free<char16_t> { enum { __value = 2 == ATOMIC_CHAR16_T_LOCK_FREE }; };
1427template<> struct __cxx_is_always_lock_free<char32_t> { enum { __value = 2 == ATOMIC_CHAR32_T_LOCK_FREE }; };
1428template<> struct __cxx_is_always_lock_free<wchar_t> { enum { __value = 2 == ATOMIC_WCHAR_T_LOCK_FREE }; };
1429template<> struct __cxx_is_always_lock_free<short> { enum { __value = 2 == ATOMIC_SHORT_LOCK_FREE }; };
1430template<> struct __cxx_is_always_lock_free<unsigned short> { enum { __value = 2 == ATOMIC_SHORT_LOCK_FREE }; };
1431template<> struct __cxx_is_always_lock_free<int> { enum { __value = 2 == ATOMIC_INT_LOCK_FREE }; };
1432template<> struct __cxx_is_always_lock_free<unsigned int> { enum { __value = 2 == ATOMIC_INT_LOCK_FREE }; };
1433template<> struct __cxx_is_always_lock_free<long> { enum { __value = 2 == ATOMIC_LONG_LOCK_FREE }; };
1434template<> struct __cxx_is_always_lock_free<unsigned long> { enum { __value = 2 == ATOMIC_LONG_LOCK_FREE }; };
1435template<> struct __cxx_is_always_lock_free<long long> { enum { __value = 2 == ATOMIC_LLONG_LOCK_FREE }; };
1436template<> struct __cxx_is_always_lock_free<unsigned long long> { enum { __value = 2 == ATOMIC_LLONG_LOCK_FREE }; };
1437template<typename _Tp> struct __cxx_is_always_lock_free<_Tp*> { enum { __value = 2 == ATOMIC_POINTER_LOCK_FREE }; };
1438template<> struct __cxx_is_always_lock_free<std::nullptr_t> { enum { __value = 2 == ATOMIC_POINTER_LOCK_FREE }; };
1439
1440#endif //__cpp_lib_atomic_is_always_lock_free
1441
1442template <typename _Tp,
1443 typename _Base = typename conditional<__cxx_is_always_lock_free<_Tp>::__value,
1444 __cxx_atomic_base_impl<_Tp>,
1445 __cxx_atomic_lock_impl<_Tp> >::type>
1446#else
1447template <typename _Tp,
1448 typename _Base = __cxx_atomic_base_impl<_Tp> >
1449#endif //_LIBCPP_ATOMIC_ONLY_USE_BUILTINS
1450struct __cxx_atomic_impl : public _Base {
1451
1452#if _GNUC_VER >= 501
1453 static_assert(is_trivially_copyable<_Tp>::value,
1454 "std::atomic<Tp> requires that 'Tp' be a trivially copyable type");
1455#endif
1456
1457 _LIBCPP_INLINE_VISIBILITY __cxx_atomic_impl() _NOEXCEPT _LIBCPP_DEFAULT
1458 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR explicit __cxx_atomic_impl(_Tp value) _NOEXCEPT
1459 : _Base(value) {}
1460};
1461
Olivier Giroux161e6e82020-02-18 09:58:34 -05001462#ifdef __linux__
1463 using __cxx_contention_t = int32_t;
1464#else
1465 using __cxx_contention_t = int64_t;
1466#endif //__linux__
1467
1468#if _LIBCPP_STD_VER >= 11
1469
1470using __cxx_atomic_contention_t = __cxx_atomic_impl<__cxx_contention_t>;
1471
1472#ifndef _LIBCPP_HAS_NO_PLATFORM_WAIT
1473
Louis Dionne48a828b2020-02-24 10:08:41 -05001474_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_one(void const volatile*);
1475_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_all(void const volatile*);
1476_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t __libcpp_atomic_monitor(void const volatile*);
1477_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __libcpp_atomic_wait(void const volatile*, __cxx_contention_t);
Olivier Giroux161e6e82020-02-18 09:58:34 -05001478
Louis Dionne48a828b2020-02-24 10:08:41 -05001479_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_one(__cxx_atomic_contention_t const volatile*);
1480_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_all(__cxx_atomic_contention_t const volatile*);
1481_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t __libcpp_atomic_monitor(__cxx_atomic_contention_t const volatile*);
1482_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 -05001483
1484template <class _Atp, class _Fn>
Louis Dionne08cd5cb2020-02-24 11:39:48 -05001485struct __libcpp_atomic_wait_backoff_impl {
1486 _Atp* __a;
1487 _Fn __test_fn;
Louis Dionne3dde4ab2020-02-24 10:09:29 -05001488 _LIBCPP_AVAILABILITY_SYNC
Louis Dionne08cd5cb2020-02-24 11:39:48 -05001489 _LIBCPP_INLINE_VISIBILITY bool operator()(chrono::nanoseconds __elapsed) const
1490 {
Olivier Giroux161e6e82020-02-18 09:58:34 -05001491 if(__elapsed > chrono::microseconds(64))
1492 {
1493 auto const __monitor = __libcpp_atomic_monitor(__a);
1494 if(__test_fn())
1495 return true;
1496 __libcpp_atomic_wait(__a, __monitor);
1497 }
1498 else if(__elapsed > chrono::microseconds(4))
1499 __libcpp_thread_yield();
1500 else
1501 ; // poll
1502 return false;
Louis Dionne08cd5cb2020-02-24 11:39:48 -05001503 }
1504};
1505
1506template <class _Atp, class _Fn>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05001507_LIBCPP_AVAILABILITY_SYNC
Louis Dionne08cd5cb2020-02-24 11:39:48 -05001508_LIBCPP_INLINE_VISIBILITY bool __cxx_atomic_wait(_Atp* __a, _Fn && __test_fn)
1509{
1510 __libcpp_atomic_wait_backoff_impl<_Atp, typename decay<_Fn>::type> __backoff_fn = {__a, __test_fn};
1511 return __libcpp_thread_poll_with_backoff(__test_fn, __backoff_fn);
Olivier Giroux161e6e82020-02-18 09:58:34 -05001512}
1513
1514#else // _LIBCPP_HAS_NO_PLATFORM_WAIT
1515
1516template <class _Tp>
1517_LIBCPP_INLINE_VISIBILITY void __cxx_atomic_notify_all(__cxx_atomic_impl<_Tp> const volatile*) { }
1518template <class _Tp>
1519_LIBCPP_INLINE_VISIBILITY void __cxx_atomic_notify_one(__cxx_atomic_impl<_Tp> const volatile*) { }
1520template <class _Atp, class _Fn>
1521_LIBCPP_INLINE_VISIBILITY bool __cxx_atomic_wait(_Atp*, _Fn && __test_fn)
1522{
1523 return __libcpp_thread_poll_with_backoff(__test_fn, __libcpp_timed_backoff_policy());
1524}
1525
1526#endif // _LIBCPP_HAS_NO_PLATFORM_WAIT
1527
1528template <class _Atp, class _Tp>
Louis Dionne08cd5cb2020-02-24 11:39:48 -05001529struct __cxx_atomic_wait_test_fn_impl {
1530 _Atp* __a;
1531 _Tp __val;
1532 memory_order __order;
1533 _LIBCPP_INLINE_VISIBILITY bool operator()() const
1534 {
1535 return !__cxx_nonatomic_compare_equal(__cxx_atomic_load(__a, __order), __val);
1536 }
1537};
1538
1539template <class _Atp, class _Tp>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05001540_LIBCPP_AVAILABILITY_SYNC
Olivier Giroux161e6e82020-02-18 09:58:34 -05001541_LIBCPP_INLINE_VISIBILITY bool __cxx_atomic_wait(_Atp* __a, _Tp const __val, memory_order __order)
1542{
Louis Dionne08cd5cb2020-02-24 11:39:48 -05001543 __cxx_atomic_wait_test_fn_impl<_Atp, _Tp> __test_fn = {__a, __val, __order};
Olivier Giroux161e6e82020-02-18 09:58:34 -05001544 return __cxx_atomic_wait(__a, __test_fn);
1545}
1546
1547#endif //_LIBCPP_STD_VER >= 11
1548
Howard Hinnant138f5922010-12-07 20:46:14 +00001549// general atomic<T>
1550
1551template <class _Tp, bool = is_integral<_Tp>::value && !is_same<_Tp, bool>::value>
1552struct __atomic_base // false
1553{
Davide Italiano011f80a2019-03-05 18:40:49 +00001554 mutable __cxx_atomic_impl<_Tp> __a_;
Howard Hinnant138f5922010-12-07 20:46:14 +00001555
JF Bastienfdb42c22016-03-25 15:48:21 +00001556#if defined(__cpp_lib_atomic_is_always_lock_free)
1557 static _LIBCPP_CONSTEXPR bool is_always_lock_free = __atomic_always_lock_free(sizeof(__a_), 0);
1558#endif
1559
Howard Hinnant138f5922010-12-07 20:46:14 +00001560 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001561 bool is_lock_free() const volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001562 {return __cxx_atomic_is_lock_free(sizeof(_Tp));}
Howard Hinnant138f5922010-12-07 20:46:14 +00001563 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001564 bool is_lock_free() const _NOEXCEPT
Eric Fiselier3fd22c22015-06-13 00:23:07 +00001565 {return static_cast<__atomic_base const volatile*>(this)->is_lock_free();}
Howard Hinnant138f5922010-12-07 20:46:14 +00001566 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001567 void store(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001568 _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
Davide Italiano011f80a2019-03-05 18:40:49 +00001569 {__cxx_atomic_store(&__a_, __d, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001570 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001571 void store(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001572 _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
Davide Italiano011f80a2019-03-05 18:40:49 +00001573 {__cxx_atomic_store(&__a_, __d, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001574 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001575 _Tp load(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001576 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
Davide Italiano011f80a2019-03-05 18:40:49 +00001577 {return __cxx_atomic_load(&__a_, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001578 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001579 _Tp load(memory_order __m = memory_order_seq_cst) const _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001580 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
Davide Italiano011f80a2019-03-05 18:40:49 +00001581 {return __cxx_atomic_load(&__a_, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001582 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001583 operator _Tp() const volatile _NOEXCEPT {return load();}
Howard Hinnant138f5922010-12-07 20:46:14 +00001584 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001585 operator _Tp() const _NOEXCEPT {return load();}
Howard Hinnant138f5922010-12-07 20:46:14 +00001586 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001587 _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001588 {return __cxx_atomic_exchange(&__a_, __d, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001589 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001590 _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001591 {return __cxx_atomic_exchange(&__a_, __d, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001592 _LIBCPP_INLINE_VISIBILITY
1593 bool compare_exchange_weak(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001594 memory_order __s, memory_order __f) volatile _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001595 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Davide Italiano011f80a2019-03-05 18:40:49 +00001596 {return __cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001597 _LIBCPP_INLINE_VISIBILITY
1598 bool compare_exchange_weak(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001599 memory_order __s, memory_order __f) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001600 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Davide Italiano011f80a2019-03-05 18:40:49 +00001601 {return __cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001602 _LIBCPP_INLINE_VISIBILITY
1603 bool compare_exchange_strong(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001604 memory_order __s, memory_order __f) volatile _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001605 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Davide Italiano011f80a2019-03-05 18:40:49 +00001606 {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001607 _LIBCPP_INLINE_VISIBILITY
1608 bool compare_exchange_strong(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001609 memory_order __s, memory_order __f) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001610 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Davide Italiano011f80a2019-03-05 18:40:49 +00001611 {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001612 _LIBCPP_INLINE_VISIBILITY
1613 bool compare_exchange_weak(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001614 memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001615 {return __cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001616 _LIBCPP_INLINE_VISIBILITY
1617 bool compare_exchange_weak(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001618 memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001619 {return __cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001620 _LIBCPP_INLINE_VISIBILITY
1621 bool compare_exchange_strong(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001622 memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001623 {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001624 _LIBCPP_INLINE_VISIBILITY
1625 bool compare_exchange_strong(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001626 memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001627 {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001628
Louis Dionne3dde4ab2020-02-24 10:09:29 -05001629 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void wait(_Tp __v, memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
Olivier Giroux161e6e82020-02-18 09:58:34 -05001630 {__cxx_atomic_wait(&__a_, __v, __m);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05001631 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void wait(_Tp __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT
Olivier Giroux161e6e82020-02-18 09:58:34 -05001632 {__cxx_atomic_wait(&__a_, __v, __m);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05001633 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_one() volatile _NOEXCEPT
Olivier Giroux161e6e82020-02-18 09:58:34 -05001634 {__cxx_atomic_notify_one(&__a_);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05001635 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_one() _NOEXCEPT
Olivier Giroux161e6e82020-02-18 09:58:34 -05001636 {__cxx_atomic_notify_one(&__a_);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05001637 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_all() volatile _NOEXCEPT
Olivier Giroux161e6e82020-02-18 09:58:34 -05001638 {__cxx_atomic_notify_all(&__a_);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05001639 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_all() _NOEXCEPT
Olivier Giroux161e6e82020-02-18 09:58:34 -05001640 {__cxx_atomic_notify_all(&__a_);}
1641
Howard Hinnant138f5922010-12-07 20:46:14 +00001642 _LIBCPP_INLINE_VISIBILITY
Davide Italiano011f80a2019-03-05 18:40:49 +00001643 __atomic_base() _NOEXCEPT _LIBCPP_DEFAULT
Howard Hinnant3d284222013-05-02 20:18:43 +00001644
Davide Italiano011f80a2019-03-05 18:40:49 +00001645 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
1646 __atomic_base(_Tp __d) _NOEXCEPT : __a_(__d) {}
1647
Eric Fiselier2d8515f2017-01-06 20:58:25 +00001648#ifndef _LIBCPP_CXX03_LANG
Howard Hinnant138f5922010-12-07 20:46:14 +00001649 __atomic_base(const __atomic_base&) = delete;
1650 __atomic_base& operator=(const __atomic_base&) = delete;
1651 __atomic_base& operator=(const __atomic_base&) volatile = delete;
Eric Fiselier2d8515f2017-01-06 20:58:25 +00001652#else
Howard Hinnant6ac60f82010-12-08 17:20:28 +00001653private:
Olivier Giroux161e6e82020-02-18 09:58:34 -05001654 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant6ac60f82010-12-08 17:20:28 +00001655 __atomic_base(const __atomic_base&);
Olivier Giroux161e6e82020-02-18 09:58:34 -05001656 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant6ac60f82010-12-08 17:20:28 +00001657 __atomic_base& operator=(const __atomic_base&);
Olivier Giroux161e6e82020-02-18 09:58:34 -05001658 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant6ac60f82010-12-08 17:20:28 +00001659 __atomic_base& operator=(const __atomic_base&) volatile;
Eric Fiselier2d8515f2017-01-06 20:58:25 +00001660#endif
Howard Hinnant138f5922010-12-07 20:46:14 +00001661};
1662
JF Bastienfdb42c22016-03-25 15:48:21 +00001663#if defined(__cpp_lib_atomic_is_always_lock_free)
1664template <class _Tp, bool __b>
1665_LIBCPP_CONSTEXPR bool __atomic_base<_Tp, __b>::is_always_lock_free;
1666#endif
1667
Howard Hinnant138f5922010-12-07 20:46:14 +00001668// atomic<Integral>
1669
1670template <class _Tp>
1671struct __atomic_base<_Tp, true>
1672 : public __atomic_base<_Tp, false>
1673{
1674 typedef __atomic_base<_Tp, false> __base;
1675 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3d284222013-05-02 20:18:43 +00001676 __atomic_base() _NOEXCEPT _LIBCPP_DEFAULT
Howard Hinnant138f5922010-12-07 20:46:14 +00001677 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001678 _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __base(__d) {}
Howard Hinnant138f5922010-12-07 20:46:14 +00001679
1680 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001681 _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001682 {return __cxx_atomic_fetch_add(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001683 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001684 _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001685 {return __cxx_atomic_fetch_add(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001686 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001687 _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001688 {return __cxx_atomic_fetch_sub(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001689 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001690 _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001691 {return __cxx_atomic_fetch_sub(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001692 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001693 _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001694 {return __cxx_atomic_fetch_and(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001695 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001696 _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001697 {return __cxx_atomic_fetch_and(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001698 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001699 _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001700 {return __cxx_atomic_fetch_or(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001701 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001702 _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001703 {return __cxx_atomic_fetch_or(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001704 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001705 _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001706 {return __cxx_atomic_fetch_xor(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001707 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001708 _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001709 {return __cxx_atomic_fetch_xor(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001710
1711 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001712 _Tp operator++(int) volatile _NOEXCEPT {return fetch_add(_Tp(1));}
Howard Hinnant138f5922010-12-07 20:46:14 +00001713 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001714 _Tp operator++(int) _NOEXCEPT {return fetch_add(_Tp(1));}
Howard Hinnant138f5922010-12-07 20:46:14 +00001715 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001716 _Tp operator--(int) volatile _NOEXCEPT {return fetch_sub(_Tp(1));}
Howard Hinnant138f5922010-12-07 20:46:14 +00001717 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001718 _Tp operator--(int) _NOEXCEPT {return fetch_sub(_Tp(1));}
Howard Hinnant138f5922010-12-07 20:46:14 +00001719 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001720 _Tp operator++() volatile _NOEXCEPT {return fetch_add(_Tp(1)) + _Tp(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001721 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001722 _Tp operator++() _NOEXCEPT {return fetch_add(_Tp(1)) + _Tp(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001723 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001724 _Tp operator--() volatile _NOEXCEPT {return fetch_sub(_Tp(1)) - _Tp(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001725 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001726 _Tp operator--() _NOEXCEPT {return fetch_sub(_Tp(1)) - _Tp(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001727 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001728 _Tp operator+=(_Tp __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001729 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001730 _Tp operator+=(_Tp __op) _NOEXCEPT {return fetch_add(__op) + __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001731 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001732 _Tp operator-=(_Tp __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001733 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001734 _Tp operator-=(_Tp __op) _NOEXCEPT {return fetch_sub(__op) - __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001735 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001736 _Tp operator&=(_Tp __op) volatile _NOEXCEPT {return fetch_and(__op) & __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001737 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001738 _Tp operator&=(_Tp __op) _NOEXCEPT {return fetch_and(__op) & __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001739 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001740 _Tp operator|=(_Tp __op) volatile _NOEXCEPT {return fetch_or(__op) | __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001741 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001742 _Tp operator|=(_Tp __op) _NOEXCEPT {return fetch_or(__op) | __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001743 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001744 _Tp operator^=(_Tp __op) volatile _NOEXCEPT {return fetch_xor(__op) ^ __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001745 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001746 _Tp operator^=(_Tp __op) _NOEXCEPT {return fetch_xor(__op) ^ __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001747};
1748
1749// atomic<T>
1750
1751template <class _Tp>
1752struct atomic
1753 : public __atomic_base<_Tp>
1754{
1755 typedef __atomic_base<_Tp> __base;
Olivier Giroux161e6e82020-02-18 09:58:34 -05001756 typedef _Tp value_type;
Howard Hinnant138f5922010-12-07 20:46:14 +00001757 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3d284222013-05-02 20:18:43 +00001758 atomic() _NOEXCEPT _LIBCPP_DEFAULT
Howard Hinnant138f5922010-12-07 20:46:14 +00001759 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001760 _LIBCPP_CONSTEXPR atomic(_Tp __d) _NOEXCEPT : __base(__d) {}
Howard Hinnant96e4cd62010-12-07 23:24:41 +00001761
1762 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001763 _Tp operator=(_Tp __d) volatile _NOEXCEPT
Howard Hinnant96e4cd62010-12-07 23:24:41 +00001764 {__base::store(__d); return __d;}
1765 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001766 _Tp operator=(_Tp __d) _NOEXCEPT
Howard Hinnant96e4cd62010-12-07 23:24:41 +00001767 {__base::store(__d); return __d;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001768};
1769
1770// atomic<T*>
1771
1772template <class _Tp>
1773struct atomic<_Tp*>
1774 : public __atomic_base<_Tp*>
1775{
Howard Hinnant96e4cd62010-12-07 23:24:41 +00001776 typedef __atomic_base<_Tp*> __base;
Olivier Giroux161e6e82020-02-18 09:58:34 -05001777 typedef _Tp* value_type;
Howard Hinnant138f5922010-12-07 20:46:14 +00001778 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3d284222013-05-02 20:18:43 +00001779 atomic() _NOEXCEPT _LIBCPP_DEFAULT
Howard Hinnant138f5922010-12-07 20:46:14 +00001780 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001781 _LIBCPP_CONSTEXPR atomic(_Tp* __d) _NOEXCEPT : __base(__d) {}
Howard Hinnant138f5922010-12-07 20:46:14 +00001782
1783 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001784 _Tp* operator=(_Tp* __d) volatile _NOEXCEPT
Howard Hinnant96e4cd62010-12-07 23:24:41 +00001785 {__base::store(__d); return __d;}
1786 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001787 _Tp* operator=(_Tp* __d) _NOEXCEPT
Howard Hinnant96e4cd62010-12-07 23:24:41 +00001788 {__base::store(__d); return __d;}
1789
1790 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00001791 _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst)
Howard Hinnanteee2c142012-04-11 20:14:21 +00001792 volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001793 {return __cxx_atomic_fetch_add(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001794 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001795 _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001796 {return __cxx_atomic_fetch_add(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001797 _LIBCPP_INLINE_VISIBILITY
1798 _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst)
Howard Hinnanteee2c142012-04-11 20:14:21 +00001799 volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001800 {return __cxx_atomic_fetch_sub(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001801 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001802 _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001803 {return __cxx_atomic_fetch_sub(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001804
1805 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001806 _Tp* operator++(int) volatile _NOEXCEPT {return fetch_add(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001807 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001808 _Tp* operator++(int) _NOEXCEPT {return fetch_add(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001809 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001810 _Tp* operator--(int) volatile _NOEXCEPT {return fetch_sub(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001811 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001812 _Tp* operator--(int) _NOEXCEPT {return fetch_sub(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001813 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001814 _Tp* operator++() volatile _NOEXCEPT {return fetch_add(1) + 1;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001815 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001816 _Tp* operator++() _NOEXCEPT {return fetch_add(1) + 1;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001817 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001818 _Tp* operator--() volatile _NOEXCEPT {return fetch_sub(1) - 1;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001819 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001820 _Tp* operator--() _NOEXCEPT {return fetch_sub(1) - 1;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001821 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001822 _Tp* operator+=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001823 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001824 _Tp* operator+=(ptrdiff_t __op) _NOEXCEPT {return fetch_add(__op) + __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001825 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001826 _Tp* operator-=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001827 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001828 _Tp* operator-=(ptrdiff_t __op) _NOEXCEPT {return fetch_sub(__op) - __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001829};
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001830
1831// atomic_is_lock_free
1832
1833template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001834_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001835bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00001836atomic_is_lock_free(const volatile atomic<_Tp>* __o) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001837{
Howard Hinnant138f5922010-12-07 20:46:14 +00001838 return __o->is_lock_free();
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001839}
1840
1841template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001842_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001843bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00001844atomic_is_lock_free(const atomic<_Tp>* __o) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001845{
Howard Hinnant138f5922010-12-07 20:46:14 +00001846 return __o->is_lock_free();
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001847}
1848
1849// atomic_init
1850
1851template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001852_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001853void
Howard Hinnanteee2c142012-04-11 20:14:21 +00001854atomic_init(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001855{
Davide Italiano011f80a2019-03-05 18:40:49 +00001856 __cxx_atomic_init(&__o->__a_, __d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001857}
1858
1859template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001860_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001861void
Howard Hinnanteee2c142012-04-11 20:14:21 +00001862atomic_init(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001863{
Davide Italiano011f80a2019-03-05 18:40:49 +00001864 __cxx_atomic_init(&__o->__a_, __d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001865}
1866
1867// atomic_store
1868
1869template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001870_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001871void
Howard Hinnanteee2c142012-04-11 20:14:21 +00001872atomic_store(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001873{
Howard Hinnant138f5922010-12-07 20:46:14 +00001874 __o->store(__d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001875}
1876
1877template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001878_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001879void
Howard Hinnanteee2c142012-04-11 20:14:21 +00001880atomic_store(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001881{
Howard Hinnant138f5922010-12-07 20:46:14 +00001882 __o->store(__d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001883}
1884
1885// atomic_store_explicit
1886
1887template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001888_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001889void
Howard Hinnanteee2c142012-04-11 20:14:21 +00001890atomic_store_explicit(volatile atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001891 _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001892{
Howard Hinnant138f5922010-12-07 20:46:14 +00001893 __o->store(__d, __m);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001894}
1895
1896template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001897_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001898void
Howard Hinnanteee2c142012-04-11 20:14:21 +00001899atomic_store_explicit(atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001900 _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001901{
Howard Hinnant138f5922010-12-07 20:46:14 +00001902 __o->store(__d, __m);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001903}
1904
1905// atomic_load
1906
1907template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001908_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001909_Tp
Howard Hinnanteee2c142012-04-11 20:14:21 +00001910atomic_load(const volatile atomic<_Tp>* __o) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001911{
Howard Hinnant138f5922010-12-07 20:46:14 +00001912 return __o->load();
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001913}
1914
1915template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001916_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001917_Tp
Howard Hinnanteee2c142012-04-11 20:14:21 +00001918atomic_load(const atomic<_Tp>* __o) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001919{
Howard Hinnant138f5922010-12-07 20:46:14 +00001920 return __o->load();
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001921}
1922
1923// atomic_load_explicit
1924
1925template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001926_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001927_Tp
Howard Hinnanteee2c142012-04-11 20:14:21 +00001928atomic_load_explicit(const volatile atomic<_Tp>* __o, memory_order __m) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001929 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001930{
Howard Hinnant138f5922010-12-07 20:46:14 +00001931 return __o->load(__m);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001932}
1933
1934template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001935_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001936_Tp
Howard Hinnanteee2c142012-04-11 20:14:21 +00001937atomic_load_explicit(const atomic<_Tp>* __o, memory_order __m) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001938 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001939{
Howard Hinnant138f5922010-12-07 20:46:14 +00001940 return __o->load(__m);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001941}
1942
1943// atomic_exchange
1944
1945template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001946_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001947_Tp
Howard Hinnanteee2c142012-04-11 20:14:21 +00001948atomic_exchange(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001949{
Howard Hinnant138f5922010-12-07 20:46:14 +00001950 return __o->exchange(__d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001951}
1952
1953template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001954_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001955_Tp
Howard Hinnanteee2c142012-04-11 20:14:21 +00001956atomic_exchange(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001957{
Howard Hinnant138f5922010-12-07 20:46:14 +00001958 return __o->exchange(__d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001959}
1960
1961// atomic_exchange_explicit
1962
1963template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001964_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001965_Tp
Howard Hinnanteee2c142012-04-11 20:14:21 +00001966atomic_exchange_explicit(volatile atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001967{
Howard Hinnant138f5922010-12-07 20:46:14 +00001968 return __o->exchange(__d, __m);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001969}
1970
1971template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001972_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001973_Tp
Howard Hinnanteee2c142012-04-11 20:14:21 +00001974atomic_exchange_explicit(atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001975{
Howard Hinnant138f5922010-12-07 20:46:14 +00001976 return __o->exchange(__d, __m);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001977}
1978
1979// atomic_compare_exchange_weak
1980
1981template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001982_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001983bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00001984atomic_compare_exchange_weak(volatile atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001985{
Howard Hinnant138f5922010-12-07 20:46:14 +00001986 return __o->compare_exchange_weak(*__e, __d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001987}
1988
1989template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001990_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001991bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00001992atomic_compare_exchange_weak(atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001993{
Howard Hinnant138f5922010-12-07 20:46:14 +00001994 return __o->compare_exchange_weak(*__e, __d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001995}
1996
1997// atomic_compare_exchange_strong
1998
1999template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002000_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002001bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00002002atomic_compare_exchange_strong(volatile atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002003{
Howard Hinnant138f5922010-12-07 20:46:14 +00002004 return __o->compare_exchange_strong(*__e, __d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002005}
2006
2007template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002008_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002009bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00002010atomic_compare_exchange_strong(atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002011{
Howard Hinnant138f5922010-12-07 20:46:14 +00002012 return __o->compare_exchange_strong(*__e, __d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002013}
2014
2015// atomic_compare_exchange_weak_explicit
2016
2017template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002018_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002019bool
2020atomic_compare_exchange_weak_explicit(volatile atomic<_Tp>* __o, _Tp* __e,
2021 _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00002022 memory_order __s, memory_order __f) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00002023 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002024{
Howard Hinnant138f5922010-12-07 20:46:14 +00002025 return __o->compare_exchange_weak(*__e, __d, __s, __f);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002026}
2027
2028template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002029_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002030bool
2031atomic_compare_exchange_weak_explicit(atomic<_Tp>* __o, _Tp* __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00002032 memory_order __s, memory_order __f) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00002033 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002034{
Howard Hinnant138f5922010-12-07 20:46:14 +00002035 return __o->compare_exchange_weak(*__e, __d, __s, __f);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002036}
2037
2038// atomic_compare_exchange_strong_explicit
2039
2040template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002041_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002042bool
2043atomic_compare_exchange_strong_explicit(volatile atomic<_Tp>* __o,
2044 _Tp* __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00002045 memory_order __s, memory_order __f) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00002046 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002047{
Howard Hinnant138f5922010-12-07 20:46:14 +00002048 return __o->compare_exchange_strong(*__e, __d, __s, __f);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002049}
2050
2051template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002052_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002053bool
2054atomic_compare_exchange_strong_explicit(atomic<_Tp>* __o, _Tp* __e,
2055 _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00002056 memory_order __s, memory_order __f) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00002057 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002058{
Howard Hinnant138f5922010-12-07 20:46:14 +00002059 return __o->compare_exchange_strong(*__e, __d, __s, __f);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002060}
2061
Olivier Giroux161e6e82020-02-18 09:58:34 -05002062// atomic_wait
2063
2064template <class _Tp>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002065_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002066void atomic_wait(const volatile atomic<_Tp>* __o,
2067 typename atomic<_Tp>::value_type __v) _NOEXCEPT
2068{
2069 return __o->wait(__v);
2070}
2071
2072template <class _Tp>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002073_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002074void atomic_wait(const atomic<_Tp>* __o,
2075 typename atomic<_Tp>::value_type __v) _NOEXCEPT
2076{
2077 return __o->wait(__v);
2078}
2079
2080// atomic_wait_explicit
2081
2082template <class _Tp>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002083_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002084void atomic_wait_explicit(const volatile atomic<_Tp>* __o,
2085 typename atomic<_Tp>::value_type __v,
2086 memory_order __m) _NOEXCEPT
2087 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
2088{
2089 return __o->wait(__v, __m);
2090}
2091
2092template <class _Tp>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002093_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002094void atomic_wait_explicit(const atomic<_Tp>* __o,
2095 typename atomic<_Tp>::value_type __v,
2096 memory_order __m) _NOEXCEPT
2097 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
2098{
2099 return __o->wait(__v, __m);
2100}
2101
2102// atomic_notify_one
2103
2104template <class _Tp>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002105_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002106void atomic_notify_one(volatile atomic<_Tp>* __o) _NOEXCEPT
2107{
2108 __o->notify_one();
2109}
2110template <class _Tp>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002111_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002112void atomic_notify_one(atomic<_Tp>* __o) _NOEXCEPT
2113{
2114 __o->notify_one();
2115}
2116
2117// atomic_notify_one
2118
2119template <class _Tp>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002120_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002121void atomic_notify_all(volatile atomic<_Tp>* __o) _NOEXCEPT
2122{
2123 __o->notify_all();
2124}
2125template <class _Tp>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002126_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002127void atomic_notify_all(atomic<_Tp>* __o) _NOEXCEPT
2128{
2129 __o->notify_all();
2130}
2131
Howard Hinnant138f5922010-12-07 20:46:14 +00002132// atomic_fetch_add
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002133
2134template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002135_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002136typename enable_if
2137<
2138 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2139 _Tp
2140>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00002141atomic_fetch_add(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002142{
Howard Hinnant138f5922010-12-07 20:46:14 +00002143 return __o->fetch_add(__op);
2144}
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002145
Howard Hinnant138f5922010-12-07 20:46:14 +00002146template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002147_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002148typename enable_if
2149<
2150 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2151 _Tp
2152>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00002153atomic_fetch_add(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002154{
2155 return __o->fetch_add(__op);
2156}
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002157
Howard Hinnant138f5922010-12-07 20:46:14 +00002158template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002159_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002160_Tp*
Howard Hinnanteee2c142012-04-11 20:14:21 +00002161atomic_fetch_add(volatile atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002162{
2163 return __o->fetch_add(__op);
2164}
2165
2166template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002167_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002168_Tp*
Howard Hinnanteee2c142012-04-11 20:14:21 +00002169atomic_fetch_add(atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002170{
2171 return __o->fetch_add(__op);
2172}
2173
2174// atomic_fetch_add_explicit
2175
2176template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002177_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002178typename enable_if
2179<
2180 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2181 _Tp
2182>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00002183atomic_fetch_add_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002184{
2185 return __o->fetch_add(__op, __m);
2186}
2187
2188template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002189_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002190typename enable_if
2191<
2192 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2193 _Tp
2194>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00002195atomic_fetch_add_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002196{
2197 return __o->fetch_add(__op, __m);
2198}
2199
2200template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002201_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002202_Tp*
2203atomic_fetch_add_explicit(volatile atomic<_Tp*>* __o, ptrdiff_t __op,
Howard Hinnanteee2c142012-04-11 20:14:21 +00002204 memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002205{
2206 return __o->fetch_add(__op, __m);
2207}
2208
2209template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002210_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002211_Tp*
Howard Hinnanteee2c142012-04-11 20:14:21 +00002212atomic_fetch_add_explicit(atomic<_Tp*>* __o, ptrdiff_t __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002213{
2214 return __o->fetch_add(__op, __m);
2215}
2216
2217// atomic_fetch_sub
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<
2223 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2224 _Tp
2225>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00002226atomic_fetch_sub(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002227{
2228 return __o->fetch_sub(__op);
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<
2235 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2236 _Tp
2237>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00002238atomic_fetch_sub(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002239{
2240 return __o->fetch_sub(__op);
2241}
2242
2243template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002244_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002245_Tp*
Howard Hinnanteee2c142012-04-11 20:14:21 +00002246atomic_fetch_sub(volatile atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002247{
2248 return __o->fetch_sub(__op);
2249}
2250
2251template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002252_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002253_Tp*
Howard Hinnanteee2c142012-04-11 20:14:21 +00002254atomic_fetch_sub(atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002255{
2256 return __o->fetch_sub(__op);
2257}
2258
2259// atomic_fetch_sub_explicit
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<
2265 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2266 _Tp
2267>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00002268atomic_fetch_sub_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002269{
2270 return __o->fetch_sub(__op, __m);
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<
2277 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2278 _Tp
2279>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00002280atomic_fetch_sub_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002281{
2282 return __o->fetch_sub(__op, __m);
2283}
2284
2285template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002286_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002287_Tp*
2288atomic_fetch_sub_explicit(volatile atomic<_Tp*>* __o, ptrdiff_t __op,
Howard Hinnanteee2c142012-04-11 20:14:21 +00002289 memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002290{
2291 return __o->fetch_sub(__op, __m);
2292}
2293
2294template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002295_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002296_Tp*
Howard Hinnanteee2c142012-04-11 20:14:21 +00002297atomic_fetch_sub_explicit(atomic<_Tp*>* __o, ptrdiff_t __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002298{
2299 return __o->fetch_sub(__op, __m);
2300}
2301
2302// atomic_fetch_and
2303
2304template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002305_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002306typename enable_if
2307<
2308 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2309 _Tp
2310>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00002311atomic_fetch_and(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002312{
2313 return __o->fetch_and(__op);
2314}
2315
2316template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002317_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002318typename enable_if
2319<
2320 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2321 _Tp
2322>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00002323atomic_fetch_and(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002324{
2325 return __o->fetch_and(__op);
2326}
2327
2328// atomic_fetch_and_explicit
2329
2330template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002331_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002332typename enable_if
2333<
2334 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2335 _Tp
2336>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00002337atomic_fetch_and_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002338{
2339 return __o->fetch_and(__op, __m);
2340}
2341
2342template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002343_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002344typename enable_if
2345<
2346 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2347 _Tp
2348>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00002349atomic_fetch_and_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002350{
2351 return __o->fetch_and(__op, __m);
2352}
2353
2354// atomic_fetch_or
2355
2356template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002357_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002358typename enable_if
2359<
2360 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2361 _Tp
2362>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00002363atomic_fetch_or(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002364{
2365 return __o->fetch_or(__op);
2366}
2367
2368template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002369_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002370typename enable_if
2371<
2372 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2373 _Tp
2374>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00002375atomic_fetch_or(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002376{
2377 return __o->fetch_or(__op);
2378}
2379
2380// atomic_fetch_or_explicit
2381
2382template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002383_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002384typename enable_if
2385<
2386 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2387 _Tp
2388>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00002389atomic_fetch_or_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002390{
2391 return __o->fetch_or(__op, __m);
2392}
2393
2394template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002395_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002396typename enable_if
2397<
2398 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2399 _Tp
2400>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00002401atomic_fetch_or_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002402{
2403 return __o->fetch_or(__op, __m);
2404}
2405
2406// atomic_fetch_xor
2407
2408template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002409_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002410typename enable_if
2411<
2412 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2413 _Tp
2414>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00002415atomic_fetch_xor(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002416{
2417 return __o->fetch_xor(__op);
2418}
2419
2420template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002421_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002422typename enable_if
2423<
2424 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2425 _Tp
2426>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00002427atomic_fetch_xor(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002428{
2429 return __o->fetch_xor(__op);
2430}
2431
2432// atomic_fetch_xor_explicit
2433
2434template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002435_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002436typename enable_if
2437<
2438 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2439 _Tp
2440>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00002441atomic_fetch_xor_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002442{
2443 return __o->fetch_xor(__op, __m);
2444}
2445
2446template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002447_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002448typename enable_if
2449<
2450 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2451 _Tp
2452>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00002453atomic_fetch_xor_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002454{
2455 return __o->fetch_xor(__op, __m);
2456}
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002457
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002458// flag type and operations
2459
2460typedef struct atomic_flag
2461{
Davide Italiano011f80a2019-03-05 18:40:49 +00002462 __cxx_atomic_impl<_LIBCPP_ATOMIC_FLAG_TYPE> __a_;
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002463
2464 _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002465 bool test(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
2466 {return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m);}
2467 _LIBCPP_INLINE_VISIBILITY
2468 bool test(memory_order __m = memory_order_seq_cst) const _NOEXCEPT
2469 {return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m);}
2470
2471 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00002472 bool test_and_set(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00002473 {return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);}
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002474 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00002475 bool test_and_set(memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00002476 {return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);}
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002477 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00002478 void clear(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00002479 {__cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);}
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002480 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00002481 void clear(memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00002482 {__cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);}
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002483
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002484 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002485 void wait(bool __v, memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
2486 {__cxx_atomic_wait(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002487 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002488 void wait(bool __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT
2489 {__cxx_atomic_wait(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002490 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002491 void notify_one() volatile _NOEXCEPT
2492 {__cxx_atomic_notify_one(&__a_);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002493 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002494 void notify_one() _NOEXCEPT
2495 {__cxx_atomic_notify_one(&__a_);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002496 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002497 void notify_all() volatile _NOEXCEPT
2498 {__cxx_atomic_notify_all(&__a_);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002499 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002500 void notify_all() _NOEXCEPT
2501 {__cxx_atomic_notify_all(&__a_);}
2502
2503 _LIBCPP_INLINE_VISIBILITY
Davide Italiano011f80a2019-03-05 18:40:49 +00002504 atomic_flag() _NOEXCEPT _LIBCPP_DEFAULT
Howard Hinnant3d284222013-05-02 20:18:43 +00002505
Marshall Clowcf990752018-04-25 14:27:29 +00002506 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
Eric Fiselierfec26a92016-05-03 02:12:26 +00002507 atomic_flag(bool __b) _NOEXCEPT : __a_(__b) {} // EXTENSION
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002508
Eric Fiselier2d8515f2017-01-06 20:58:25 +00002509#ifndef _LIBCPP_CXX03_LANG
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002510 atomic_flag(const atomic_flag&) = delete;
2511 atomic_flag& operator=(const atomic_flag&) = delete;
2512 atomic_flag& operator=(const atomic_flag&) volatile = delete;
Eric Fiselier2d8515f2017-01-06 20:58:25 +00002513#else
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002514private:
Olivier Giroux161e6e82020-02-18 09:58:34 -05002515 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002516 atomic_flag(const atomic_flag&);
Olivier Giroux161e6e82020-02-18 09:58:34 -05002517 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002518 atomic_flag& operator=(const atomic_flag&);
Olivier Giroux161e6e82020-02-18 09:58:34 -05002519 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002520 atomic_flag& operator=(const atomic_flag&) volatile;
Eric Fiselier2d8515f2017-01-06 20:58:25 +00002521#endif
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002522} atomic_flag;
2523
Olivier Giroux161e6e82020-02-18 09:58:34 -05002524
2525inline _LIBCPP_INLINE_VISIBILITY
2526bool
2527atomic_flag_test(const volatile atomic_flag* __o) _NOEXCEPT
2528{
2529 return __o->test();
2530}
2531
2532inline _LIBCPP_INLINE_VISIBILITY
2533bool
2534atomic_flag_test(const atomic_flag* __o) _NOEXCEPT
2535{
2536 return __o->test();
2537}
2538
2539inline _LIBCPP_INLINE_VISIBILITY
2540bool
2541atomic_flag_test_explicit(const volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
2542{
2543 return __o->test(__m);
2544}
2545
2546inline _LIBCPP_INLINE_VISIBILITY
2547bool
2548atomic_flag_test_explicit(const atomic_flag* __o, memory_order __m) _NOEXCEPT
2549{
2550 return __o->test(__m);
2551}
2552
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002553inline _LIBCPP_INLINE_VISIBILITY
2554bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00002555atomic_flag_test_and_set(volatile atomic_flag* __o) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002556{
2557 return __o->test_and_set();
2558}
2559
2560inline _LIBCPP_INLINE_VISIBILITY
2561bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00002562atomic_flag_test_and_set(atomic_flag* __o) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002563{
2564 return __o->test_and_set();
2565}
2566
2567inline _LIBCPP_INLINE_VISIBILITY
2568bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00002569atomic_flag_test_and_set_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002570{
2571 return __o->test_and_set(__m);
2572}
2573
2574inline _LIBCPP_INLINE_VISIBILITY
2575bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00002576atomic_flag_test_and_set_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002577{
2578 return __o->test_and_set(__m);
2579}
2580
2581inline _LIBCPP_INLINE_VISIBILITY
2582void
Howard Hinnanteee2c142012-04-11 20:14:21 +00002583atomic_flag_clear(volatile atomic_flag* __o) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002584{
2585 __o->clear();
2586}
2587
2588inline _LIBCPP_INLINE_VISIBILITY
2589void
Howard Hinnanteee2c142012-04-11 20:14:21 +00002590atomic_flag_clear(atomic_flag* __o) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002591{
2592 __o->clear();
2593}
2594
2595inline _LIBCPP_INLINE_VISIBILITY
2596void
Howard Hinnanteee2c142012-04-11 20:14:21 +00002597atomic_flag_clear_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002598{
2599 __o->clear(__m);
2600}
2601
2602inline _LIBCPP_INLINE_VISIBILITY
2603void
Howard Hinnanteee2c142012-04-11 20:14:21 +00002604atomic_flag_clear_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002605{
2606 __o->clear(__m);
2607}
2608
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002609inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
Olivier Giroux161e6e82020-02-18 09:58:34 -05002610void
2611atomic_flag_wait(const volatile atomic_flag* __o, bool __v) _NOEXCEPT
2612{
2613 __o->wait(__v);
2614}
2615
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002616inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
Olivier Giroux161e6e82020-02-18 09:58:34 -05002617void
2618atomic_flag_wait(const atomic_flag* __o, bool __v) _NOEXCEPT
2619{
2620 __o->wait(__v);
2621}
2622
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002623inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
Olivier Giroux161e6e82020-02-18 09:58:34 -05002624void
2625atomic_flag_wait_explicit(const volatile atomic_flag* __o,
2626 bool __v, memory_order __m) _NOEXCEPT
2627{
2628 __o->wait(__v, __m);
2629}
2630
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002631inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
Olivier Giroux161e6e82020-02-18 09:58:34 -05002632void
2633atomic_flag_wait_explicit(const atomic_flag* __o,
2634 bool __v, memory_order __m) _NOEXCEPT
2635{
2636 __o->wait(__v, __m);
2637}
2638
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002639inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
Olivier Giroux161e6e82020-02-18 09:58:34 -05002640void
2641atomic_flag_notify_one(volatile atomic_flag* __o) _NOEXCEPT
2642{
2643 __o->notify_one();
2644}
2645
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002646inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
Olivier Giroux161e6e82020-02-18 09:58:34 -05002647void
2648atomic_flag_notify_one(atomic_flag* __o) _NOEXCEPT
2649{
2650 __o->notify_one();
2651}
2652
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002653inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
Olivier Giroux161e6e82020-02-18 09:58:34 -05002654void
2655atomic_flag_notify_all(volatile atomic_flag* __o) _NOEXCEPT
2656{
2657 __o->notify_all();
2658}
2659
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002660inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
Olivier Giroux161e6e82020-02-18 09:58:34 -05002661void
2662atomic_flag_notify_all(atomic_flag* __o) _NOEXCEPT
2663{
2664 __o->notify_all();
2665}
2666
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002667// fences
2668
2669inline _LIBCPP_INLINE_VISIBILITY
2670void
Howard Hinnanteee2c142012-04-11 20:14:21 +00002671atomic_thread_fence(memory_order __m) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002672{
Davide Italiano011f80a2019-03-05 18:40:49 +00002673 __cxx_atomic_thread_fence(__m);
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002674}
2675
2676inline _LIBCPP_INLINE_VISIBILITY
2677void
Howard Hinnanteee2c142012-04-11 20:14:21 +00002678atomic_signal_fence(memory_order __m) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002679{
Davide Italiano011f80a2019-03-05 18:40:49 +00002680 __cxx_atomic_signal_fence(__m);
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002681}
2682
Howard Hinnant96e4cd62010-12-07 23:24:41 +00002683// Atomics for standard typedef types
2684
Howard Hinnantf0af8d92013-01-04 18:58:50 +00002685typedef atomic<bool> atomic_bool;
Howard Hinnant96e4cd62010-12-07 23:24:41 +00002686typedef atomic<char> atomic_char;
2687typedef atomic<signed char> atomic_schar;
2688typedef atomic<unsigned char> atomic_uchar;
2689typedef atomic<short> atomic_short;
2690typedef atomic<unsigned short> atomic_ushort;
2691typedef atomic<int> atomic_int;
2692typedef atomic<unsigned int> atomic_uint;
2693typedef atomic<long> atomic_long;
2694typedef atomic<unsigned long> atomic_ulong;
2695typedef atomic<long long> atomic_llong;
2696typedef atomic<unsigned long long> atomic_ullong;
2697typedef atomic<char16_t> atomic_char16_t;
2698typedef atomic<char32_t> atomic_char32_t;
2699typedef atomic<wchar_t> atomic_wchar_t;
2700
2701typedef atomic<int_least8_t> atomic_int_least8_t;
2702typedef atomic<uint_least8_t> atomic_uint_least8_t;
2703typedef atomic<int_least16_t> atomic_int_least16_t;
2704typedef atomic<uint_least16_t> atomic_uint_least16_t;
2705typedef atomic<int_least32_t> atomic_int_least32_t;
2706typedef atomic<uint_least32_t> atomic_uint_least32_t;
2707typedef atomic<int_least64_t> atomic_int_least64_t;
2708typedef atomic<uint_least64_t> atomic_uint_least64_t;
2709
2710typedef atomic<int_fast8_t> atomic_int_fast8_t;
2711typedef atomic<uint_fast8_t> atomic_uint_fast8_t;
2712typedef atomic<int_fast16_t> atomic_int_fast16_t;
2713typedef atomic<uint_fast16_t> atomic_uint_fast16_t;
2714typedef atomic<int_fast32_t> atomic_int_fast32_t;
2715typedef atomic<uint_fast32_t> atomic_uint_fast32_t;
2716typedef atomic<int_fast64_t> atomic_int_fast64_t;
2717typedef atomic<uint_fast64_t> atomic_uint_fast64_t;
2718
Marshall Clowf710afc2016-06-30 15:28:38 +00002719typedef atomic< int8_t> atomic_int8_t;
2720typedef atomic<uint8_t> atomic_uint8_t;
2721typedef atomic< int16_t> atomic_int16_t;
2722typedef atomic<uint16_t> atomic_uint16_t;
2723typedef atomic< int32_t> atomic_int32_t;
2724typedef atomic<uint32_t> atomic_uint32_t;
2725typedef atomic< int64_t> atomic_int64_t;
2726typedef atomic<uint64_t> atomic_uint64_t;
2727
Howard Hinnant96e4cd62010-12-07 23:24:41 +00002728typedef atomic<intptr_t> atomic_intptr_t;
2729typedef atomic<uintptr_t> atomic_uintptr_t;
2730typedef atomic<size_t> atomic_size_t;
2731typedef atomic<ptrdiff_t> atomic_ptrdiff_t;
2732typedef atomic<intmax_t> atomic_intmax_t;
2733typedef atomic<uintmax_t> atomic_uintmax_t;
2734
Olivier Giroux161e6e82020-02-18 09:58:34 -05002735// atomic_*_lock_free : prefer the contention type most highly, then the largest lock-free type
2736
2737#ifdef __cpp_lib_atomic_is_always_lock_free
2738# define _LIBCPP_CONTENTION_LOCK_FREE __atomic_always_lock_free(sizeof(__cxx_contention_t), 0)
2739#else
2740# define _LIBCPP_CONTENTION_LOCK_FREE false
2741#endif
2742
2743#if ATOMIC_LLONG_LOCK_FREE == 2
2744typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, long long>::type __libcpp_signed_lock_free;
2745typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned long long>::type __libcpp_unsigned_lock_free;
2746#elif ATOMIC_INT_LOCK_FREE == 2
2747typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, int>::type __libcpp_signed_lock_free;
2748typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned int>::type __libcpp_unsigned_lock_free;
2749#elif ATOMIC_SHORT_LOCK_FREE == 2
2750typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, short>::type __libcpp_signed_lock_free;
2751typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned short>::type __libcpp_unsigned_lock_free;
2752#elif ATOMIC_CHAR_LOCK_FREE == 2
2753typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, char>::type __libcpp_signed_lock_free;
2754typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned char>::type __libcpp_unsigned_lock_free;
2755#else
2756 // No signed/unsigned lock-free types
2757#endif
2758
2759typedef atomic<__libcpp_signed_lock_free> atomic_signed_lock_free;
2760typedef atomic<__libcpp_unsigned_lock_free> atomic_unsigned_lock_free;
2761
Howard Hinnantf1f066a2010-09-29 21:20:03 +00002762#define ATOMIC_FLAG_INIT {false}
Howard Hinnant953c31d2010-10-04 18:52:54 +00002763#define ATOMIC_VAR_INIT(__v) {__v}
2764
Howard Hinnant71be7292010-09-27 21:17:38 +00002765_LIBCPP_END_NAMESPACE_STD
2766
Howard Hinnant71be7292010-09-27 21:17:38 +00002767#endif // _LIBCPP_ATOMIC