blob: 56d8026c4e4fe7987b8ba53b6b688d4665f44c72 [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;
1488 _LIBCPP_INLINE_VISIBILITY bool operator()(chrono::nanoseconds __elapsed) const
1489 {
Olivier Giroux161e6e82020-02-18 09:58:34 -05001490 if(__elapsed > chrono::microseconds(64))
1491 {
1492 auto const __monitor = __libcpp_atomic_monitor(__a);
1493 if(__test_fn())
1494 return true;
1495 __libcpp_atomic_wait(__a, __monitor);
1496 }
1497 else if(__elapsed > chrono::microseconds(4))
1498 __libcpp_thread_yield();
1499 else
1500 ; // poll
1501 return false;
Louis Dionne08cd5cb2020-02-24 11:39:48 -05001502 }
1503};
1504
1505template <class _Atp, class _Fn>
1506_LIBCPP_INLINE_VISIBILITY bool __cxx_atomic_wait(_Atp* __a, _Fn && __test_fn)
1507{
1508 __libcpp_atomic_wait_backoff_impl<_Atp, typename decay<_Fn>::type> __backoff_fn = {__a, __test_fn};
1509 return __libcpp_thread_poll_with_backoff(__test_fn, __backoff_fn);
Olivier Giroux161e6e82020-02-18 09:58:34 -05001510}
1511
1512#else // _LIBCPP_HAS_NO_PLATFORM_WAIT
1513
1514template <class _Tp>
1515_LIBCPP_INLINE_VISIBILITY void __cxx_atomic_notify_all(__cxx_atomic_impl<_Tp> const volatile*) { }
1516template <class _Tp>
1517_LIBCPP_INLINE_VISIBILITY void __cxx_atomic_notify_one(__cxx_atomic_impl<_Tp> const volatile*) { }
1518template <class _Atp, class _Fn>
1519_LIBCPP_INLINE_VISIBILITY bool __cxx_atomic_wait(_Atp*, _Fn && __test_fn)
1520{
1521 return __libcpp_thread_poll_with_backoff(__test_fn, __libcpp_timed_backoff_policy());
1522}
1523
1524#endif // _LIBCPP_HAS_NO_PLATFORM_WAIT
1525
1526template <class _Atp, class _Tp>
Louis Dionne08cd5cb2020-02-24 11:39:48 -05001527struct __cxx_atomic_wait_test_fn_impl {
1528 _Atp* __a;
1529 _Tp __val;
1530 memory_order __order;
1531 _LIBCPP_INLINE_VISIBILITY bool operator()() const
1532 {
1533 return !__cxx_nonatomic_compare_equal(__cxx_atomic_load(__a, __order), __val);
1534 }
1535};
1536
1537template <class _Atp, class _Tp>
Olivier Giroux161e6e82020-02-18 09:58:34 -05001538_LIBCPP_INLINE_VISIBILITY bool __cxx_atomic_wait(_Atp* __a, _Tp const __val, memory_order __order)
1539{
Louis Dionne08cd5cb2020-02-24 11:39:48 -05001540 __cxx_atomic_wait_test_fn_impl<_Atp, _Tp> __test_fn = {__a, __val, __order};
Olivier Giroux161e6e82020-02-18 09:58:34 -05001541 return __cxx_atomic_wait(__a, __test_fn);
1542}
1543
1544#endif //_LIBCPP_STD_VER >= 11
1545
Howard Hinnant138f5922010-12-07 20:46:14 +00001546// general atomic<T>
1547
1548template <class _Tp, bool = is_integral<_Tp>::value && !is_same<_Tp, bool>::value>
1549struct __atomic_base // false
1550{
Davide Italiano011f80a2019-03-05 18:40:49 +00001551 mutable __cxx_atomic_impl<_Tp> __a_;
Howard Hinnant138f5922010-12-07 20:46:14 +00001552
JF Bastienfdb42c22016-03-25 15:48:21 +00001553#if defined(__cpp_lib_atomic_is_always_lock_free)
1554 static _LIBCPP_CONSTEXPR bool is_always_lock_free = __atomic_always_lock_free(sizeof(__a_), 0);
1555#endif
1556
Howard Hinnant138f5922010-12-07 20:46:14 +00001557 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001558 bool is_lock_free() const volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001559 {return __cxx_atomic_is_lock_free(sizeof(_Tp));}
Howard Hinnant138f5922010-12-07 20:46:14 +00001560 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001561 bool is_lock_free() const _NOEXCEPT
Eric Fiselier3fd22c22015-06-13 00:23:07 +00001562 {return static_cast<__atomic_base const volatile*>(this)->is_lock_free();}
Howard Hinnant138f5922010-12-07 20:46:14 +00001563 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001564 void store(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001565 _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
Davide Italiano011f80a2019-03-05 18:40:49 +00001566 {__cxx_atomic_store(&__a_, __d, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001567 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001568 void store(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001569 _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
Davide Italiano011f80a2019-03-05 18:40:49 +00001570 {__cxx_atomic_store(&__a_, __d, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001571 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001572 _Tp load(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001573 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
Davide Italiano011f80a2019-03-05 18:40:49 +00001574 {return __cxx_atomic_load(&__a_, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001575 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001576 _Tp load(memory_order __m = memory_order_seq_cst) const _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001577 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
Davide Italiano011f80a2019-03-05 18:40:49 +00001578 {return __cxx_atomic_load(&__a_, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001579 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001580 operator _Tp() const volatile _NOEXCEPT {return load();}
Howard Hinnant138f5922010-12-07 20:46:14 +00001581 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001582 operator _Tp() const _NOEXCEPT {return load();}
Howard Hinnant138f5922010-12-07 20:46:14 +00001583 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001584 _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001585 {return __cxx_atomic_exchange(&__a_, __d, __m);}
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) _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
1590 bool compare_exchange_weak(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001591 memory_order __s, memory_order __f) volatile _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001592 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Davide Italiano011f80a2019-03-05 18:40:49 +00001593 {return __cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001594 _LIBCPP_INLINE_VISIBILITY
1595 bool compare_exchange_weak(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001596 memory_order __s, memory_order __f) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001597 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Davide Italiano011f80a2019-03-05 18:40:49 +00001598 {return __cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001599 _LIBCPP_INLINE_VISIBILITY
1600 bool compare_exchange_strong(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001601 memory_order __s, memory_order __f) volatile _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001602 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Davide Italiano011f80a2019-03-05 18:40:49 +00001603 {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001604 _LIBCPP_INLINE_VISIBILITY
1605 bool compare_exchange_strong(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001606 memory_order __s, memory_order __f) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001607 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Davide Italiano011f80a2019-03-05 18:40:49 +00001608 {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001609 _LIBCPP_INLINE_VISIBILITY
1610 bool compare_exchange_weak(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001611 memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001612 {return __cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001613 _LIBCPP_INLINE_VISIBILITY
1614 bool compare_exchange_weak(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001615 memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001616 {return __cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001617 _LIBCPP_INLINE_VISIBILITY
1618 bool compare_exchange_strong(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001619 memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001620 {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001621 _LIBCPP_INLINE_VISIBILITY
1622 bool compare_exchange_strong(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001623 memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001624 {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001625
Olivier Giroux161e6e82020-02-18 09:58:34 -05001626 _LIBCPP_INLINE_VISIBILITY void wait(_Tp __v, memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
1627 {__cxx_atomic_wait(&__a_, __v, __m);}
1628 _LIBCPP_INLINE_VISIBILITY void wait(_Tp __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT
1629 {__cxx_atomic_wait(&__a_, __v, __m);}
1630 _LIBCPP_INLINE_VISIBILITY void notify_one() volatile _NOEXCEPT
1631 {__cxx_atomic_notify_one(&__a_);}
1632 _LIBCPP_INLINE_VISIBILITY void notify_one() _NOEXCEPT
1633 {__cxx_atomic_notify_one(&__a_);}
1634 _LIBCPP_INLINE_VISIBILITY void notify_all() volatile _NOEXCEPT
1635 {__cxx_atomic_notify_all(&__a_);}
1636 _LIBCPP_INLINE_VISIBILITY void notify_all() _NOEXCEPT
1637 {__cxx_atomic_notify_all(&__a_);}
1638
Howard Hinnant138f5922010-12-07 20:46:14 +00001639 _LIBCPP_INLINE_VISIBILITY
Davide Italiano011f80a2019-03-05 18:40:49 +00001640 __atomic_base() _NOEXCEPT _LIBCPP_DEFAULT
Howard Hinnant3d284222013-05-02 20:18:43 +00001641
Davide Italiano011f80a2019-03-05 18:40:49 +00001642 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
1643 __atomic_base(_Tp __d) _NOEXCEPT : __a_(__d) {}
1644
Eric Fiselier2d8515f2017-01-06 20:58:25 +00001645#ifndef _LIBCPP_CXX03_LANG
Howard Hinnant138f5922010-12-07 20:46:14 +00001646 __atomic_base(const __atomic_base&) = delete;
1647 __atomic_base& operator=(const __atomic_base&) = delete;
1648 __atomic_base& operator=(const __atomic_base&) volatile = delete;
Eric Fiselier2d8515f2017-01-06 20:58:25 +00001649#else
Howard Hinnant6ac60f82010-12-08 17:20:28 +00001650private:
Olivier Giroux161e6e82020-02-18 09:58:34 -05001651 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant6ac60f82010-12-08 17:20:28 +00001652 __atomic_base(const __atomic_base&);
Olivier Giroux161e6e82020-02-18 09:58:34 -05001653 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant6ac60f82010-12-08 17:20:28 +00001654 __atomic_base& operator=(const __atomic_base&);
Olivier Giroux161e6e82020-02-18 09:58:34 -05001655 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant6ac60f82010-12-08 17:20:28 +00001656 __atomic_base& operator=(const __atomic_base&) volatile;
Eric Fiselier2d8515f2017-01-06 20:58:25 +00001657#endif
Howard Hinnant138f5922010-12-07 20:46:14 +00001658};
1659
JF Bastienfdb42c22016-03-25 15:48:21 +00001660#if defined(__cpp_lib_atomic_is_always_lock_free)
1661template <class _Tp, bool __b>
1662_LIBCPP_CONSTEXPR bool __atomic_base<_Tp, __b>::is_always_lock_free;
1663#endif
1664
Howard Hinnant138f5922010-12-07 20:46:14 +00001665// atomic<Integral>
1666
1667template <class _Tp>
1668struct __atomic_base<_Tp, true>
1669 : public __atomic_base<_Tp, false>
1670{
1671 typedef __atomic_base<_Tp, false> __base;
1672 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3d284222013-05-02 20:18:43 +00001673 __atomic_base() _NOEXCEPT _LIBCPP_DEFAULT
Howard Hinnant138f5922010-12-07 20:46:14 +00001674 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001675 _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __base(__d) {}
Howard Hinnant138f5922010-12-07 20:46:14 +00001676
1677 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001678 _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001679 {return __cxx_atomic_fetch_add(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001680 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001681 _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) _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_sub(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001685 {return __cxx_atomic_fetch_sub(&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) _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_and(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001691 {return __cxx_atomic_fetch_and(&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) _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_or(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001697 {return __cxx_atomic_fetch_or(&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) _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_xor(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001703 {return __cxx_atomic_fetch_xor(&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) _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
1708 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001709 _Tp operator++(int) volatile _NOEXCEPT {return fetch_add(_Tp(1));}
Howard Hinnant138f5922010-12-07 20:46:14 +00001710 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001711 _Tp operator++(int) _NOEXCEPT {return fetch_add(_Tp(1));}
Howard Hinnant138f5922010-12-07 20:46:14 +00001712 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001713 _Tp operator--(int) volatile _NOEXCEPT {return fetch_sub(_Tp(1));}
Howard Hinnant138f5922010-12-07 20:46:14 +00001714 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001715 _Tp operator--(int) _NOEXCEPT {return fetch_sub(_Tp(1));}
Howard Hinnant138f5922010-12-07 20:46:14 +00001716 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001717 _Tp operator++() volatile _NOEXCEPT {return fetch_add(_Tp(1)) + _Tp(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001718 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001719 _Tp operator++() _NOEXCEPT {return fetch_add(_Tp(1)) + _Tp(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001720 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001721 _Tp operator--() volatile _NOEXCEPT {return fetch_sub(_Tp(1)) - _Tp(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001722 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001723 _Tp operator--() _NOEXCEPT {return fetch_sub(_Tp(1)) - _Tp(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001724 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001725 _Tp operator+=(_Tp __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001726 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001727 _Tp operator+=(_Tp __op) _NOEXCEPT {return fetch_add(__op) + __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001728 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001729 _Tp operator-=(_Tp __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001730 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001731 _Tp operator-=(_Tp __op) _NOEXCEPT {return fetch_sub(__op) - __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001732 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001733 _Tp operator&=(_Tp __op) volatile _NOEXCEPT {return fetch_and(__op) & __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001734 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001735 _Tp operator&=(_Tp __op) _NOEXCEPT {return fetch_and(__op) & __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001736 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001737 _Tp operator|=(_Tp __op) volatile _NOEXCEPT {return fetch_or(__op) | __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001738 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001739 _Tp operator|=(_Tp __op) _NOEXCEPT {return fetch_or(__op) | __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001740 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001741 _Tp operator^=(_Tp __op) volatile _NOEXCEPT {return fetch_xor(__op) ^ __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001742 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001743 _Tp operator^=(_Tp __op) _NOEXCEPT {return fetch_xor(__op) ^ __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001744};
1745
1746// atomic<T>
1747
1748template <class _Tp>
1749struct atomic
1750 : public __atomic_base<_Tp>
1751{
1752 typedef __atomic_base<_Tp> __base;
Olivier Giroux161e6e82020-02-18 09:58:34 -05001753 typedef _Tp value_type;
Howard Hinnant138f5922010-12-07 20:46:14 +00001754 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3d284222013-05-02 20:18:43 +00001755 atomic() _NOEXCEPT _LIBCPP_DEFAULT
Howard Hinnant138f5922010-12-07 20:46:14 +00001756 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001757 _LIBCPP_CONSTEXPR atomic(_Tp __d) _NOEXCEPT : __base(__d) {}
Howard Hinnant96e4cd62010-12-07 23:24:41 +00001758
1759 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001760 _Tp operator=(_Tp __d) volatile _NOEXCEPT
Howard Hinnant96e4cd62010-12-07 23:24:41 +00001761 {__base::store(__d); return __d;}
1762 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001763 _Tp operator=(_Tp __d) _NOEXCEPT
Howard Hinnant96e4cd62010-12-07 23:24:41 +00001764 {__base::store(__d); return __d;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001765};
1766
1767// atomic<T*>
1768
1769template <class _Tp>
1770struct atomic<_Tp*>
1771 : public __atomic_base<_Tp*>
1772{
Howard Hinnant96e4cd62010-12-07 23:24:41 +00001773 typedef __atomic_base<_Tp*> __base;
Olivier Giroux161e6e82020-02-18 09:58:34 -05001774 typedef _Tp* value_type;
Howard Hinnant138f5922010-12-07 20:46:14 +00001775 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3d284222013-05-02 20:18:43 +00001776 atomic() _NOEXCEPT _LIBCPP_DEFAULT
Howard Hinnant138f5922010-12-07 20:46:14 +00001777 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001778 _LIBCPP_CONSTEXPR atomic(_Tp* __d) _NOEXCEPT : __base(__d) {}
Howard Hinnant138f5922010-12-07 20:46:14 +00001779
1780 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001781 _Tp* operator=(_Tp* __d) volatile _NOEXCEPT
Howard Hinnant96e4cd62010-12-07 23:24:41 +00001782 {__base::store(__d); return __d;}
1783 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001784 _Tp* operator=(_Tp* __d) _NOEXCEPT
Howard Hinnant96e4cd62010-12-07 23:24:41 +00001785 {__base::store(__d); return __d;}
1786
1787 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00001788 _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst)
Howard Hinnanteee2c142012-04-11 20:14:21 +00001789 volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001790 {return __cxx_atomic_fetch_add(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001791 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001792 _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _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
1795 _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst)
Howard Hinnanteee2c142012-04-11 20:14:21 +00001796 volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001797 {return __cxx_atomic_fetch_sub(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001798 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001799 _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _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
1802 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001803 _Tp* operator++(int) volatile _NOEXCEPT {return fetch_add(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001804 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001805 _Tp* operator++(int) _NOEXCEPT {return fetch_add(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001806 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001807 _Tp* operator--(int) volatile _NOEXCEPT {return fetch_sub(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001808 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001809 _Tp* operator--(int) _NOEXCEPT {return fetch_sub(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001810 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001811 _Tp* operator++() volatile _NOEXCEPT {return fetch_add(1) + 1;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001812 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001813 _Tp* operator++() _NOEXCEPT {return fetch_add(1) + 1;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001814 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001815 _Tp* operator--() volatile _NOEXCEPT {return fetch_sub(1) - 1;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001816 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001817 _Tp* operator--() _NOEXCEPT {return fetch_sub(1) - 1;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001818 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001819 _Tp* operator+=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001820 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001821 _Tp* operator+=(ptrdiff_t __op) _NOEXCEPT {return fetch_add(__op) + __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001822 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001823 _Tp* operator-=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001824 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001825 _Tp* operator-=(ptrdiff_t __op) _NOEXCEPT {return fetch_sub(__op) - __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001826};
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001827
1828// atomic_is_lock_free
1829
1830template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001831_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001832bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00001833atomic_is_lock_free(const volatile atomic<_Tp>* __o) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001834{
Howard Hinnant138f5922010-12-07 20:46:14 +00001835 return __o->is_lock_free();
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001836}
1837
1838template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001839_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001840bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00001841atomic_is_lock_free(const atomic<_Tp>* __o) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001842{
Howard Hinnant138f5922010-12-07 20:46:14 +00001843 return __o->is_lock_free();
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001844}
1845
1846// atomic_init
1847
1848template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001849_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001850void
Howard Hinnanteee2c142012-04-11 20:14:21 +00001851atomic_init(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001852{
Davide Italiano011f80a2019-03-05 18:40:49 +00001853 __cxx_atomic_init(&__o->__a_, __d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001854}
1855
1856template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001857_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001858void
Howard Hinnanteee2c142012-04-11 20:14:21 +00001859atomic_init(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001860{
Davide Italiano011f80a2019-03-05 18:40:49 +00001861 __cxx_atomic_init(&__o->__a_, __d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001862}
1863
1864// atomic_store
1865
1866template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001867_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001868void
Howard Hinnanteee2c142012-04-11 20:14:21 +00001869atomic_store(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001870{
Howard Hinnant138f5922010-12-07 20:46:14 +00001871 __o->store(__d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001872}
1873
1874template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001875_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001876void
Howard Hinnanteee2c142012-04-11 20:14:21 +00001877atomic_store(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001878{
Howard Hinnant138f5922010-12-07 20:46:14 +00001879 __o->store(__d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001880}
1881
1882// atomic_store_explicit
1883
1884template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001885_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001886void
Howard Hinnanteee2c142012-04-11 20:14:21 +00001887atomic_store_explicit(volatile atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001888 _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001889{
Howard Hinnant138f5922010-12-07 20:46:14 +00001890 __o->store(__d, __m);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001891}
1892
1893template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001894_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001895void
Howard Hinnanteee2c142012-04-11 20:14:21 +00001896atomic_store_explicit(atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001897 _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001898{
Howard Hinnant138f5922010-12-07 20:46:14 +00001899 __o->store(__d, __m);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001900}
1901
1902// atomic_load
1903
1904template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001905_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001906_Tp
Howard Hinnanteee2c142012-04-11 20:14:21 +00001907atomic_load(const volatile atomic<_Tp>* __o) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001908{
Howard Hinnant138f5922010-12-07 20:46:14 +00001909 return __o->load();
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001910}
1911
1912template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001913_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001914_Tp
Howard Hinnanteee2c142012-04-11 20:14:21 +00001915atomic_load(const atomic<_Tp>* __o) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001916{
Howard Hinnant138f5922010-12-07 20:46:14 +00001917 return __o->load();
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001918}
1919
1920// atomic_load_explicit
1921
1922template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001923_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001924_Tp
Howard Hinnanteee2c142012-04-11 20:14:21 +00001925atomic_load_explicit(const volatile atomic<_Tp>* __o, memory_order __m) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001926 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001927{
Howard Hinnant138f5922010-12-07 20:46:14 +00001928 return __o->load(__m);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001929}
1930
1931template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001932_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001933_Tp
Howard Hinnanteee2c142012-04-11 20:14:21 +00001934atomic_load_explicit(const atomic<_Tp>* __o, memory_order __m) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001935 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001936{
Howard Hinnant138f5922010-12-07 20:46:14 +00001937 return __o->load(__m);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001938}
1939
1940// atomic_exchange
1941
1942template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001943_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001944_Tp
Howard Hinnanteee2c142012-04-11 20:14:21 +00001945atomic_exchange(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001946{
Howard Hinnant138f5922010-12-07 20:46:14 +00001947 return __o->exchange(__d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001948}
1949
1950template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001951_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001952_Tp
Howard Hinnanteee2c142012-04-11 20:14:21 +00001953atomic_exchange(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001954{
Howard Hinnant138f5922010-12-07 20:46:14 +00001955 return __o->exchange(__d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001956}
1957
1958// atomic_exchange_explicit
1959
1960template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001961_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001962_Tp
Howard Hinnanteee2c142012-04-11 20:14:21 +00001963atomic_exchange_explicit(volatile atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001964{
Howard Hinnant138f5922010-12-07 20:46:14 +00001965 return __o->exchange(__d, __m);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001966}
1967
1968template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001969_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001970_Tp
Howard Hinnanteee2c142012-04-11 20:14:21 +00001971atomic_exchange_explicit(atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001972{
Howard Hinnant138f5922010-12-07 20:46:14 +00001973 return __o->exchange(__d, __m);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001974}
1975
1976// atomic_compare_exchange_weak
1977
1978template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001979_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001980bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00001981atomic_compare_exchange_weak(volatile atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001982{
Howard Hinnant138f5922010-12-07 20:46:14 +00001983 return __o->compare_exchange_weak(*__e, __d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001984}
1985
1986template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001987_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001988bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00001989atomic_compare_exchange_weak(atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001990{
Howard Hinnant138f5922010-12-07 20:46:14 +00001991 return __o->compare_exchange_weak(*__e, __d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001992}
1993
1994// atomic_compare_exchange_strong
1995
1996template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001997_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001998bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00001999atomic_compare_exchange_strong(volatile atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002000{
Howard Hinnant138f5922010-12-07 20:46:14 +00002001 return __o->compare_exchange_strong(*__e, __d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002002}
2003
2004template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002005_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002006bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00002007atomic_compare_exchange_strong(atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002008{
Howard Hinnant138f5922010-12-07 20:46:14 +00002009 return __o->compare_exchange_strong(*__e, __d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002010}
2011
2012// atomic_compare_exchange_weak_explicit
2013
2014template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002015_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002016bool
2017atomic_compare_exchange_weak_explicit(volatile atomic<_Tp>* __o, _Tp* __e,
2018 _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00002019 memory_order __s, memory_order __f) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00002020 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002021{
Howard Hinnant138f5922010-12-07 20:46:14 +00002022 return __o->compare_exchange_weak(*__e, __d, __s, __f);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002023}
2024
2025template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002026_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002027bool
2028atomic_compare_exchange_weak_explicit(atomic<_Tp>* __o, _Tp* __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00002029 memory_order __s, memory_order __f) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00002030 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002031{
Howard Hinnant138f5922010-12-07 20:46:14 +00002032 return __o->compare_exchange_weak(*__e, __d, __s, __f);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002033}
2034
2035// atomic_compare_exchange_strong_explicit
2036
2037template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002038_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002039bool
2040atomic_compare_exchange_strong_explicit(volatile atomic<_Tp>* __o,
2041 _Tp* __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00002042 memory_order __s, memory_order __f) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00002043 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002044{
Howard Hinnant138f5922010-12-07 20:46:14 +00002045 return __o->compare_exchange_strong(*__e, __d, __s, __f);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002046}
2047
2048template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002049_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002050bool
2051atomic_compare_exchange_strong_explicit(atomic<_Tp>* __o, _Tp* __e,
2052 _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00002053 memory_order __s, memory_order __f) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00002054 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002055{
Howard Hinnant138f5922010-12-07 20:46:14 +00002056 return __o->compare_exchange_strong(*__e, __d, __s, __f);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002057}
2058
Olivier Giroux161e6e82020-02-18 09:58:34 -05002059// atomic_wait
2060
2061template <class _Tp>
2062_LIBCPP_INLINE_VISIBILITY
2063void atomic_wait(const volatile atomic<_Tp>* __o,
2064 typename atomic<_Tp>::value_type __v) _NOEXCEPT
2065{
2066 return __o->wait(__v);
2067}
2068
2069template <class _Tp>
2070_LIBCPP_INLINE_VISIBILITY
2071void atomic_wait(const atomic<_Tp>* __o,
2072 typename atomic<_Tp>::value_type __v) _NOEXCEPT
2073{
2074 return __o->wait(__v);
2075}
2076
2077// atomic_wait_explicit
2078
2079template <class _Tp>
2080_LIBCPP_INLINE_VISIBILITY
2081void atomic_wait_explicit(const volatile atomic<_Tp>* __o,
2082 typename atomic<_Tp>::value_type __v,
2083 memory_order __m) _NOEXCEPT
2084 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
2085{
2086 return __o->wait(__v, __m);
2087}
2088
2089template <class _Tp>
2090_LIBCPP_INLINE_VISIBILITY
2091void atomic_wait_explicit(const atomic<_Tp>* __o,
2092 typename atomic<_Tp>::value_type __v,
2093 memory_order __m) _NOEXCEPT
2094 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
2095{
2096 return __o->wait(__v, __m);
2097}
2098
2099// atomic_notify_one
2100
2101template <class _Tp>
2102_LIBCPP_INLINE_VISIBILITY
2103void atomic_notify_one(volatile atomic<_Tp>* __o) _NOEXCEPT
2104{
2105 __o->notify_one();
2106}
2107template <class _Tp>
2108_LIBCPP_INLINE_VISIBILITY
2109void atomic_notify_one(atomic<_Tp>* __o) _NOEXCEPT
2110{
2111 __o->notify_one();
2112}
2113
2114// atomic_notify_one
2115
2116template <class _Tp>
2117_LIBCPP_INLINE_VISIBILITY
2118void atomic_notify_all(volatile atomic<_Tp>* __o) _NOEXCEPT
2119{
2120 __o->notify_all();
2121}
2122template <class _Tp>
2123_LIBCPP_INLINE_VISIBILITY
2124void atomic_notify_all(atomic<_Tp>* __o) _NOEXCEPT
2125{
2126 __o->notify_all();
2127}
2128
Howard Hinnant138f5922010-12-07 20:46:14 +00002129// atomic_fetch_add
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002130
2131template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002132_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002133typename enable_if
2134<
2135 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2136 _Tp
2137>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00002138atomic_fetch_add(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002139{
Howard Hinnant138f5922010-12-07 20:46:14 +00002140 return __o->fetch_add(__op);
2141}
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002142
Howard Hinnant138f5922010-12-07 20:46:14 +00002143template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002144_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002145typename enable_if
2146<
2147 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2148 _Tp
2149>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00002150atomic_fetch_add(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002151{
2152 return __o->fetch_add(__op);
2153}
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002154
Howard Hinnant138f5922010-12-07 20:46:14 +00002155template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002156_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002157_Tp*
Howard Hinnanteee2c142012-04-11 20:14:21 +00002158atomic_fetch_add(volatile atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002159{
2160 return __o->fetch_add(__op);
2161}
2162
2163template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002164_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002165_Tp*
Howard Hinnanteee2c142012-04-11 20:14:21 +00002166atomic_fetch_add(atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002167{
2168 return __o->fetch_add(__op);
2169}
2170
2171// atomic_fetch_add_explicit
2172
2173template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002174_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002175typename enable_if
2176<
2177 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2178 _Tp
2179>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00002180atomic_fetch_add_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002181{
2182 return __o->fetch_add(__op, __m);
2183}
2184
2185template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002186_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002187typename enable_if
2188<
2189 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2190 _Tp
2191>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00002192atomic_fetch_add_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002193{
2194 return __o->fetch_add(__op, __m);
2195}
2196
2197template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002198_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002199_Tp*
2200atomic_fetch_add_explicit(volatile atomic<_Tp*>* __o, ptrdiff_t __op,
Howard Hinnanteee2c142012-04-11 20:14:21 +00002201 memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002202{
2203 return __o->fetch_add(__op, __m);
2204}
2205
2206template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002207_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002208_Tp*
Howard Hinnanteee2c142012-04-11 20:14:21 +00002209atomic_fetch_add_explicit(atomic<_Tp*>* __o, ptrdiff_t __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002210{
2211 return __o->fetch_add(__op, __m);
2212}
2213
2214// atomic_fetch_sub
2215
2216template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002217_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002218typename enable_if
2219<
2220 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2221 _Tp
2222>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00002223atomic_fetch_sub(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002224{
2225 return __o->fetch_sub(__op);
2226}
2227
2228template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002229_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002230typename enable_if
2231<
2232 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2233 _Tp
2234>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00002235atomic_fetch_sub(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002236{
2237 return __o->fetch_sub(__op);
2238}
2239
2240template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002241_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002242_Tp*
Howard Hinnanteee2c142012-04-11 20:14:21 +00002243atomic_fetch_sub(volatile atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002244{
2245 return __o->fetch_sub(__op);
2246}
2247
2248template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002249_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002250_Tp*
Howard Hinnanteee2c142012-04-11 20:14:21 +00002251atomic_fetch_sub(atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002252{
2253 return __o->fetch_sub(__op);
2254}
2255
2256// atomic_fetch_sub_explicit
2257
2258template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002259_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002260typename enable_if
2261<
2262 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2263 _Tp
2264>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00002265atomic_fetch_sub_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002266{
2267 return __o->fetch_sub(__op, __m);
2268}
2269
2270template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002271_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002272typename enable_if
2273<
2274 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2275 _Tp
2276>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00002277atomic_fetch_sub_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002278{
2279 return __o->fetch_sub(__op, __m);
2280}
2281
2282template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002283_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002284_Tp*
2285atomic_fetch_sub_explicit(volatile atomic<_Tp*>* __o, ptrdiff_t __op,
Howard Hinnanteee2c142012-04-11 20:14:21 +00002286 memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002287{
2288 return __o->fetch_sub(__op, __m);
2289}
2290
2291template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002292_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002293_Tp*
Howard Hinnanteee2c142012-04-11 20:14:21 +00002294atomic_fetch_sub_explicit(atomic<_Tp*>* __o, ptrdiff_t __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002295{
2296 return __o->fetch_sub(__op, __m);
2297}
2298
2299// atomic_fetch_and
2300
2301template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002302_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002303typename enable_if
2304<
2305 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2306 _Tp
2307>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00002308atomic_fetch_and(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002309{
2310 return __o->fetch_and(__op);
2311}
2312
2313template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002314_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002315typename enable_if
2316<
2317 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2318 _Tp
2319>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00002320atomic_fetch_and(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002321{
2322 return __o->fetch_and(__op);
2323}
2324
2325// atomic_fetch_and_explicit
2326
2327template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002328_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002329typename enable_if
2330<
2331 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2332 _Tp
2333>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00002334atomic_fetch_and_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002335{
2336 return __o->fetch_and(__op, __m);
2337}
2338
2339template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002340_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002341typename enable_if
2342<
2343 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2344 _Tp
2345>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00002346atomic_fetch_and_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002347{
2348 return __o->fetch_and(__op, __m);
2349}
2350
2351// atomic_fetch_or
2352
2353template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002354_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002355typename enable_if
2356<
2357 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2358 _Tp
2359>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00002360atomic_fetch_or(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002361{
2362 return __o->fetch_or(__op);
2363}
2364
2365template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002366_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002367typename enable_if
2368<
2369 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2370 _Tp
2371>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00002372atomic_fetch_or(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002373{
2374 return __o->fetch_or(__op);
2375}
2376
2377// atomic_fetch_or_explicit
2378
2379template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002380_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002381typename enable_if
2382<
2383 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2384 _Tp
2385>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00002386atomic_fetch_or_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002387{
2388 return __o->fetch_or(__op, __m);
2389}
2390
2391template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002392_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002393typename enable_if
2394<
2395 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2396 _Tp
2397>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00002398atomic_fetch_or_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002399{
2400 return __o->fetch_or(__op, __m);
2401}
2402
2403// atomic_fetch_xor
2404
2405template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002406_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002407typename enable_if
2408<
2409 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2410 _Tp
2411>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00002412atomic_fetch_xor(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002413{
2414 return __o->fetch_xor(__op);
2415}
2416
2417template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002418_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002419typename enable_if
2420<
2421 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2422 _Tp
2423>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00002424atomic_fetch_xor(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002425{
2426 return __o->fetch_xor(__op);
2427}
2428
2429// atomic_fetch_xor_explicit
2430
2431template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002432_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002433typename enable_if
2434<
2435 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2436 _Tp
2437>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00002438atomic_fetch_xor_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002439{
2440 return __o->fetch_xor(__op, __m);
2441}
2442
2443template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002444_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002445typename enable_if
2446<
2447 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2448 _Tp
2449>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00002450atomic_fetch_xor_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002451{
2452 return __o->fetch_xor(__op, __m);
2453}
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002454
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002455// flag type and operations
2456
2457typedef struct atomic_flag
2458{
Davide Italiano011f80a2019-03-05 18:40:49 +00002459 __cxx_atomic_impl<_LIBCPP_ATOMIC_FLAG_TYPE> __a_;
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002460
2461 _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002462 bool test(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
2463 {return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m);}
2464 _LIBCPP_INLINE_VISIBILITY
2465 bool test(memory_order __m = memory_order_seq_cst) const _NOEXCEPT
2466 {return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m);}
2467
2468 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00002469 bool test_and_set(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00002470 {return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);}
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002471 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00002472 bool test_and_set(memory_order __m = memory_order_seq_cst) _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 void clear(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00002476 {__cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __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) _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
2481 _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002482 void wait(bool __v, memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
2483 {__cxx_atomic_wait(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);}
2484 _LIBCPP_INLINE_VISIBILITY
2485 void wait(bool __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT
2486 {__cxx_atomic_wait(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);}
2487 _LIBCPP_INLINE_VISIBILITY
2488 void notify_one() volatile _NOEXCEPT
2489 {__cxx_atomic_notify_one(&__a_);}
2490 _LIBCPP_INLINE_VISIBILITY
2491 void notify_one() _NOEXCEPT
2492 {__cxx_atomic_notify_one(&__a_);}
2493 _LIBCPP_INLINE_VISIBILITY
2494 void notify_all() volatile _NOEXCEPT
2495 {__cxx_atomic_notify_all(&__a_);}
2496 _LIBCPP_INLINE_VISIBILITY
2497 void notify_all() _NOEXCEPT
2498 {__cxx_atomic_notify_all(&__a_);}
2499
2500 _LIBCPP_INLINE_VISIBILITY
Davide Italiano011f80a2019-03-05 18:40:49 +00002501 atomic_flag() _NOEXCEPT _LIBCPP_DEFAULT
Howard Hinnant3d284222013-05-02 20:18:43 +00002502
Marshall Clowcf990752018-04-25 14:27:29 +00002503 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
Eric Fiselierfec26a92016-05-03 02:12:26 +00002504 atomic_flag(bool __b) _NOEXCEPT : __a_(__b) {} // EXTENSION
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002505
Eric Fiselier2d8515f2017-01-06 20:58:25 +00002506#ifndef _LIBCPP_CXX03_LANG
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002507 atomic_flag(const atomic_flag&) = delete;
2508 atomic_flag& operator=(const atomic_flag&) = delete;
2509 atomic_flag& operator=(const atomic_flag&) volatile = delete;
Eric Fiselier2d8515f2017-01-06 20:58:25 +00002510#else
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002511private:
Olivier Giroux161e6e82020-02-18 09:58:34 -05002512 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002513 atomic_flag(const atomic_flag&);
Olivier Giroux161e6e82020-02-18 09:58:34 -05002514 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002515 atomic_flag& operator=(const atomic_flag&);
Olivier Giroux161e6e82020-02-18 09:58:34 -05002516 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002517 atomic_flag& operator=(const atomic_flag&) volatile;
Eric Fiselier2d8515f2017-01-06 20:58:25 +00002518#endif
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002519} atomic_flag;
2520
Olivier Giroux161e6e82020-02-18 09:58:34 -05002521
2522inline _LIBCPP_INLINE_VISIBILITY
2523bool
2524atomic_flag_test(const volatile atomic_flag* __o) _NOEXCEPT
2525{
2526 return __o->test();
2527}
2528
2529inline _LIBCPP_INLINE_VISIBILITY
2530bool
2531atomic_flag_test(const atomic_flag* __o) _NOEXCEPT
2532{
2533 return __o->test();
2534}
2535
2536inline _LIBCPP_INLINE_VISIBILITY
2537bool
2538atomic_flag_test_explicit(const volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
2539{
2540 return __o->test(__m);
2541}
2542
2543inline _LIBCPP_INLINE_VISIBILITY
2544bool
2545atomic_flag_test_explicit(const atomic_flag* __o, memory_order __m) _NOEXCEPT
2546{
2547 return __o->test(__m);
2548}
2549
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002550inline _LIBCPP_INLINE_VISIBILITY
2551bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00002552atomic_flag_test_and_set(volatile atomic_flag* __o) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002553{
2554 return __o->test_and_set();
2555}
2556
2557inline _LIBCPP_INLINE_VISIBILITY
2558bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00002559atomic_flag_test_and_set(atomic_flag* __o) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002560{
2561 return __o->test_and_set();
2562}
2563
2564inline _LIBCPP_INLINE_VISIBILITY
2565bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00002566atomic_flag_test_and_set_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002567{
2568 return __o->test_and_set(__m);
2569}
2570
2571inline _LIBCPP_INLINE_VISIBILITY
2572bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00002573atomic_flag_test_and_set_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002574{
2575 return __o->test_and_set(__m);
2576}
2577
2578inline _LIBCPP_INLINE_VISIBILITY
2579void
Howard Hinnanteee2c142012-04-11 20:14:21 +00002580atomic_flag_clear(volatile atomic_flag* __o) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002581{
2582 __o->clear();
2583}
2584
2585inline _LIBCPP_INLINE_VISIBILITY
2586void
Howard Hinnanteee2c142012-04-11 20:14:21 +00002587atomic_flag_clear(atomic_flag* __o) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002588{
2589 __o->clear();
2590}
2591
2592inline _LIBCPP_INLINE_VISIBILITY
2593void
Howard Hinnanteee2c142012-04-11 20:14:21 +00002594atomic_flag_clear_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002595{
2596 __o->clear(__m);
2597}
2598
2599inline _LIBCPP_INLINE_VISIBILITY
2600void
Howard Hinnanteee2c142012-04-11 20:14:21 +00002601atomic_flag_clear_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002602{
2603 __o->clear(__m);
2604}
2605
Olivier Giroux161e6e82020-02-18 09:58:34 -05002606inline _LIBCPP_INLINE_VISIBILITY
2607void
2608atomic_flag_wait(const volatile atomic_flag* __o, bool __v) _NOEXCEPT
2609{
2610 __o->wait(__v);
2611}
2612
2613inline _LIBCPP_INLINE_VISIBILITY
2614void
2615atomic_flag_wait(const atomic_flag* __o, bool __v) _NOEXCEPT
2616{
2617 __o->wait(__v);
2618}
2619
2620inline _LIBCPP_INLINE_VISIBILITY
2621void
2622atomic_flag_wait_explicit(const volatile atomic_flag* __o,
2623 bool __v, memory_order __m) _NOEXCEPT
2624{
2625 __o->wait(__v, __m);
2626}
2627
2628inline _LIBCPP_INLINE_VISIBILITY
2629void
2630atomic_flag_wait_explicit(const atomic_flag* __o,
2631 bool __v, memory_order __m) _NOEXCEPT
2632{
2633 __o->wait(__v, __m);
2634}
2635
2636inline _LIBCPP_INLINE_VISIBILITY
2637void
2638atomic_flag_notify_one(volatile atomic_flag* __o) _NOEXCEPT
2639{
2640 __o->notify_one();
2641}
2642
2643inline _LIBCPP_INLINE_VISIBILITY
2644void
2645atomic_flag_notify_one(atomic_flag* __o) _NOEXCEPT
2646{
2647 __o->notify_one();
2648}
2649
2650inline _LIBCPP_INLINE_VISIBILITY
2651void
2652atomic_flag_notify_all(volatile atomic_flag* __o) _NOEXCEPT
2653{
2654 __o->notify_all();
2655}
2656
2657inline _LIBCPP_INLINE_VISIBILITY
2658void
2659atomic_flag_notify_all(atomic_flag* __o) _NOEXCEPT
2660{
2661 __o->notify_all();
2662}
2663
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002664// fences
2665
2666inline _LIBCPP_INLINE_VISIBILITY
2667void
Howard Hinnanteee2c142012-04-11 20:14:21 +00002668atomic_thread_fence(memory_order __m) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002669{
Davide Italiano011f80a2019-03-05 18:40:49 +00002670 __cxx_atomic_thread_fence(__m);
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002671}
2672
2673inline _LIBCPP_INLINE_VISIBILITY
2674void
Howard Hinnanteee2c142012-04-11 20:14:21 +00002675atomic_signal_fence(memory_order __m) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002676{
Davide Italiano011f80a2019-03-05 18:40:49 +00002677 __cxx_atomic_signal_fence(__m);
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002678}
2679
Howard Hinnant96e4cd62010-12-07 23:24:41 +00002680// Atomics for standard typedef types
2681
Howard Hinnantf0af8d92013-01-04 18:58:50 +00002682typedef atomic<bool> atomic_bool;
Howard Hinnant96e4cd62010-12-07 23:24:41 +00002683typedef atomic<char> atomic_char;
2684typedef atomic<signed char> atomic_schar;
2685typedef atomic<unsigned char> atomic_uchar;
2686typedef atomic<short> atomic_short;
2687typedef atomic<unsigned short> atomic_ushort;
2688typedef atomic<int> atomic_int;
2689typedef atomic<unsigned int> atomic_uint;
2690typedef atomic<long> atomic_long;
2691typedef atomic<unsigned long> atomic_ulong;
2692typedef atomic<long long> atomic_llong;
2693typedef atomic<unsigned long long> atomic_ullong;
2694typedef atomic<char16_t> atomic_char16_t;
2695typedef atomic<char32_t> atomic_char32_t;
2696typedef atomic<wchar_t> atomic_wchar_t;
2697
2698typedef atomic<int_least8_t> atomic_int_least8_t;
2699typedef atomic<uint_least8_t> atomic_uint_least8_t;
2700typedef atomic<int_least16_t> atomic_int_least16_t;
2701typedef atomic<uint_least16_t> atomic_uint_least16_t;
2702typedef atomic<int_least32_t> atomic_int_least32_t;
2703typedef atomic<uint_least32_t> atomic_uint_least32_t;
2704typedef atomic<int_least64_t> atomic_int_least64_t;
2705typedef atomic<uint_least64_t> atomic_uint_least64_t;
2706
2707typedef atomic<int_fast8_t> atomic_int_fast8_t;
2708typedef atomic<uint_fast8_t> atomic_uint_fast8_t;
2709typedef atomic<int_fast16_t> atomic_int_fast16_t;
2710typedef atomic<uint_fast16_t> atomic_uint_fast16_t;
2711typedef atomic<int_fast32_t> atomic_int_fast32_t;
2712typedef atomic<uint_fast32_t> atomic_uint_fast32_t;
2713typedef atomic<int_fast64_t> atomic_int_fast64_t;
2714typedef atomic<uint_fast64_t> atomic_uint_fast64_t;
2715
Marshall Clowf710afc2016-06-30 15:28:38 +00002716typedef atomic< int8_t> atomic_int8_t;
2717typedef atomic<uint8_t> atomic_uint8_t;
2718typedef atomic< int16_t> atomic_int16_t;
2719typedef atomic<uint16_t> atomic_uint16_t;
2720typedef atomic< int32_t> atomic_int32_t;
2721typedef atomic<uint32_t> atomic_uint32_t;
2722typedef atomic< int64_t> atomic_int64_t;
2723typedef atomic<uint64_t> atomic_uint64_t;
2724
Howard Hinnant96e4cd62010-12-07 23:24:41 +00002725typedef atomic<intptr_t> atomic_intptr_t;
2726typedef atomic<uintptr_t> atomic_uintptr_t;
2727typedef atomic<size_t> atomic_size_t;
2728typedef atomic<ptrdiff_t> atomic_ptrdiff_t;
2729typedef atomic<intmax_t> atomic_intmax_t;
2730typedef atomic<uintmax_t> atomic_uintmax_t;
2731
Olivier Giroux161e6e82020-02-18 09:58:34 -05002732// atomic_*_lock_free : prefer the contention type most highly, then the largest lock-free type
2733
2734#ifdef __cpp_lib_atomic_is_always_lock_free
2735# define _LIBCPP_CONTENTION_LOCK_FREE __atomic_always_lock_free(sizeof(__cxx_contention_t), 0)
2736#else
2737# define _LIBCPP_CONTENTION_LOCK_FREE false
2738#endif
2739
2740#if ATOMIC_LLONG_LOCK_FREE == 2
2741typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, long long>::type __libcpp_signed_lock_free;
2742typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned long long>::type __libcpp_unsigned_lock_free;
2743#elif ATOMIC_INT_LOCK_FREE == 2
2744typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, int>::type __libcpp_signed_lock_free;
2745typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned int>::type __libcpp_unsigned_lock_free;
2746#elif ATOMIC_SHORT_LOCK_FREE == 2
2747typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, short>::type __libcpp_signed_lock_free;
2748typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned short>::type __libcpp_unsigned_lock_free;
2749#elif ATOMIC_CHAR_LOCK_FREE == 2
2750typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, char>::type __libcpp_signed_lock_free;
2751typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned char>::type __libcpp_unsigned_lock_free;
2752#else
2753 // No signed/unsigned lock-free types
2754#endif
2755
2756typedef atomic<__libcpp_signed_lock_free> atomic_signed_lock_free;
2757typedef atomic<__libcpp_unsigned_lock_free> atomic_unsigned_lock_free;
2758
Howard Hinnantf1f066a2010-09-29 21:20:03 +00002759#define ATOMIC_FLAG_INIT {false}
Howard Hinnant953c31d2010-10-04 18:52:54 +00002760#define ATOMIC_VAR_INIT(__v) {__v}
2761
Howard Hinnant71be7292010-09-27 21:17:38 +00002762_LIBCPP_END_NAMESPACE_STD
2763
Howard Hinnant71be7292010-09-27 21:17:38 +00002764#endif // _LIBCPP_ATOMIC