blob: 65cd8d59e5ce26562129dac43cbf512245a0fe85 [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
Howard Hinnant71be7292010-09-27 21:17:38 +000023// order and consistency
24
25typedef enum memory_order
26{
Howard Hinnantdca6e712010-09-28 17:13:38 +000027 memory_order_relaxed,
28 memory_order_consume, // load-consume
29 memory_order_acquire, // load-acquire
30 memory_order_release, // store-release
31 memory_order_acq_rel, // store-release load-acquire
32 memory_order_seq_cst // store-release load-acquire
Howard Hinnant71be7292010-09-27 21:17:38 +000033} memory_order;
34
Howard Hinnanteee2c142012-04-11 20:14:21 +000035template <class T> T kill_dependency(T y) noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +000036
37// lock-free property
38
Howard Hinnant931e3402013-01-21 20:39:41 +000039#define ATOMIC_BOOL_LOCK_FREE unspecified
Howard Hinnant71be7292010-09-27 21:17:38 +000040#define ATOMIC_CHAR_LOCK_FREE unspecified
41#define ATOMIC_CHAR16_T_LOCK_FREE unspecified
42#define ATOMIC_CHAR32_T_LOCK_FREE unspecified
43#define ATOMIC_WCHAR_T_LOCK_FREE unspecified
44#define ATOMIC_SHORT_LOCK_FREE unspecified
45#define ATOMIC_INT_LOCK_FREE unspecified
46#define ATOMIC_LONG_LOCK_FREE unspecified
47#define ATOMIC_LLONG_LOCK_FREE unspecified
Howard Hinnant931e3402013-01-21 20:39:41 +000048#define ATOMIC_POINTER_LOCK_FREE unspecified
Howard Hinnant71be7292010-09-27 21:17:38 +000049
Howard Hinnant71be7292010-09-27 21:17:38 +000050// flag type and operations
51
52typedef struct atomic_flag
53{
Howard Hinnanteee2c142012-04-11 20:14:21 +000054 bool test_and_set(memory_order m = memory_order_seq_cst) volatile noexcept;
55 bool test_and_set(memory_order m = memory_order_seq_cst) noexcept;
56 void clear(memory_order m = memory_order_seq_cst) volatile noexcept;
57 void clear(memory_order m = memory_order_seq_cst) noexcept;
58 atomic_flag() noexcept = default;
Howard Hinnant71be7292010-09-27 21:17:38 +000059 atomic_flag(const atomic_flag&) = delete;
60 atomic_flag& operator=(const atomic_flag&) = delete;
61 atomic_flag& operator=(const atomic_flag&) volatile = delete;
62} atomic_flag;
63
Howard Hinnant7bfaeb82010-12-06 23:10:08 +000064bool
Howard Hinnanteee2c142012-04-11 20:14:21 +000065 atomic_flag_test_and_set(volatile atomic_flag* obj) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +000066
67bool
Howard Hinnanteee2c142012-04-11 20:14:21 +000068 atomic_flag_test_and_set(atomic_flag* obj) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +000069
70bool
71 atomic_flag_test_and_set_explicit(volatile atomic_flag* obj,
Howard Hinnanteee2c142012-04-11 20:14:21 +000072 memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +000073
74bool
Howard Hinnanteee2c142012-04-11 20:14:21 +000075 atomic_flag_test_and_set_explicit(atomic_flag* obj, memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +000076
77void
Howard Hinnanteee2c142012-04-11 20:14:21 +000078 atomic_flag_clear(volatile atomic_flag* obj) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +000079
80void
Howard Hinnanteee2c142012-04-11 20:14:21 +000081 atomic_flag_clear(atomic_flag* obj) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +000082
83void
Howard Hinnanteee2c142012-04-11 20:14:21 +000084 atomic_flag_clear_explicit(volatile atomic_flag* obj, memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +000085
86void
Howard Hinnanteee2c142012-04-11 20:14:21 +000087 atomic_flag_clear_explicit(atomic_flag* obj, memory_order m) noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +000088
89#define ATOMIC_FLAG_INIT see below
Howard Hinnant493d1d92010-10-19 16:51:18 +000090#define ATOMIC_VAR_INIT(value) see below
Howard Hinnant71be7292010-09-27 21:17:38 +000091
Howard Hinnant71be7292010-09-27 21:17:38 +000092template <class T>
93struct atomic
94{
JF Bastienfdb42c22016-03-25 15:48:21 +000095 static constexpr bool is_always_lock_free;
Howard Hinnanteee2c142012-04-11 20:14:21 +000096 bool is_lock_free() const volatile noexcept;
97 bool is_lock_free() const noexcept;
98 void store(T desr, memory_order m = memory_order_seq_cst) volatile noexcept;
99 void store(T desr, memory_order m = memory_order_seq_cst) noexcept;
100 T load(memory_order m = memory_order_seq_cst) const volatile noexcept;
101 T load(memory_order m = memory_order_seq_cst) const noexcept;
102 operator T() const volatile noexcept;
103 operator T() const noexcept;
104 T exchange(T desr, memory_order m = memory_order_seq_cst) volatile noexcept;
105 T exchange(T desr, memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000106 bool compare_exchange_weak(T& expc, T desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000107 memory_order s, memory_order f) volatile noexcept;
108 bool compare_exchange_weak(T& expc, T desr, memory_order s, memory_order f) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000109 bool compare_exchange_strong(T& expc, T desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000110 memory_order s, memory_order f) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000111 bool compare_exchange_strong(T& expc, T desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000112 memory_order s, memory_order f) 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 m = memory_order_seq_cst) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000115 bool compare_exchange_weak(T& expc, T desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000116 memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000117 bool compare_exchange_strong(T& expc, T desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000118 memory_order m = memory_order_seq_cst) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000119 bool compare_exchange_strong(T& expc, T desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000120 memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +0000121
Howard Hinnanteee2c142012-04-11 20:14:21 +0000122 atomic() noexcept = default;
123 constexpr atomic(T desr) noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +0000124 atomic(const atomic&) = delete;
125 atomic& operator=(const atomic&) = delete;
126 atomic& operator=(const atomic&) volatile = delete;
Howard Hinnanteee2c142012-04-11 20:14:21 +0000127 T operator=(T) volatile noexcept;
128 T operator=(T) noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +0000129};
130
131template <>
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000132struct atomic<integral>
Howard Hinnant71be7292010-09-27 21:17:38 +0000133{
JF Bastienfdb42c22016-03-25 15:48:21 +0000134 static constexpr bool is_always_lock_free;
Howard Hinnanteee2c142012-04-11 20:14:21 +0000135 bool is_lock_free() const volatile noexcept;
136 bool is_lock_free() const noexcept;
137 void store(integral desr, memory_order m = memory_order_seq_cst) volatile noexcept;
138 void store(integral desr, memory_order m = memory_order_seq_cst) noexcept;
139 integral load(memory_order m = memory_order_seq_cst) const volatile noexcept;
140 integral load(memory_order m = memory_order_seq_cst) const noexcept;
141 operator integral() const volatile noexcept;
142 operator integral() const noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000143 integral exchange(integral desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000144 memory_order m = memory_order_seq_cst) volatile noexcept;
145 integral exchange(integral desr, memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000146 bool compare_exchange_weak(integral& expc, integral desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000147 memory_order s, memory_order f) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000148 bool compare_exchange_weak(integral& expc, integral desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000149 memory_order s, memory_order f) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000150 bool compare_exchange_strong(integral& expc, integral desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000151 memory_order s, memory_order f) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000152 bool compare_exchange_strong(integral& expc, integral desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000153 memory_order s, memory_order f) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000154 bool compare_exchange_weak(integral& expc, integral desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000155 memory_order m = memory_order_seq_cst) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000156 bool compare_exchange_weak(integral& expc, integral desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000157 memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000158 bool compare_exchange_strong(integral& expc, integral desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000159 memory_order m = memory_order_seq_cst) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000160 bool compare_exchange_strong(integral& expc, integral desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000161 memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +0000162
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000163 integral
Howard Hinnanteee2c142012-04-11 20:14:21 +0000164 fetch_add(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
165 integral fetch_add(integral op, memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000166 integral
Howard Hinnanteee2c142012-04-11 20:14:21 +0000167 fetch_sub(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
168 integral fetch_sub(integral op, memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000169 integral
Howard Hinnanteee2c142012-04-11 20:14:21 +0000170 fetch_and(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
171 integral fetch_and(integral op, memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000172 integral
Howard Hinnanteee2c142012-04-11 20:14:21 +0000173 fetch_or(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
174 integral fetch_or(integral op, memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000175 integral
Howard Hinnanteee2c142012-04-11 20:14:21 +0000176 fetch_xor(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
177 integral fetch_xor(integral op, memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +0000178
Howard Hinnanteee2c142012-04-11 20:14:21 +0000179 atomic() noexcept = default;
180 constexpr atomic(integral desr) noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +0000181 atomic(const atomic&) = delete;
182 atomic& operator=(const atomic&) = delete;
183 atomic& operator=(const atomic&) volatile = delete;
Howard Hinnanteee2c142012-04-11 20:14:21 +0000184 integral operator=(integral desr) volatile noexcept;
185 integral operator=(integral desr) noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +0000186
Howard Hinnanteee2c142012-04-11 20:14:21 +0000187 integral operator++(int) volatile noexcept;
188 integral operator++(int) noexcept;
189 integral operator--(int) volatile noexcept;
190 integral operator--(int) noexcept;
191 integral operator++() volatile noexcept;
192 integral operator++() noexcept;
193 integral operator--() volatile noexcept;
194 integral operator--() noexcept;
195 integral operator+=(integral op) volatile noexcept;
196 integral operator+=(integral op) noexcept;
197 integral operator-=(integral op) volatile noexcept;
198 integral operator-=(integral op) noexcept;
199 integral operator&=(integral op) volatile noexcept;
200 integral operator&=(integral op) noexcept;
201 integral operator|=(integral op) volatile noexcept;
202 integral operator|=(integral op) noexcept;
203 integral operator^=(integral op) volatile noexcept;
204 integral operator^=(integral op) noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +0000205};
206
207template <class T>
208struct atomic<T*>
Howard Hinnant71be7292010-09-27 21:17:38 +0000209{
JF Bastienfdb42c22016-03-25 15:48:21 +0000210 static constexpr bool is_always_lock_free;
Howard Hinnanteee2c142012-04-11 20:14:21 +0000211 bool is_lock_free() const volatile noexcept;
212 bool is_lock_free() const noexcept;
213 void store(T* desr, memory_order m = memory_order_seq_cst) volatile noexcept;
214 void store(T* desr, memory_order m = memory_order_seq_cst) noexcept;
215 T* load(memory_order m = memory_order_seq_cst) const volatile noexcept;
216 T* load(memory_order m = memory_order_seq_cst) const noexcept;
217 operator T*() const volatile noexcept;
218 operator T*() const noexcept;
219 T* exchange(T* desr, memory_order m = memory_order_seq_cst) volatile noexcept;
220 T* exchange(T* desr, memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000221 bool compare_exchange_weak(T*& expc, T* desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000222 memory_order s, memory_order f) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000223 bool compare_exchange_weak(T*& expc, T* desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000224 memory_order s, memory_order f) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000225 bool compare_exchange_strong(T*& expc, T* desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000226 memory_order s, memory_order f) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000227 bool compare_exchange_strong(T*& expc, T* desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000228 memory_order s, memory_order f) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000229 bool compare_exchange_weak(T*& expc, T* desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000230 memory_order m = memory_order_seq_cst) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000231 bool compare_exchange_weak(T*& expc, T* desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000232 memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000233 bool compare_exchange_strong(T*& expc, T* desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000234 memory_order m = memory_order_seq_cst) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000235 bool compare_exchange_strong(T*& expc, T* desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000236 memory_order m = memory_order_seq_cst) noexcept;
237 T* fetch_add(ptrdiff_t op, memory_order m = memory_order_seq_cst) volatile noexcept;
238 T* fetch_add(ptrdiff_t op, memory_order m = memory_order_seq_cst) noexcept;
239 T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst) volatile noexcept;
240 T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000241
Howard Hinnanteee2c142012-04-11 20:14:21 +0000242 atomic() noexcept = default;
243 constexpr atomic(T* desr) noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +0000244 atomic(const atomic&) = delete;
245 atomic& operator=(const atomic&) = delete;
246 atomic& operator=(const atomic&) volatile = delete;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000247
Howard Hinnanteee2c142012-04-11 20:14:21 +0000248 T* operator=(T*) volatile noexcept;
249 T* operator=(T*) noexcept;
250 T* operator++(int) volatile noexcept;
251 T* operator++(int) noexcept;
252 T* operator--(int) volatile noexcept;
253 T* operator--(int) noexcept;
254 T* operator++() volatile noexcept;
255 T* operator++() noexcept;
256 T* operator--() volatile noexcept;
257 T* operator--() noexcept;
258 T* operator+=(ptrdiff_t op) volatile noexcept;
259 T* operator+=(ptrdiff_t op) noexcept;
260 T* operator-=(ptrdiff_t op) volatile noexcept;
261 T* operator-=(ptrdiff_t op) noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +0000262};
263
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000264
265template <class T>
266 bool
Howard Hinnanteee2c142012-04-11 20:14:21 +0000267 atomic_is_lock_free(const volatile atomic<T>* obj) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000268
269template <class T>
270 bool
Howard Hinnanteee2c142012-04-11 20:14:21 +0000271 atomic_is_lock_free(const atomic<T>* obj) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000272
273template <class T>
274 void
Howard Hinnanteee2c142012-04-11 20:14:21 +0000275 atomic_init(volatile atomic<T>* obj, T desr) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000276
277template <class T>
278 void
Howard Hinnanteee2c142012-04-11 20:14:21 +0000279 atomic_init(atomic<T>* obj, T desr) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000280
281template <class T>
282 void
Howard Hinnanteee2c142012-04-11 20:14:21 +0000283 atomic_store(volatile atomic<T>* obj, T desr) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000284
285template <class T>
286 void
Howard Hinnanteee2c142012-04-11 20:14:21 +0000287 atomic_store(atomic<T>* obj, T desr) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000288
289template <class T>
290 void
Howard Hinnanteee2c142012-04-11 20:14:21 +0000291 atomic_store_explicit(volatile atomic<T>* obj, T desr, memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000292
293template <class T>
294 void
Howard Hinnanteee2c142012-04-11 20:14:21 +0000295 atomic_store_explicit(atomic<T>* obj, T desr, memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000296
297template <class T>
298 T
Howard Hinnanteee2c142012-04-11 20:14:21 +0000299 atomic_load(const volatile atomic<T>* obj) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000300
301template <class T>
302 T
Howard Hinnanteee2c142012-04-11 20:14:21 +0000303 atomic_load(const atomic<T>* obj) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000304
305template <class T>
306 T
Howard Hinnanteee2c142012-04-11 20:14:21 +0000307 atomic_load_explicit(const volatile atomic<T>* obj, memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000308
309template <class T>
310 T
Howard Hinnanteee2c142012-04-11 20:14:21 +0000311 atomic_load_explicit(const atomic<T>* obj, memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000312
313template <class T>
314 T
Howard Hinnanteee2c142012-04-11 20:14:21 +0000315 atomic_exchange(volatile atomic<T>* obj, T desr) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000316
317template <class T>
318 T
Howard Hinnanteee2c142012-04-11 20:14:21 +0000319 atomic_exchange(atomic<T>* obj, T desr) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000320
321template <class T>
322 T
Howard Hinnanteee2c142012-04-11 20:14:21 +0000323 atomic_exchange_explicit(volatile atomic<T>* obj, T desr, memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000324
325template <class T>
326 T
Howard Hinnanteee2c142012-04-11 20:14:21 +0000327 atomic_exchange_explicit(atomic<T>* obj, T desr, memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000328
329template <class T>
330 bool
Howard Hinnanteee2c142012-04-11 20:14:21 +0000331 atomic_compare_exchange_weak(volatile atomic<T>* obj, T* expc, T desr) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000332
333template <class T>
334 bool
Howard Hinnanteee2c142012-04-11 20:14:21 +0000335 atomic_compare_exchange_weak(atomic<T>* obj, T* expc, T desr) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000336
337template <class T>
338 bool
Howard Hinnanteee2c142012-04-11 20:14:21 +0000339 atomic_compare_exchange_strong(volatile atomic<T>* obj, T* expc, T desr) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000340
341template <class T>
342 bool
Howard Hinnanteee2c142012-04-11 20:14:21 +0000343 atomic_compare_exchange_strong(atomic<T>* obj, T* expc, T desr) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000344
345template <class T>
346 bool
347 atomic_compare_exchange_weak_explicit(volatile atomic<T>* obj, T* expc,
348 T desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000349 memory_order s, memory_order f) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000350
351template <class T>
352 bool
353 atomic_compare_exchange_weak_explicit(atomic<T>* obj, T* expc, T desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000354 memory_order s, memory_order f) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000355
356template <class T>
357 bool
358 atomic_compare_exchange_strong_explicit(volatile atomic<T>* obj,
359 T* expc, T desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000360 memory_order s, memory_order f) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000361
362template <class T>
363 bool
364 atomic_compare_exchange_strong_explicit(atomic<T>* obj, T* expc,
365 T desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000366 memory_order s, memory_order f) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000367
368template <class Integral>
369 Integral
Howard Hinnanteee2c142012-04-11 20:14:21 +0000370 atomic_fetch_add(volatile atomic<Integral>* obj, Integral op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000371
372template <class Integral>
373 Integral
Howard Hinnanteee2c142012-04-11 20:14:21 +0000374 atomic_fetch_add(atomic<Integral>* obj, Integral op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000375
376template <class Integral>
377 Integral
378 atomic_fetch_add_explicit(volatile atomic<Integral>* obj, Integral op,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000379 memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000380template <class Integral>
381 Integral
382 atomic_fetch_add_explicit(atomic<Integral>* obj, Integral op,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000383 memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000384template <class Integral>
385 Integral
Howard Hinnanteee2c142012-04-11 20:14:21 +0000386 atomic_fetch_sub(volatile atomic<Integral>* obj, Integral op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000387
388template <class Integral>
389 Integral
Howard Hinnanteee2c142012-04-11 20:14:21 +0000390 atomic_fetch_sub(atomic<Integral>* obj, Integral op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000391
392template <class Integral>
393 Integral
394 atomic_fetch_sub_explicit(volatile atomic<Integral>* obj, Integral op,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000395 memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000396template <class Integral>
397 Integral
398 atomic_fetch_sub_explicit(atomic<Integral>* obj, Integral op,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000399 memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000400template <class Integral>
401 Integral
Howard Hinnanteee2c142012-04-11 20:14:21 +0000402 atomic_fetch_and(volatile atomic<Integral>* obj, Integral op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000403
404template <class Integral>
405 Integral
Howard Hinnanteee2c142012-04-11 20:14:21 +0000406 atomic_fetch_and(atomic<Integral>* obj, Integral op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000407
408template <class Integral>
409 Integral
410 atomic_fetch_and_explicit(volatile atomic<Integral>* obj, Integral op,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000411 memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000412template <class Integral>
413 Integral
414 atomic_fetch_and_explicit(atomic<Integral>* obj, Integral op,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000415 memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000416template <class Integral>
417 Integral
Howard Hinnanteee2c142012-04-11 20:14:21 +0000418 atomic_fetch_or(volatile atomic<Integral>* obj, Integral op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000419
420template <class Integral>
421 Integral
Howard Hinnanteee2c142012-04-11 20:14:21 +0000422 atomic_fetch_or(atomic<Integral>* obj, Integral op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000423
424template <class Integral>
425 Integral
426 atomic_fetch_or_explicit(volatile atomic<Integral>* obj, Integral op,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000427 memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000428template <class Integral>
429 Integral
430 atomic_fetch_or_explicit(atomic<Integral>* obj, Integral op,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000431 memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000432template <class Integral>
433 Integral
Howard Hinnanteee2c142012-04-11 20:14:21 +0000434 atomic_fetch_xor(volatile atomic<Integral>* obj, Integral op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000435
436template <class Integral>
437 Integral
Howard Hinnanteee2c142012-04-11 20:14:21 +0000438 atomic_fetch_xor(atomic<Integral>* obj, Integral op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000439
440template <class Integral>
441 Integral
442 atomic_fetch_xor_explicit(volatile atomic<Integral>* obj, Integral op,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000443 memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000444template <class Integral>
445 Integral
446 atomic_fetch_xor_explicit(atomic<Integral>* obj, Integral op,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000447 memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000448
449template <class T>
450 T*
Howard Hinnanteee2c142012-04-11 20:14:21 +0000451 atomic_fetch_add(volatile atomic<T*>* obj, ptrdiff_t op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000452
453template <class T>
454 T*
Howard Hinnanteee2c142012-04-11 20:14:21 +0000455 atomic_fetch_add(atomic<T*>* obj, ptrdiff_t op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000456
457template <class T>
458 T*
459 atomic_fetch_add_explicit(volatile atomic<T*>* obj, ptrdiff_t op,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000460 memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000461template <class T>
462 T*
Howard Hinnanteee2c142012-04-11 20:14:21 +0000463 atomic_fetch_add_explicit(atomic<T*>* obj, ptrdiff_t op, memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000464
465template <class T>
466 T*
Howard Hinnanteee2c142012-04-11 20:14:21 +0000467 atomic_fetch_sub(volatile atomic<T*>* obj, ptrdiff_t op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000468
469template <class T>
470 T*
Howard Hinnanteee2c142012-04-11 20:14:21 +0000471 atomic_fetch_sub(atomic<T*>* obj, ptrdiff_t op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000472
473template <class T>
474 T*
475 atomic_fetch_sub_explicit(volatile atomic<T*>* obj, ptrdiff_t op,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000476 memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000477template <class T>
478 T*
Howard Hinnanteee2c142012-04-11 20:14:21 +0000479 atomic_fetch_sub_explicit(atomic<T*>* obj, ptrdiff_t op, memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000480
481// Atomics for standard typedef types
482
Howard Hinnantf0af8d92013-01-04 18:58:50 +0000483typedef atomic<bool> atomic_bool;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000484typedef atomic<char> atomic_char;
485typedef atomic<signed char> atomic_schar;
486typedef atomic<unsigned char> atomic_uchar;
487typedef atomic<short> atomic_short;
488typedef atomic<unsigned short> atomic_ushort;
489typedef atomic<int> atomic_int;
490typedef atomic<unsigned int> atomic_uint;
491typedef atomic<long> atomic_long;
492typedef atomic<unsigned long> atomic_ulong;
493typedef atomic<long long> atomic_llong;
494typedef atomic<unsigned long long> atomic_ullong;
495typedef atomic<char16_t> atomic_char16_t;
496typedef atomic<char32_t> atomic_char32_t;
497typedef atomic<wchar_t> atomic_wchar_t;
498
499typedef atomic<int_least8_t> atomic_int_least8_t;
500typedef atomic<uint_least8_t> atomic_uint_least8_t;
501typedef atomic<int_least16_t> atomic_int_least16_t;
502typedef atomic<uint_least16_t> atomic_uint_least16_t;
503typedef atomic<int_least32_t> atomic_int_least32_t;
504typedef atomic<uint_least32_t> atomic_uint_least32_t;
505typedef atomic<int_least64_t> atomic_int_least64_t;
506typedef atomic<uint_least64_t> atomic_uint_least64_t;
507
508typedef atomic<int_fast8_t> atomic_int_fast8_t;
509typedef atomic<uint_fast8_t> atomic_uint_fast8_t;
510typedef atomic<int_fast16_t> atomic_int_fast16_t;
511typedef atomic<uint_fast16_t> atomic_uint_fast16_t;
512typedef atomic<int_fast32_t> atomic_int_fast32_t;
513typedef atomic<uint_fast32_t> atomic_uint_fast32_t;
514typedef atomic<int_fast64_t> atomic_int_fast64_t;
515typedef atomic<uint_fast64_t> atomic_uint_fast64_t;
516
Marshall Clowf710afc2016-06-30 15:28:38 +0000517typedef atomic<int8_t> atomic_int8_t;
518typedef atomic<uint8_t> atomic_uint8_t;
519typedef atomic<int16_t> atomic_int16_t;
520typedef atomic<uint16_t> atomic_uint16_t;
521typedef atomic<int32_t> atomic_int32_t;
522typedef atomic<uint32_t> atomic_uint32_t;
523typedef atomic<int64_t> atomic_int64_t;
524typedef atomic<uint64_t> atomic_uint64_t;
525
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000526typedef atomic<intptr_t> atomic_intptr_t;
527typedef atomic<uintptr_t> atomic_uintptr_t;
528typedef atomic<size_t> atomic_size_t;
529typedef atomic<ptrdiff_t> atomic_ptrdiff_t;
530typedef atomic<intmax_t> atomic_intmax_t;
531typedef atomic<uintmax_t> atomic_uintmax_t;
532
Howard Hinnant71be7292010-09-27 21:17:38 +0000533// fences
534
Howard Hinnanteee2c142012-04-11 20:14:21 +0000535void atomic_thread_fence(memory_order m) noexcept;
536void atomic_signal_fence(memory_order m) noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +0000537
538} // std
539
540*/
541
542#include <__config>
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000543#include <cstddef>
544#include <cstdint>
545#include <type_traits>
Marshall Clow0a1e7502018-09-12 19:41:40 +0000546#include <version>
Howard Hinnant71be7292010-09-27 21:17:38 +0000547
Howard Hinnantaaaa52b2011-10-17 20:05:10 +0000548#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
Howard Hinnant71be7292010-09-27 21:17:38 +0000549#pragma GCC system_header
Howard Hinnantaaaa52b2011-10-17 20:05:10 +0000550#endif
Howard Hinnant71be7292010-09-27 21:17:38 +0000551
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000552#ifdef _LIBCPP_HAS_NO_THREADS
Louis Dionnea1ae0032019-03-04 15:26:27 +0000553# error <atomic> is not supported on this single threaded system
Eric Fiselier8020b6c2015-08-19 17:21:46 +0000554#endif
Louis Dionnea1ae0032019-03-04 15:26:27 +0000555#ifdef _LIBCPP_HAS_NO_ATOMIC_HEADER
556# error <atomic> is not implemented
Eric Fiselier8020b6c2015-08-19 17:21:46 +0000557#endif
Volodymyr Sapsaif3ed1fd2018-05-15 22:38:31 +0000558#ifdef kill_dependency
Louis Dionnea1ae0032019-03-04 15:26:27 +0000559# error C++ standard library is incompatible with <stdatomic.h>
Volodymyr Sapsaif3ed1fd2018-05-15 22:38:31 +0000560#endif
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000561
Eric Fiselierb5ab51d2017-01-13 23:45:39 +0000562#define _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) \
563 _LIBCPP_DIAGNOSE_WARNING(__m == memory_order_consume || \
564 __m == memory_order_acquire || \
565 __m == memory_order_acq_rel, \
566 "memory order argument to atomic operation is invalid")
567
568#define _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) \
569 _LIBCPP_DIAGNOSE_WARNING(__m == memory_order_release || \
570 __m == memory_order_acq_rel, \
571 "memory order argument to atomic operation is invalid")
572
573#define _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__m, __f) \
574 _LIBCPP_DIAGNOSE_WARNING(__f == memory_order_release || \
575 __f == memory_order_acq_rel, \
576 "memory order argument to atomic operation is invalid")
577
Howard Hinnant71be7292010-09-27 21:17:38 +0000578_LIBCPP_BEGIN_NAMESPACE_STD
579
Howard Hinnantdca6e712010-09-28 17:13:38 +0000580typedef enum memory_order
581{
582 memory_order_relaxed, memory_order_consume, memory_order_acquire,
583 memory_order_release, memory_order_acq_rel, memory_order_seq_cst
584} memory_order;
585
Louis Dionnea1ae0032019-03-04 15:26:27 +0000586#if defined(_LIBCPP_HAS_GCC_ATOMIC_IMP) || \
587 defined(_LIBCPP_ATOMIC_ONLY_USE_BUILTINS)
Eric Fiselier88f07122015-12-15 00:32:21 +0000588
Louis Dionnea1ae0032019-03-04 15:26:27 +0000589// [atomics.types.generic]p1 guarantees _Tp is trivially copyable. Because
590// the default operator= in an object is not volatile, a byte-by-byte copy
591// is required.
592template <typename _Tp, typename _Tv> _LIBCPP_INLINE_VISIBILITY
593typename enable_if<is_assignable<_Tp&, _Tv>::value>::type
594__cxx_atomic_assign_volatile(_Tp& __a_value, _Tv const& __val) {
595 __a_value = __val;
596}
597template <typename _Tp, typename _Tv> _LIBCPP_INLINE_VISIBILITY
598typename enable_if<is_assignable<_Tp&, _Tv>::value>::type
599__cxx_atomic_assign_volatile(_Tp volatile& __a_value, _Tv volatile const& __val) {
600 volatile char* __to = reinterpret_cast<volatile char*>(&__a_value);
601 volatile char* __end = __to + sizeof(_Tp);
602 volatile const char* __from = reinterpret_cast<volatile const char*>(&__val);
603 while (__to != __end)
604 *__to++ = *__from++;
605}
606
Eric Fiselier88f07122015-12-15 00:32:21 +0000607#endif
608
Louis Dionnea1ae0032019-03-04 15:26:27 +0000609#if defined(_LIBCPP_HAS_GCC_ATOMIC_IMP)
610
611template <typename _Tp>
612struct __cxx_atomic_base_impl {
613
Eric Fiselier684aaca2015-10-14 08:36:22 +0000614 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier07b2b552016-11-18 06:42:17 +0000615#ifndef _LIBCPP_CXX03_LANG
Louis Dionnea1ae0032019-03-04 15:26:27 +0000616 __cxx_atomic_base_impl() _NOEXCEPT = default;
Eric Fiselier684aaca2015-10-14 08:36:22 +0000617#else
Louis Dionnea1ae0032019-03-04 15:26:27 +0000618 __cxx_atomic_base_impl() _NOEXCEPT : __a_value() {}
Eric Fiselier07b2b552016-11-18 06:42:17 +0000619#endif // _LIBCPP_CXX03_LANG
Louis Dionnea1ae0032019-03-04 15:26:27 +0000620 _LIBCPP_CONSTEXPR explicit __cxx_atomic_base_impl(_Tp value) _NOEXCEPT
Eric Fiselier719e0442015-07-14 17:50:27 +0000621 : __a_value(value) {}
Marshall Clow290eb3f2015-01-11 06:15:59 +0000622 _Tp __a_value;
Dan Albert7b65ace2014-08-09 23:51:51 +0000623};
Dan Albert7b65ace2014-08-09 23:51:51 +0000624
Louis Dionnea1ae0032019-03-04 15:26:27 +0000625_LIBCPP_INLINE_VISIBILITY inline _LIBCPP_CONSTEXPR int __to_gcc_order(memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000626 // Avoid switch statement to make this a constexpr.
627 return __order == memory_order_relaxed ? __ATOMIC_RELAXED:
628 (__order == memory_order_acquire ? __ATOMIC_ACQUIRE:
629 (__order == memory_order_release ? __ATOMIC_RELEASE:
630 (__order == memory_order_seq_cst ? __ATOMIC_SEQ_CST:
631 (__order == memory_order_acq_rel ? __ATOMIC_ACQ_REL:
632 __ATOMIC_CONSUME))));
633}
634
Louis Dionnea1ae0032019-03-04 15:26:27 +0000635_LIBCPP_INLINE_VISIBILITY inline _LIBCPP_CONSTEXPR int __to_gcc_failure_order(memory_order __order) {
Dan Albert48815f22015-01-06 18:39:37 +0000636 // Avoid switch statement to make this a constexpr.
637 return __order == memory_order_relaxed ? __ATOMIC_RELAXED:
638 (__order == memory_order_acquire ? __ATOMIC_ACQUIRE:
639 (__order == memory_order_release ? __ATOMIC_RELAXED:
640 (__order == memory_order_seq_cst ? __ATOMIC_SEQ_CST:
641 (__order == memory_order_acq_rel ? __ATOMIC_ACQUIRE:
642 __ATOMIC_CONSUME))));
643}
644
Louis Dionnea1ae0032019-03-04 15:26:27 +0000645template <typename _Tp>
646_LIBCPP_INLINE_VISIBILITY
647void __cxx_atomic_init(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __val) {
648 __cxx_atomic_assign_volatile(__a->__a_value, __val);
649}
Dan Albert7b65ace2014-08-09 23:51:51 +0000650
651template <typename _Tp>
Louis Dionnea1ae0032019-03-04 15:26:27 +0000652_LIBCPP_INLINE_VISIBILITY
653void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp>* __a, _Tp __val) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000654 __a->__a_value = __val;
655}
656
Louis Dionnea1ae0032019-03-04 15:26:27 +0000657_LIBCPP_INLINE_VISIBILITY inline
658void __cxx_atomic_thread_fence(memory_order __order) {
659 __atomic_thread_fence(__to_gcc_order(__order));
660}
661
662_LIBCPP_INLINE_VISIBILITY inline
663void __cxx_atomic_signal_fence(memory_order __order) {
664 __atomic_signal_fence(__to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000665}
666
667template <typename _Tp>
Louis Dionnea1ae0032019-03-04 15:26:27 +0000668_LIBCPP_INLINE_VISIBILITY
669void __cxx_atomic_store(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __val,
670 memory_order __order) {
Dan Albert48815f22015-01-06 18:39:37 +0000671 __atomic_store(&__a->__a_value, &__val,
Louis Dionnea1ae0032019-03-04 15:26:27 +0000672 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000673}
674
675template <typename _Tp>
Louis Dionnea1ae0032019-03-04 15:26:27 +0000676_LIBCPP_INLINE_VISIBILITY
677void __cxx_atomic_store(__cxx_atomic_base_impl<_Tp>* __a, _Tp __val,
678 memory_order __order) {
679 __atomic_store(&__a->__a_value, &__val,
680 __to_gcc_order(__order));
681}
682
683template <typename _Tp>
684_LIBCPP_INLINE_VISIBILITY
685_Tp __cxx_atomic_load(const volatile __cxx_atomic_base_impl<_Tp>* __a,
686 memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000687 _Tp __ret;
688 __atomic_load(&__a->__a_value, &__ret,
Louis Dionnea1ae0032019-03-04 15:26:27 +0000689 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000690 return __ret;
691}
692
693template <typename _Tp>
Louis Dionnea1ae0032019-03-04 15:26:27 +0000694_LIBCPP_INLINE_VISIBILITY
695_Tp __cxx_atomic_load(const __cxx_atomic_base_impl<_Tp>* __a, memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000696 _Tp __ret;
697 __atomic_load(&__a->__a_value, &__ret,
Louis Dionnea1ae0032019-03-04 15:26:27 +0000698 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000699 return __ret;
700}
701
702template <typename _Tp>
Louis Dionnea1ae0032019-03-04 15:26:27 +0000703_LIBCPP_INLINE_VISIBILITY
704_Tp __cxx_atomic_exchange(volatile __cxx_atomic_base_impl<_Tp>* __a,
705 _Tp __value, memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000706 _Tp __ret;
707 __atomic_exchange(&__a->__a_value, &__value, &__ret,
Louis Dionnea1ae0032019-03-04 15:26:27 +0000708 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000709 return __ret;
710}
711
712template <typename _Tp>
Louis Dionnea1ae0032019-03-04 15:26:27 +0000713_LIBCPP_INLINE_VISIBILITY
714_Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp>* __a, _Tp __value,
715 memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000716 _Tp __ret;
717 __atomic_exchange(&__a->__a_value, &__value, &__ret,
Louis Dionnea1ae0032019-03-04 15:26:27 +0000718 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000719 return __ret;
720}
721
722template <typename _Tp>
Louis Dionnea1ae0032019-03-04 15:26:27 +0000723_LIBCPP_INLINE_VISIBILITY
724bool __cxx_atomic_compare_exchange_strong(
725 volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value,
JF Bastien6e412d92018-05-26 19:44:45 +0000726 memory_order __success, memory_order __failure) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000727 return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
728 false,
Louis Dionnea1ae0032019-03-04 15:26:27 +0000729 __to_gcc_order(__success),
730 __to_gcc_failure_order(__failure));
Dan Albert7b65ace2014-08-09 23:51:51 +0000731}
732
733template <typename _Tp>
Louis Dionnea1ae0032019-03-04 15:26:27 +0000734_LIBCPP_INLINE_VISIBILITY
735bool __cxx_atomic_compare_exchange_strong(
736 __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success,
JF Bastien6e412d92018-05-26 19:44:45 +0000737 memory_order __failure) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000738 return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
739 false,
Louis Dionnea1ae0032019-03-04 15:26:27 +0000740 __to_gcc_order(__success),
741 __to_gcc_failure_order(__failure));
Dan Albert7b65ace2014-08-09 23:51:51 +0000742}
743
744template <typename _Tp>
Louis Dionnea1ae0032019-03-04 15:26:27 +0000745_LIBCPP_INLINE_VISIBILITY
746bool __cxx_atomic_compare_exchange_weak(
747 volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value,
JF Bastien6e412d92018-05-26 19:44:45 +0000748 memory_order __success, memory_order __failure) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000749 return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
750 true,
Louis Dionnea1ae0032019-03-04 15:26:27 +0000751 __to_gcc_order(__success),
752 __to_gcc_failure_order(__failure));
Dan Albert7b65ace2014-08-09 23:51:51 +0000753}
754
755template <typename _Tp>
Louis Dionnea1ae0032019-03-04 15:26:27 +0000756_LIBCPP_INLINE_VISIBILITY
757bool __cxx_atomic_compare_exchange_weak(
758 __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success,
JF Bastien6e412d92018-05-26 19:44:45 +0000759 memory_order __failure) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000760 return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
761 true,
Louis Dionnea1ae0032019-03-04 15:26:27 +0000762 __to_gcc_order(__success),
763 __to_gcc_failure_order(__failure));
Dan Albert7b65ace2014-08-09 23:51:51 +0000764}
765
766template <typename _Tp>
767struct __skip_amt { enum {value = 1}; };
768
769template <typename _Tp>
770struct __skip_amt<_Tp*> { enum {value = sizeof(_Tp)}; };
771
772// FIXME: Haven't figured out what the spec says about using arrays with
773// atomic_fetch_add. Force a failure rather than creating bad behavior.
774template <typename _Tp>
775struct __skip_amt<_Tp[]> { };
776template <typename _Tp, int n>
777struct __skip_amt<_Tp[n]> { };
778
779template <typename _Tp, typename _Td>
Louis Dionnea1ae0032019-03-04 15:26:27 +0000780_LIBCPP_INLINE_VISIBILITY
781_Tp __cxx_atomic_fetch_add(volatile __cxx_atomic_base_impl<_Tp>* __a,
782 _Td __delta, memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000783 return __atomic_fetch_add(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
Louis Dionnea1ae0032019-03-04 15:26:27 +0000784 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000785}
786
787template <typename _Tp, typename _Td>
Louis Dionnea1ae0032019-03-04 15:26:27 +0000788_LIBCPP_INLINE_VISIBILITY
789_Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp>* __a, _Td __delta,
790 memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000791 return __atomic_fetch_add(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
Louis Dionnea1ae0032019-03-04 15:26:27 +0000792 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000793}
794
795template <typename _Tp, typename _Td>
Louis Dionnea1ae0032019-03-04 15:26:27 +0000796_LIBCPP_INLINE_VISIBILITY
797_Tp __cxx_atomic_fetch_sub(volatile __cxx_atomic_base_impl<_Tp>* __a,
798 _Td __delta, memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000799 return __atomic_fetch_sub(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
Louis Dionnea1ae0032019-03-04 15:26:27 +0000800 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000801}
802
803template <typename _Tp, typename _Td>
Louis Dionnea1ae0032019-03-04 15:26:27 +0000804_LIBCPP_INLINE_VISIBILITY
805_Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp>* __a, _Td __delta,
806 memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000807 return __atomic_fetch_sub(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
Louis Dionnea1ae0032019-03-04 15:26:27 +0000808 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000809}
810
811template <typename _Tp>
Louis Dionnea1ae0032019-03-04 15:26:27 +0000812_LIBCPP_INLINE_VISIBILITY
813_Tp __cxx_atomic_fetch_and(volatile __cxx_atomic_base_impl<_Tp>* __a,
814 _Tp __pattern, memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000815 return __atomic_fetch_and(&__a->__a_value, __pattern,
Louis Dionnea1ae0032019-03-04 15:26:27 +0000816 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000817}
818
819template <typename _Tp>
Louis Dionnea1ae0032019-03-04 15:26:27 +0000820_LIBCPP_INLINE_VISIBILITY
821_Tp __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp>* __a,
822 _Tp __pattern, memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000823 return __atomic_fetch_and(&__a->__a_value, __pattern,
Louis Dionnea1ae0032019-03-04 15:26:27 +0000824 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000825}
826
827template <typename _Tp>
Louis Dionnea1ae0032019-03-04 15:26:27 +0000828_LIBCPP_INLINE_VISIBILITY
829_Tp __cxx_atomic_fetch_or(volatile __cxx_atomic_base_impl<_Tp>* __a,
830 _Tp __pattern, memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000831 return __atomic_fetch_or(&__a->__a_value, __pattern,
Louis Dionnea1ae0032019-03-04 15:26:27 +0000832 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000833}
834
835template <typename _Tp>
Louis Dionnea1ae0032019-03-04 15:26:27 +0000836_LIBCPP_INLINE_VISIBILITY
837_Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern,
838 memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000839 return __atomic_fetch_or(&__a->__a_value, __pattern,
Louis Dionnea1ae0032019-03-04 15:26:27 +0000840 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000841}
842
843template <typename _Tp>
Louis Dionnea1ae0032019-03-04 15:26:27 +0000844_LIBCPP_INLINE_VISIBILITY
845_Tp __cxx_atomic_fetch_xor(volatile __cxx_atomic_base_impl<_Tp>* __a,
846 _Tp __pattern, memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000847 return __atomic_fetch_xor(&__a->__a_value, __pattern,
Louis Dionnea1ae0032019-03-04 15:26:27 +0000848 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000849}
850
851template <typename _Tp>
Louis Dionnea1ae0032019-03-04 15:26:27 +0000852_LIBCPP_INLINE_VISIBILITY
853_Tp __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern,
854 memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000855 return __atomic_fetch_xor(&__a->__a_value, __pattern,
Louis Dionnea1ae0032019-03-04 15:26:27 +0000856 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000857}
Louis Dionnea1ae0032019-03-04 15:26:27 +0000858
859#define __cxx_atomic_is_lock_free(__s) __atomic_is_lock_free(__s, 0)
860
861#elif defined(_LIBCPP_HAS_C_ATOMIC_IMP)
862
863template <typename _Tp>
864struct __cxx_atomic_base_impl {
865
866 _LIBCPP_INLINE_VISIBILITY
867#ifndef _LIBCPP_CXX03_LANG
868 __cxx_atomic_base_impl() _NOEXCEPT = default;
869#else
870 __cxx_atomic_base_impl() _NOEXCEPT : __a_value() {}
871#endif // _LIBCPP_CXX03_LANG
872 _LIBCPP_CONSTEXPR explicit __cxx_atomic_base_impl(_Tp value) _NOEXCEPT
873 : __a_value(value) {}
874 _Atomic(_Tp) __a_value;
875};
876
877#define __cxx_atomic_is_lock_free(__s) __c11_atomic_is_lock_free(__s)
878
879_LIBCPP_INLINE_VISIBILITY inline
880void __cxx_atomic_thread_fence(int __order) {
881 __c11_atomic_thread_fence(__order);
882}
883
884_LIBCPP_INLINE_VISIBILITY inline
885void __cxx_atomic_signal_fence(int __order) {
886 __c11_atomic_signal_fence(__order);
887}
888
889template<class _Tp>
890_LIBCPP_INLINE_VISIBILITY
891void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __val) {
892 __c11_atomic_init(&__a->__a_value, __val);
893}
894template<class _Tp>
895_LIBCPP_INLINE_VISIBILITY
896void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp> * __a, _Tp __val) {
897 __c11_atomic_init(&__a->__a_value, __val);
898}
899
900template<class _Tp>
901_LIBCPP_INLINE_VISIBILITY
902void __cxx_atomic_store(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __val, int __order) {
903 __c11_atomic_store(&__a->__a_value, __val, __order);
904}
905template<class _Tp>
906_LIBCPP_INLINE_VISIBILITY
907void __cxx_atomic_store(__cxx_atomic_base_impl<_Tp> * __a, _Tp __val, int __order) {
908 __c11_atomic_store(&__a->__a_value, __val, __order);
909}
910
911template<class _Tp>
912_LIBCPP_INLINE_VISIBILITY
913_Tp __cxx_atomic_load(__cxx_atomic_base_impl<_Tp> const volatile* __a, int __order) {
914 using __ptr_type = typename remove_const<decltype(__a->__a_value)>::type*;
915 return __c11_atomic_load(const_cast<__ptr_type>(&__a->__a_value), __order);
916}
917template<class _Tp>
918_LIBCPP_INLINE_VISIBILITY
919_Tp __cxx_atomic_load(__cxx_atomic_base_impl<_Tp> const* __a, int __order) {
920 using __ptr_type = typename remove_const<decltype(__a->__a_value)>::type*;
921 return __c11_atomic_load(const_cast<__ptr_type>(&__a->__a_value), __order);
922}
923
924template<class _Tp>
925_LIBCPP_INLINE_VISIBILITY
926_Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __value, int __order) {
927 return __c11_atomic_exchange(&__a->__a_value, __value, __order);
928}
929template<class _Tp>
930_LIBCPP_INLINE_VISIBILITY
931_Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp> * __a, _Tp __value, int __order) {
932 return __c11_atomic_exchange(&__a->__a_value, __value, __order);
933}
934
935template<class _Tp>
936_LIBCPP_INLINE_VISIBILITY
937bool __cxx_atomic_compare_exchange_strong(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp* __expected, _Tp __value, int __success, int __failure) {
938 return __c11_atomic_compare_exchange_strong(&__a->__a_value, __expected, __value, __success, __failure);
939}
940template<class _Tp>
941_LIBCPP_INLINE_VISIBILITY
942bool __cxx_atomic_compare_exchange_strong(__cxx_atomic_base_impl<_Tp> * __a, _Tp* __expected, _Tp __value, int __success, int __failure) {
943 return __c11_atomic_compare_exchange_strong(&__a->__a_value, __expected, __value, __success, __failure);
944}
945
946template<class _Tp>
947_LIBCPP_INLINE_VISIBILITY
948bool __cxx_atomic_compare_exchange_weak(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp* __expected, _Tp __value, int __success, int __failure) {
949 return __c11_atomic_compare_exchange_weak(&__a->__a_value, __expected, __value, __success, __failure);
950}
951template<class _Tp>
952_LIBCPP_INLINE_VISIBILITY
953bool __cxx_atomic_compare_exchange_weak(__cxx_atomic_base_impl<_Tp> * __a, _Tp* __expected, _Tp __value, int __success, int __failure) {
954 return __c11_atomic_compare_exchange_weak(&__a->__a_value, __expected, __value, __success, __failure);
955}
956
957template<class _Tp>
958_LIBCPP_INLINE_VISIBILITY
959_Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __delta, int __order) {
960 return __c11_atomic_fetch_add(&__a->__a_value, __delta, __order);
961}
962template<class _Tp>
963_LIBCPP_INLINE_VISIBILITY
964_Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp> * __a, _Tp __delta, int __order) {
965 return __c11_atomic_fetch_add(&__a->__a_value, __delta, __order);
966}
967
968template<class _Tp>
969_LIBCPP_INLINE_VISIBILITY
970_Tp* __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp*> volatile* __a, ptrdiff_t __delta, int __order) {
971 return __c11_atomic_fetch_add(&__a->__a_value, __delta, __order);
972}
973template<class _Tp>
974_LIBCPP_INLINE_VISIBILITY
975_Tp* __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp*> * __a, ptrdiff_t __delta, int __order) {
976 return __c11_atomic_fetch_add(&__a->__a_value, __delta, __order);
977}
978
979template<class _Tp>
980_LIBCPP_INLINE_VISIBILITY
981_Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __delta, int __order) {
982 return __c11_atomic_fetch_sub(&__a->__a_value, __delta, __order);
983}
984template<class _Tp>
985_LIBCPP_INLINE_VISIBILITY
986_Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp> * __a, _Tp __delta, int __order) {
987 return __c11_atomic_fetch_sub(&__a->__a_value, __delta, __order);
988}
989template<class _Tp>
990_LIBCPP_INLINE_VISIBILITY
991_Tp* __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp*> volatile* __a, ptrdiff_t __delta, int __order) {
992 return __c11_atomic_fetch_sub(&__a->__a_value, __delta, __order);
993}
994template<class _Tp>
995_LIBCPP_INLINE_VISIBILITY
996_Tp* __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp*> * __a, ptrdiff_t __delta, int __order) {
997 return __c11_atomic_fetch_sub(&__a->__a_value, __delta, __order);
998}
999
1000template<class _Tp>
1001_LIBCPP_INLINE_VISIBILITY
1002_Tp __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, int __order) {
1003 return __c11_atomic_fetch_and(&__a->__a_value, __pattern, __order);
1004}
1005template<class _Tp>
1006_LIBCPP_INLINE_VISIBILITY
1007_Tp __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, int __order) {
1008 return __c11_atomic_fetch_and(&__a->__a_value, __pattern, __order);
1009}
1010
1011template<class _Tp>
1012_LIBCPP_INLINE_VISIBILITY
1013_Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, int __order) {
1014 return __c11_atomic_fetch_or(&__a->__a_value, __pattern, __order);
1015}
1016template<class _Tp>
1017_LIBCPP_INLINE_VISIBILITY
1018_Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, int __order) {
1019 return __c11_atomic_fetch_or(&__a->__a_value, __pattern, __order);
1020}
1021
1022template<class _Tp>
1023_LIBCPP_INLINE_VISIBILITY
1024_Tp __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, int __order) {
1025 return __c11_atomic_fetch_xor(&__a->__a_value, __pattern, __order);
1026}
1027template<class _Tp>
1028_LIBCPP_INLINE_VISIBILITY
1029_Tp __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, int __order) {
1030 return __c11_atomic_fetch_xor(&__a->__a_value, __pattern, __order);
1031}
1032
1033#endif // _LIBCPP_HAS_GCC_ATOMIC_IMP, _LIBCPP_HAS_C_ATOMIC_IMP
Dan Albert7b65ace2014-08-09 23:51:51 +00001034
Howard Hinnantdca6e712010-09-28 17:13:38 +00001035template <class _Tp>
Louis Dionnea1ae0032019-03-04 15:26:27 +00001036_LIBCPP_INLINE_VISIBILITY
1037_Tp kill_dependency(_Tp __y) _NOEXCEPT
Howard Hinnantdca6e712010-09-28 17:13:38 +00001038{
1039 return __y;
1040}
Howard Hinnant71be7292010-09-27 21:17:38 +00001041
Eric Fiselierbed42df2017-04-20 23:22:46 +00001042#if defined(__CLANG_ATOMIC_BOOL_LOCK_FREE)
1043# define ATOMIC_BOOL_LOCK_FREE __CLANG_ATOMIC_BOOL_LOCK_FREE
1044# define ATOMIC_CHAR_LOCK_FREE __CLANG_ATOMIC_CHAR_LOCK_FREE
1045# define ATOMIC_CHAR16_T_LOCK_FREE __CLANG_ATOMIC_CHAR16_T_LOCK_FREE
1046# define ATOMIC_CHAR32_T_LOCK_FREE __CLANG_ATOMIC_CHAR32_T_LOCK_FREE
1047# define ATOMIC_WCHAR_T_LOCK_FREE __CLANG_ATOMIC_WCHAR_T_LOCK_FREE
1048# define ATOMIC_SHORT_LOCK_FREE __CLANG_ATOMIC_SHORT_LOCK_FREE
1049# define ATOMIC_INT_LOCK_FREE __CLANG_ATOMIC_INT_LOCK_FREE
1050# define ATOMIC_LONG_LOCK_FREE __CLANG_ATOMIC_LONG_LOCK_FREE
1051# define ATOMIC_LLONG_LOCK_FREE __CLANG_ATOMIC_LLONG_LOCK_FREE
1052# define ATOMIC_POINTER_LOCK_FREE __CLANG_ATOMIC_POINTER_LOCK_FREE
Louis Dionnea1ae0032019-03-04 15:26:27 +00001053#elif defined(__GCC_ATOMIC_BOOL_LOCK_FREE)
Eric Fiselierbed42df2017-04-20 23:22:46 +00001054# define ATOMIC_BOOL_LOCK_FREE __GCC_ATOMIC_BOOL_LOCK_FREE
1055# define ATOMIC_CHAR_LOCK_FREE __GCC_ATOMIC_CHAR_LOCK_FREE
1056# define ATOMIC_CHAR16_T_LOCK_FREE __GCC_ATOMIC_CHAR16_T_LOCK_FREE
1057# define ATOMIC_CHAR32_T_LOCK_FREE __GCC_ATOMIC_CHAR32_T_LOCK_FREE
1058# define ATOMIC_WCHAR_T_LOCK_FREE __GCC_ATOMIC_WCHAR_T_LOCK_FREE
1059# define ATOMIC_SHORT_LOCK_FREE __GCC_ATOMIC_SHORT_LOCK_FREE
1060# define ATOMIC_INT_LOCK_FREE __GCC_ATOMIC_INT_LOCK_FREE
1061# define ATOMIC_LONG_LOCK_FREE __GCC_ATOMIC_LONG_LOCK_FREE
1062# define ATOMIC_LLONG_LOCK_FREE __GCC_ATOMIC_LLONG_LOCK_FREE
1063# define ATOMIC_POINTER_LOCK_FREE __GCC_ATOMIC_POINTER_LOCK_FREE
1064#endif
JF Bastienfdb42c22016-03-25 15:48:21 +00001065
Louis Dionnea1ae0032019-03-04 15:26:27 +00001066#ifdef _LIBCPP_ATOMIC_ONLY_USE_BUILTINS
1067
1068template<typename _Tp>
1069struct __cxx_atomic_lock_impl {
1070
1071 _LIBCPP_INLINE_VISIBILITY
1072 __cxx_atomic_lock_impl() _NOEXCEPT
1073 : __a_value(), __a_lock(0) {}
1074 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR explicit
1075 __cxx_atomic_lock_impl(_Tp value) _NOEXCEPT
1076 : __a_value(value), __a_lock(0) {}
1077
1078 _Tp __a_value;
1079 mutable __cxx_atomic_base_impl<_LIBCPP_ATOMIC_FLAG_TYPE> __a_lock;
1080
1081 _LIBCPP_INLINE_VISIBILITY void __lock() const volatile {
1082 while(1 == __cxx_atomic_exchange(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(true), memory_order_acquire))
1083 /*spin*/;
1084 }
1085 _LIBCPP_INLINE_VISIBILITY void __lock() const {
1086 while(1 == __cxx_atomic_exchange(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(true), memory_order_acquire))
1087 /*spin*/;
1088 }
1089 _LIBCPP_INLINE_VISIBILITY void __unlock() const volatile {
1090 __cxx_atomic_store(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(false), memory_order_release);
1091 }
1092 _LIBCPP_INLINE_VISIBILITY void __unlock() const {
1093 __cxx_atomic_store(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(false), memory_order_release);
1094 }
1095 _LIBCPP_INLINE_VISIBILITY _Tp __read() const volatile {
1096 __lock();
1097 _Tp __old;
1098 __cxx_atomic_assign_volatile(__old, __a_value);
1099 __unlock();
1100 return __old;
1101 }
1102 _LIBCPP_INLINE_VISIBILITY _Tp __read() const {
1103 __lock();
1104 _Tp __old = __a_value;
1105 __unlock();
1106 return __old;
1107 }
1108};
1109
1110template <typename _Tp>
1111_LIBCPP_INLINE_VISIBILITY
1112void __cxx_atomic_init(volatile __cxx_atomic_lock_impl<_Tp>* __a, _Tp __val) {
1113 __cxx_atomic_assign_volatile(__a->__a_value, __val);
1114}
1115template <typename _Tp>
1116_LIBCPP_INLINE_VISIBILITY
1117void __cxx_atomic_init(__cxx_atomic_lock_impl<_Tp>* __a, _Tp __val) {
1118 __a->__a_value = __val;
1119}
1120
1121template <typename _Tp>
1122_LIBCPP_INLINE_VISIBILITY
1123void __cxx_atomic_store(volatile __cxx_atomic_lock_impl<_Tp>* __a, _Tp __val, memory_order) {
1124 __a->__lock();
1125 __cxx_atomic_assign_volatile(__a->__a_value, __val);
1126 __a->__unlock();
1127}
1128template <typename _Tp>
1129_LIBCPP_INLINE_VISIBILITY
1130void __cxx_atomic_store(__cxx_atomic_lock_impl<_Tp>* __a, _Tp __val, memory_order) {
1131 __a->__lock();
1132 __a->__a_value = __val;
1133 __a->__unlock();
1134}
1135
1136template <typename _Tp>
1137_LIBCPP_INLINE_VISIBILITY
1138_Tp __cxx_atomic_load(const volatile __cxx_atomic_lock_impl<_Tp>* __a, memory_order) {
1139 return __a->__read();
1140}
1141template <typename _Tp>
1142_LIBCPP_INLINE_VISIBILITY
1143_Tp __cxx_atomic_load(const __cxx_atomic_lock_impl<_Tp>* __a, memory_order) {
1144 return __a->__read();
1145}
1146
1147template <typename _Tp>
1148_LIBCPP_INLINE_VISIBILITY
1149_Tp __cxx_atomic_exchange(volatile __cxx_atomic_lock_impl<_Tp>* __a, _Tp __value, memory_order) {
1150 __a->__lock();
1151 _Tp __old;
1152 __cxx_atomic_assign_volatile(__old, __a->__a_value);
1153 __cxx_atomic_assign_volatile(__a->__a_value, __value);
1154 __a->__unlock();
1155 return __old;
1156}
1157template <typename _Tp>
1158_LIBCPP_INLINE_VISIBILITY
1159_Tp __cxx_atomic_exchange(__cxx_atomic_lock_impl<_Tp>* __a, _Tp __value, memory_order) {
1160 __a->__lock();
1161 _Tp __old = __a->__a_value;
1162 __a->__a_value = __value;
1163 __a->__unlock();
1164 return __old;
1165}
1166
1167template <typename _Tp>
1168_LIBCPP_INLINE_VISIBILITY
1169bool __cxx_atomic_compare_exchange_strong(volatile __cxx_atomic_lock_impl<_Tp>* __a,
1170 _Tp* __expected, _Tp __value, memory_order, memory_order) {
1171 __a->__lock();
1172 _Tp temp;
1173 __cxx_atomic_assign_volatile(temp, __a->__a_value);
1174 bool __ret = temp == *__expected;
1175 if(__ret)
1176 __cxx_atomic_assign_volatile(__a->__a_value, __value);
1177 else
1178 __cxx_atomic_assign_volatile(*__expected, __a->__a_value);
1179 __a->__unlock();
1180 return __ret;
1181}
1182template <typename _Tp>
1183_LIBCPP_INLINE_VISIBILITY
1184bool __cxx_atomic_compare_exchange_strong(__cxx_atomic_lock_impl<_Tp>* __a,
1185 _Tp* __expected, _Tp __value, memory_order, memory_order) {
1186 __a->__lock();
1187 bool __ret = __a->__a_value == *__expected;
1188 if(__ret)
1189 __a->__a_value = __value;
1190 else
1191 *__expected = __a->__a_value;
1192 __a->__unlock();
1193 return __ret;
1194}
1195
1196template <typename _Tp>
1197_LIBCPP_INLINE_VISIBILITY
1198bool __cxx_atomic_compare_exchange_weak(volatile __cxx_atomic_lock_impl<_Tp>* __a,
1199 _Tp* __expected, _Tp __value, memory_order, memory_order) {
1200 __a->__lock();
1201 _Tp temp;
1202 __cxx_atomic_assign_volatile(temp, __a->__a_value);
1203 bool __ret = temp == *__expected;
1204 if(__ret)
1205 __cxx_atomic_assign_volatile(__a->__a_value, __value);
1206 else
1207 __cxx_atomic_assign_volatile(*__expected, __a->__a_value);
1208 __a->__unlock();
1209 return __ret;
1210}
1211template <typename _Tp>
1212_LIBCPP_INLINE_VISIBILITY
1213bool __cxx_atomic_compare_exchange_weak(__cxx_atomic_lock_impl<_Tp>* __a,
1214 _Tp* __expected, _Tp __value, memory_order, memory_order) {
1215 __a->__lock();
1216 bool __ret = __a->__a_value == *__expected;
1217 if(__ret)
1218 __a->__a_value = __value;
1219 else
1220 *__expected = __a->__a_value;
1221 __a->__unlock();
1222 return __ret;
1223}
1224
1225template <typename _Tp, typename _Td>
1226_LIBCPP_INLINE_VISIBILITY
1227_Tp __cxx_atomic_fetch_add(volatile __cxx_atomic_lock_impl<_Tp>* __a,
1228 _Td __delta, memory_order) {
1229 __a->__lock();
1230 _Tp __old;
1231 __cxx_atomic_assign_volatile(__old, __a->__a_value);
1232 __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old + __delta));
1233 __a->__unlock();
1234 return __old;
1235}
1236template <typename _Tp, typename _Td>
1237_LIBCPP_INLINE_VISIBILITY
1238_Tp __cxx_atomic_fetch_add(__cxx_atomic_lock_impl<_Tp>* __a,
1239 _Td __delta, memory_order) {
1240 __a->__lock();
1241 _Tp __old = __a->__a_value;
1242 __a->__a_value += __delta;
1243 __a->__unlock();
1244 return __old;
1245}
1246
1247template <typename _Tp, typename _Td>
1248_LIBCPP_INLINE_VISIBILITY
1249_Tp* __cxx_atomic_fetch_add(volatile __cxx_atomic_lock_impl<_Tp*>* __a,
1250 ptrdiff_t __delta, memory_order) {
1251 __a->__lock();
1252 _Tp* __old;
1253 __cxx_atomic_assign_volatile(__old, __a->__a_value);
1254 __cxx_atomic_assign_volatile(__a->__a_value, __old + __delta);
1255 __a->__unlock();
1256 return __old;
1257}
1258template <typename _Tp, typename _Td>
1259_LIBCPP_INLINE_VISIBILITY
1260_Tp* __cxx_atomic_fetch_add(__cxx_atomic_lock_impl<_Tp*>* __a,
1261 ptrdiff_t __delta, memory_order) {
1262 __a->__lock();
1263 _Tp* __old = __a->__a_value;
1264 __a->__a_value += __delta;
1265 __a->__unlock();
1266 return __old;
1267}
1268
1269template <typename _Tp, typename _Td>
1270_LIBCPP_INLINE_VISIBILITY
1271_Tp __cxx_atomic_fetch_sub(volatile __cxx_atomic_lock_impl<_Tp>* __a,
1272 _Td __delta, memory_order) {
1273 __a->__lock();
1274 _Tp __old;
1275 __cxx_atomic_assign_volatile(__old, __a->__a_value);
1276 __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old - __delta));
1277 __a->__unlock();
1278 return __old;
1279}
1280template <typename _Tp, typename _Td>
1281_LIBCPP_INLINE_VISIBILITY
1282_Tp __cxx_atomic_fetch_sub(__cxx_atomic_lock_impl<_Tp>* __a,
1283 _Td __delta, memory_order) {
1284 __a->__lock();
1285 _Tp __old = __a->__a_value;
1286 __a->__a_value -= __delta;
1287 __a->__unlock();
1288 return __old;
1289}
1290
1291template <typename _Tp>
1292_LIBCPP_INLINE_VISIBILITY
1293_Tp __cxx_atomic_fetch_and(volatile __cxx_atomic_lock_impl<_Tp>* __a,
1294 _Tp __pattern, memory_order) {
1295 __a->__lock();
1296 _Tp __old;
1297 __cxx_atomic_assign_volatile(__old, __a->__a_value);
1298 __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old & __pattern));
1299 __a->__unlock();
1300 return __old;
1301}
1302template <typename _Tp>
1303_LIBCPP_INLINE_VISIBILITY
1304_Tp __cxx_atomic_fetch_and(__cxx_atomic_lock_impl<_Tp>* __a,
1305 _Tp __pattern, memory_order) {
1306 __a->__lock();
1307 _Tp __old = __a->__a_value;
1308 __a->__a_value &= __pattern;
1309 __a->__unlock();
1310 return __old;
1311}
1312
1313template <typename _Tp>
1314_LIBCPP_INLINE_VISIBILITY
1315_Tp __cxx_atomic_fetch_or(volatile __cxx_atomic_lock_impl<_Tp>* __a,
1316 _Tp __pattern, memory_order) {
1317 __a->__lock();
1318 _Tp __old;
1319 __cxx_atomic_assign_volatile(__old, __a->__a_value);
1320 __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old | __pattern));
1321 __a->__unlock();
1322 return __old;
1323}
1324template <typename _Tp>
1325_LIBCPP_INLINE_VISIBILITY
1326_Tp __cxx_atomic_fetch_or(__cxx_atomic_lock_impl<_Tp>* __a,
1327 _Tp __pattern, memory_order) {
1328 __a->__lock();
1329 _Tp __old = __a->__a_value;
1330 __a->__a_value |= __pattern;
1331 __a->__unlock();
1332 return __old;
1333}
1334
1335template <typename _Tp>
1336_LIBCPP_INLINE_VISIBILITY
1337_Tp __cxx_atomic_fetch_xor(volatile __cxx_atomic_lock_impl<_Tp>* __a,
1338 _Tp __pattern, memory_order) {
1339 __a->__lock();
1340 _Tp __old;
1341 __cxx_atomic_assign_volatile(__old, __a->__a_value);
1342 __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old ^ __pattern));
1343 __a->__unlock();
1344 return __old;
1345}
1346template <typename _Tp>
1347_LIBCPP_INLINE_VISIBILITY
1348_Tp __cxx_atomic_fetch_xor(__cxx_atomic_lock_impl<_Tp>* __a,
1349 _Tp __pattern, memory_order) {
1350 __a->__lock();
1351 _Tp __old = __a->__a_value;
1352 __a->__a_value ^= __pattern;
1353 __a->__unlock();
1354 return __old;
1355}
1356
1357#ifdef __cpp_lib_atomic_is_always_lock_free
1358
1359template<typename _Tp> struct __cxx_is_always_lock_free {
1360 enum { __value = __atomic_always_lock_free(sizeof(_Tp), 0) }; };
1361
1362#else
1363
1364template<typename _Tp> struct __cxx_is_always_lock_free { enum { __value = false }; };
1365// Implementations must match the C ATOMIC_*_LOCK_FREE macro values.
1366template<> struct __cxx_is_always_lock_free<bool> { enum { __value = 2 == ATOMIC_BOOL_LOCK_FREE }; };
1367template<> struct __cxx_is_always_lock_free<char> { enum { __value = 2 == ATOMIC_CHAR_LOCK_FREE }; };
1368template<> struct __cxx_is_always_lock_free<signed char> { enum { __value = 2 == ATOMIC_CHAR_LOCK_FREE }; };
1369template<> struct __cxx_is_always_lock_free<unsigned char> { enum { __value = 2 == ATOMIC_CHAR_LOCK_FREE }; };
1370template<> struct __cxx_is_always_lock_free<char16_t> { enum { __value = 2 == ATOMIC_CHAR16_T_LOCK_FREE }; };
1371template<> struct __cxx_is_always_lock_free<char32_t> { enum { __value = 2 == ATOMIC_CHAR32_T_LOCK_FREE }; };
1372template<> struct __cxx_is_always_lock_free<wchar_t> { enum { __value = 2 == ATOMIC_WCHAR_T_LOCK_FREE }; };
1373template<> struct __cxx_is_always_lock_free<short> { enum { __value = 2 == ATOMIC_SHORT_LOCK_FREE }; };
1374template<> struct __cxx_is_always_lock_free<unsigned short> { enum { __value = 2 == ATOMIC_SHORT_LOCK_FREE }; };
1375template<> struct __cxx_is_always_lock_free<int> { enum { __value = 2 == ATOMIC_INT_LOCK_FREE }; };
1376template<> struct __cxx_is_always_lock_free<unsigned int> { enum { __value = 2 == ATOMIC_INT_LOCK_FREE }; };
1377template<> struct __cxx_is_always_lock_free<long> { enum { __value = 2 == ATOMIC_LONG_LOCK_FREE }; };
1378template<> struct __cxx_is_always_lock_free<unsigned long> { enum { __value = 2 == ATOMIC_LONG_LOCK_FREE }; };
1379template<> struct __cxx_is_always_lock_free<long long> { enum { __value = 2 == ATOMIC_LLONG_LOCK_FREE }; };
1380template<> struct __cxx_is_always_lock_free<unsigned long long> { enum { __value = 2 == ATOMIC_LLONG_LOCK_FREE }; };
1381template<typename _Tp> struct __cxx_is_always_lock_free<_Tp*> { enum { __value = 2 == ATOMIC_POINTER_LOCK_FREE }; };
1382template<> struct __cxx_is_always_lock_free<std::nullptr_t> { enum { __value = 2 == ATOMIC_POINTER_LOCK_FREE }; };
1383
1384#endif //__cpp_lib_atomic_is_always_lock_free
1385
1386template <typename _Tp,
1387 typename _Base = typename conditional<__cxx_is_always_lock_free<_Tp>::__value,
1388 __cxx_atomic_base_impl<_Tp>,
1389 __cxx_atomic_lock_impl<_Tp> >::type>
1390#else
1391template <typename _Tp,
1392 typename _Base = __cxx_atomic_base_impl<_Tp> >
1393#endif //_LIBCPP_ATOMIC_ONLY_USE_BUILTINS
1394struct __cxx_atomic_impl : public _Base {
1395
1396#if _GNUC_VER >= 501
1397 static_assert(is_trivially_copyable<_Tp>::value,
1398 "std::atomic<Tp> requires that 'Tp' be a trivially copyable type");
1399#endif
1400
1401 _LIBCPP_INLINE_VISIBILITY __cxx_atomic_impl() _NOEXCEPT _LIBCPP_DEFAULT
1402 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR explicit __cxx_atomic_impl(_Tp value) _NOEXCEPT
1403 : _Base(value) {}
1404};
1405
Howard Hinnant138f5922010-12-07 20:46:14 +00001406// general atomic<T>
1407
1408template <class _Tp, bool = is_integral<_Tp>::value && !is_same<_Tp, bool>::value>
1409struct __atomic_base // false
1410{
Louis Dionnea1ae0032019-03-04 15:26:27 +00001411 mutable __cxx_atomic_impl<_Tp> __a_;
Howard Hinnant138f5922010-12-07 20:46:14 +00001412
JF Bastienfdb42c22016-03-25 15:48:21 +00001413#if defined(__cpp_lib_atomic_is_always_lock_free)
1414 static _LIBCPP_CONSTEXPR bool is_always_lock_free = __atomic_always_lock_free(sizeof(__a_), 0);
1415#endif
1416
Howard Hinnant138f5922010-12-07 20:46:14 +00001417 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001418 bool is_lock_free() const volatile _NOEXCEPT
Louis Dionnea1ae0032019-03-04 15:26:27 +00001419 {return __cxx_atomic_is_lock_free(sizeof(_Tp));}
Howard Hinnant138f5922010-12-07 20:46:14 +00001420 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001421 bool is_lock_free() const _NOEXCEPT
Eric Fiselier3fd22c22015-06-13 00:23:07 +00001422 {return static_cast<__atomic_base const volatile*>(this)->is_lock_free();}
Howard Hinnant138f5922010-12-07 20:46:14 +00001423 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001424 void store(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001425 _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
Louis Dionnea1ae0032019-03-04 15:26:27 +00001426 {__cxx_atomic_store(&__a_, __d, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001427 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001428 void store(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001429 _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
Louis Dionnea1ae0032019-03-04 15:26:27 +00001430 {__cxx_atomic_store(&__a_, __d, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001431 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001432 _Tp load(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001433 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
Louis Dionnea1ae0032019-03-04 15:26:27 +00001434 {return __cxx_atomic_load(&__a_, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001435 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001436 _Tp load(memory_order __m = memory_order_seq_cst) const _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001437 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
Louis Dionnea1ae0032019-03-04 15:26:27 +00001438 {return __cxx_atomic_load(&__a_, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001439 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001440 operator _Tp() const volatile _NOEXCEPT {return load();}
Howard Hinnant138f5922010-12-07 20:46:14 +00001441 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001442 operator _Tp() const _NOEXCEPT {return load();}
Howard Hinnant138f5922010-12-07 20:46:14 +00001443 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001444 _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Louis Dionnea1ae0032019-03-04 15:26:27 +00001445 {return __cxx_atomic_exchange(&__a_, __d, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001446 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001447 _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Louis Dionnea1ae0032019-03-04 15:26:27 +00001448 {return __cxx_atomic_exchange(&__a_, __d, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001449 _LIBCPP_INLINE_VISIBILITY
1450 bool compare_exchange_weak(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001451 memory_order __s, memory_order __f) volatile _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001452 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Louis Dionnea1ae0032019-03-04 15:26:27 +00001453 {return __cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001454 _LIBCPP_INLINE_VISIBILITY
1455 bool compare_exchange_weak(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001456 memory_order __s, memory_order __f) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001457 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Louis Dionnea1ae0032019-03-04 15:26:27 +00001458 {return __cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001459 _LIBCPP_INLINE_VISIBILITY
1460 bool compare_exchange_strong(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001461 memory_order __s, memory_order __f) volatile _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001462 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Louis Dionnea1ae0032019-03-04 15:26:27 +00001463 {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001464 _LIBCPP_INLINE_VISIBILITY
1465 bool compare_exchange_strong(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001466 memory_order __s, memory_order __f) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001467 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Louis Dionnea1ae0032019-03-04 15:26:27 +00001468 {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001469 _LIBCPP_INLINE_VISIBILITY
1470 bool compare_exchange_weak(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001471 memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Louis Dionnea1ae0032019-03-04 15:26:27 +00001472 {return __cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001473 _LIBCPP_INLINE_VISIBILITY
1474 bool compare_exchange_weak(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001475 memory_order __m = memory_order_seq_cst) _NOEXCEPT
Louis Dionnea1ae0032019-03-04 15:26:27 +00001476 {return __cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001477 _LIBCPP_INLINE_VISIBILITY
1478 bool compare_exchange_strong(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001479 memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Louis Dionnea1ae0032019-03-04 15:26:27 +00001480 {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001481 _LIBCPP_INLINE_VISIBILITY
1482 bool compare_exchange_strong(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001483 memory_order __m = memory_order_seq_cst) _NOEXCEPT
Louis Dionnea1ae0032019-03-04 15:26:27 +00001484 {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001485
1486 _LIBCPP_INLINE_VISIBILITY
Louis Dionnea1ae0032019-03-04 15:26:27 +00001487 __atomic_base() _NOEXCEPT _LIBCPP_DEFAULT
Howard Hinnant3d284222013-05-02 20:18:43 +00001488
Louis Dionnea1ae0032019-03-04 15:26:27 +00001489 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
1490 __atomic_base(_Tp __d) _NOEXCEPT : __a_(__d) {}
1491
Eric Fiselier2d8515f2017-01-06 20:58:25 +00001492#ifndef _LIBCPP_CXX03_LANG
Howard Hinnant138f5922010-12-07 20:46:14 +00001493 __atomic_base(const __atomic_base&) = delete;
1494 __atomic_base& operator=(const __atomic_base&) = delete;
1495 __atomic_base& operator=(const __atomic_base&) volatile = delete;
Eric Fiselier2d8515f2017-01-06 20:58:25 +00001496#else
Howard Hinnant6ac60f82010-12-08 17:20:28 +00001497private:
1498 __atomic_base(const __atomic_base&);
1499 __atomic_base& operator=(const __atomic_base&);
1500 __atomic_base& operator=(const __atomic_base&) volatile;
Eric Fiselier2d8515f2017-01-06 20:58:25 +00001501#endif
Howard Hinnant138f5922010-12-07 20:46:14 +00001502};
1503
JF Bastienfdb42c22016-03-25 15:48:21 +00001504#if defined(__cpp_lib_atomic_is_always_lock_free)
1505template <class _Tp, bool __b>
1506_LIBCPP_CONSTEXPR bool __atomic_base<_Tp, __b>::is_always_lock_free;
1507#endif
1508
Howard Hinnant138f5922010-12-07 20:46:14 +00001509// atomic<Integral>
1510
1511template <class _Tp>
1512struct __atomic_base<_Tp, true>
1513 : public __atomic_base<_Tp, false>
1514{
1515 typedef __atomic_base<_Tp, false> __base;
1516 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3d284222013-05-02 20:18:43 +00001517 __atomic_base() _NOEXCEPT _LIBCPP_DEFAULT
Howard Hinnant138f5922010-12-07 20:46:14 +00001518 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001519 _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __base(__d) {}
Howard Hinnant138f5922010-12-07 20:46:14 +00001520
1521 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001522 _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Louis Dionnea1ae0032019-03-04 15:26:27 +00001523 {return __cxx_atomic_fetch_add(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001524 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001525 _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Louis Dionnea1ae0032019-03-04 15:26:27 +00001526 {return __cxx_atomic_fetch_add(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001527 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001528 _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Louis Dionnea1ae0032019-03-04 15:26:27 +00001529 {return __cxx_atomic_fetch_sub(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001530 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001531 _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Louis Dionnea1ae0032019-03-04 15:26:27 +00001532 {return __cxx_atomic_fetch_sub(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001533 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001534 _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Louis Dionnea1ae0032019-03-04 15:26:27 +00001535 {return __cxx_atomic_fetch_and(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001536 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001537 _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Louis Dionnea1ae0032019-03-04 15:26:27 +00001538 {return __cxx_atomic_fetch_and(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001539 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001540 _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Louis Dionnea1ae0032019-03-04 15:26:27 +00001541 {return __cxx_atomic_fetch_or(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001542 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001543 _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Louis Dionnea1ae0032019-03-04 15:26:27 +00001544 {return __cxx_atomic_fetch_or(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001545 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001546 _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Louis Dionnea1ae0032019-03-04 15:26:27 +00001547 {return __cxx_atomic_fetch_xor(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001548 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001549 _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Louis Dionnea1ae0032019-03-04 15:26:27 +00001550 {return __cxx_atomic_fetch_xor(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001551
1552 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001553 _Tp operator++(int) volatile _NOEXCEPT {return fetch_add(_Tp(1));}
Howard Hinnant138f5922010-12-07 20:46:14 +00001554 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001555 _Tp operator++(int) _NOEXCEPT {return fetch_add(_Tp(1));}
Howard Hinnant138f5922010-12-07 20:46:14 +00001556 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001557 _Tp operator--(int) volatile _NOEXCEPT {return fetch_sub(_Tp(1));}
Howard Hinnant138f5922010-12-07 20:46:14 +00001558 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001559 _Tp operator--(int) _NOEXCEPT {return fetch_sub(_Tp(1));}
Howard Hinnant138f5922010-12-07 20:46:14 +00001560 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001561 _Tp operator++() volatile _NOEXCEPT {return fetch_add(_Tp(1)) + _Tp(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001562 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001563 _Tp operator++() _NOEXCEPT {return fetch_add(_Tp(1)) + _Tp(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001564 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001565 _Tp operator--() volatile _NOEXCEPT {return fetch_sub(_Tp(1)) - _Tp(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001566 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001567 _Tp operator--() _NOEXCEPT {return fetch_sub(_Tp(1)) - _Tp(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001568 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001569 _Tp operator+=(_Tp __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001570 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001571 _Tp operator+=(_Tp __op) _NOEXCEPT {return fetch_add(__op) + __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001572 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001573 _Tp operator-=(_Tp __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001574 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001575 _Tp operator-=(_Tp __op) _NOEXCEPT {return fetch_sub(__op) - __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001576 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001577 _Tp operator&=(_Tp __op) volatile _NOEXCEPT {return fetch_and(__op) & __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001578 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001579 _Tp operator&=(_Tp __op) _NOEXCEPT {return fetch_and(__op) & __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001580 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001581 _Tp operator|=(_Tp __op) volatile _NOEXCEPT {return fetch_or(__op) | __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001582 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001583 _Tp operator|=(_Tp __op) _NOEXCEPT {return fetch_or(__op) | __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001584 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001585 _Tp operator^=(_Tp __op) volatile _NOEXCEPT {return fetch_xor(__op) ^ __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001586 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001587 _Tp operator^=(_Tp __op) _NOEXCEPT {return fetch_xor(__op) ^ __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001588};
1589
1590// atomic<T>
1591
1592template <class _Tp>
1593struct atomic
1594 : public __atomic_base<_Tp>
1595{
1596 typedef __atomic_base<_Tp> __base;
1597 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3d284222013-05-02 20:18:43 +00001598 atomic() _NOEXCEPT _LIBCPP_DEFAULT
Howard Hinnant138f5922010-12-07 20:46:14 +00001599 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001600 _LIBCPP_CONSTEXPR atomic(_Tp __d) _NOEXCEPT : __base(__d) {}
Howard Hinnant96e4cd62010-12-07 23:24:41 +00001601
1602 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001603 _Tp operator=(_Tp __d) volatile _NOEXCEPT
Howard Hinnant96e4cd62010-12-07 23:24:41 +00001604 {__base::store(__d); return __d;}
1605 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001606 _Tp operator=(_Tp __d) _NOEXCEPT
Howard Hinnant96e4cd62010-12-07 23:24:41 +00001607 {__base::store(__d); return __d;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001608};
1609
1610// atomic<T*>
1611
1612template <class _Tp>
1613struct atomic<_Tp*>
1614 : public __atomic_base<_Tp*>
1615{
Howard Hinnant96e4cd62010-12-07 23:24:41 +00001616 typedef __atomic_base<_Tp*> __base;
Howard Hinnant138f5922010-12-07 20:46:14 +00001617 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3d284222013-05-02 20:18:43 +00001618 atomic() _NOEXCEPT _LIBCPP_DEFAULT
Howard Hinnant138f5922010-12-07 20:46:14 +00001619 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001620 _LIBCPP_CONSTEXPR atomic(_Tp* __d) _NOEXCEPT : __base(__d) {}
Howard Hinnant138f5922010-12-07 20:46:14 +00001621
1622 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001623 _Tp* operator=(_Tp* __d) volatile _NOEXCEPT
Howard Hinnant96e4cd62010-12-07 23:24:41 +00001624 {__base::store(__d); return __d;}
1625 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001626 _Tp* operator=(_Tp* __d) _NOEXCEPT
Howard Hinnant96e4cd62010-12-07 23:24:41 +00001627 {__base::store(__d); return __d;}
1628
1629 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00001630 _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst)
Howard Hinnanteee2c142012-04-11 20:14:21 +00001631 volatile _NOEXCEPT
Louis Dionnea1ae0032019-03-04 15:26:27 +00001632 {return __cxx_atomic_fetch_add(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001633 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001634 _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Louis Dionnea1ae0032019-03-04 15:26:27 +00001635 {return __cxx_atomic_fetch_add(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001636 _LIBCPP_INLINE_VISIBILITY
1637 _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst)
Howard Hinnanteee2c142012-04-11 20:14:21 +00001638 volatile _NOEXCEPT
Louis Dionnea1ae0032019-03-04 15:26:27 +00001639 {return __cxx_atomic_fetch_sub(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001640 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001641 _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Louis Dionnea1ae0032019-03-04 15:26:27 +00001642 {return __cxx_atomic_fetch_sub(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001643
1644 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001645 _Tp* operator++(int) volatile _NOEXCEPT {return fetch_add(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001646 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001647 _Tp* operator++(int) _NOEXCEPT {return fetch_add(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001648 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001649 _Tp* operator--(int) volatile _NOEXCEPT {return fetch_sub(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001650 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001651 _Tp* operator--(int) _NOEXCEPT {return fetch_sub(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001652 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001653 _Tp* operator++() volatile _NOEXCEPT {return fetch_add(1) + 1;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001654 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001655 _Tp* operator++() _NOEXCEPT {return fetch_add(1) + 1;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001656 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001657 _Tp* operator--() volatile _NOEXCEPT {return fetch_sub(1) - 1;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001658 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001659 _Tp* operator--() _NOEXCEPT {return fetch_sub(1) - 1;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001660 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001661 _Tp* operator+=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001662 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001663 _Tp* operator+=(ptrdiff_t __op) _NOEXCEPT {return fetch_add(__op) + __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001664 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001665 _Tp* operator-=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001666 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001667 _Tp* operator-=(ptrdiff_t __op) _NOEXCEPT {return fetch_sub(__op) - __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001668};
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001669
1670// atomic_is_lock_free
1671
1672template <class _Tp>
Louis Dionnea1ae0032019-03-04 15:26:27 +00001673_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001674bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00001675atomic_is_lock_free(const volatile atomic<_Tp>* __o) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001676{
Howard Hinnant138f5922010-12-07 20:46:14 +00001677 return __o->is_lock_free();
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001678}
1679
1680template <class _Tp>
Louis Dionnea1ae0032019-03-04 15:26:27 +00001681_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001682bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00001683atomic_is_lock_free(const atomic<_Tp>* __o) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001684{
Howard Hinnant138f5922010-12-07 20:46:14 +00001685 return __o->is_lock_free();
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001686}
1687
1688// atomic_init
1689
1690template <class _Tp>
Louis Dionnea1ae0032019-03-04 15:26:27 +00001691_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001692void
Howard Hinnanteee2c142012-04-11 20:14:21 +00001693atomic_init(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001694{
Louis Dionnea1ae0032019-03-04 15:26:27 +00001695 __cxx_atomic_init(&__o->__a_, __d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001696}
1697
1698template <class _Tp>
Louis Dionnea1ae0032019-03-04 15:26:27 +00001699_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001700void
Howard Hinnanteee2c142012-04-11 20:14:21 +00001701atomic_init(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001702{
Louis Dionnea1ae0032019-03-04 15:26:27 +00001703 __cxx_atomic_init(&__o->__a_, __d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001704}
1705
1706// atomic_store
1707
1708template <class _Tp>
Louis Dionnea1ae0032019-03-04 15:26:27 +00001709_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001710void
Howard Hinnanteee2c142012-04-11 20:14:21 +00001711atomic_store(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001712{
Howard Hinnant138f5922010-12-07 20:46:14 +00001713 __o->store(__d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001714}
1715
1716template <class _Tp>
Louis Dionnea1ae0032019-03-04 15:26:27 +00001717_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001718void
Howard Hinnanteee2c142012-04-11 20:14:21 +00001719atomic_store(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001720{
Howard Hinnant138f5922010-12-07 20:46:14 +00001721 __o->store(__d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001722}
1723
1724// atomic_store_explicit
1725
1726template <class _Tp>
Louis Dionnea1ae0032019-03-04 15:26:27 +00001727_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001728void
Howard Hinnanteee2c142012-04-11 20:14:21 +00001729atomic_store_explicit(volatile atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001730 _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001731{
Howard Hinnant138f5922010-12-07 20:46:14 +00001732 __o->store(__d, __m);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001733}
1734
1735template <class _Tp>
Louis Dionnea1ae0032019-03-04 15:26:27 +00001736_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001737void
Howard Hinnanteee2c142012-04-11 20:14:21 +00001738atomic_store_explicit(atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001739 _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001740{
Howard Hinnant138f5922010-12-07 20:46:14 +00001741 __o->store(__d, __m);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001742}
1743
1744// atomic_load
1745
1746template <class _Tp>
Louis Dionnea1ae0032019-03-04 15:26:27 +00001747_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001748_Tp
Howard Hinnanteee2c142012-04-11 20:14:21 +00001749atomic_load(const volatile atomic<_Tp>* __o) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001750{
Howard Hinnant138f5922010-12-07 20:46:14 +00001751 return __o->load();
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001752}
1753
1754template <class _Tp>
Louis Dionnea1ae0032019-03-04 15:26:27 +00001755_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001756_Tp
Howard Hinnanteee2c142012-04-11 20:14:21 +00001757atomic_load(const atomic<_Tp>* __o) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001758{
Howard Hinnant138f5922010-12-07 20:46:14 +00001759 return __o->load();
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001760}
1761
1762// atomic_load_explicit
1763
1764template <class _Tp>
Louis Dionnea1ae0032019-03-04 15:26:27 +00001765_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001766_Tp
Howard Hinnanteee2c142012-04-11 20:14:21 +00001767atomic_load_explicit(const volatile atomic<_Tp>* __o, memory_order __m) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001768 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001769{
Howard Hinnant138f5922010-12-07 20:46:14 +00001770 return __o->load(__m);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001771}
1772
1773template <class _Tp>
Louis Dionnea1ae0032019-03-04 15:26:27 +00001774_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001775_Tp
Howard Hinnanteee2c142012-04-11 20:14:21 +00001776atomic_load_explicit(const atomic<_Tp>* __o, memory_order __m) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001777 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001778{
Howard Hinnant138f5922010-12-07 20:46:14 +00001779 return __o->load(__m);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001780}
1781
1782// atomic_exchange
1783
1784template <class _Tp>
Louis Dionnea1ae0032019-03-04 15:26:27 +00001785_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001786_Tp
Howard Hinnanteee2c142012-04-11 20:14:21 +00001787atomic_exchange(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001788{
Howard Hinnant138f5922010-12-07 20:46:14 +00001789 return __o->exchange(__d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001790}
1791
1792template <class _Tp>
Louis Dionnea1ae0032019-03-04 15:26:27 +00001793_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001794_Tp
Howard Hinnanteee2c142012-04-11 20:14:21 +00001795atomic_exchange(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001796{
Howard Hinnant138f5922010-12-07 20:46:14 +00001797 return __o->exchange(__d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001798}
1799
1800// atomic_exchange_explicit
1801
1802template <class _Tp>
Louis Dionnea1ae0032019-03-04 15:26:27 +00001803_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001804_Tp
Howard Hinnanteee2c142012-04-11 20:14:21 +00001805atomic_exchange_explicit(volatile atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001806{
Howard Hinnant138f5922010-12-07 20:46:14 +00001807 return __o->exchange(__d, __m);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001808}
1809
1810template <class _Tp>
Louis Dionnea1ae0032019-03-04 15:26:27 +00001811_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001812_Tp
Howard Hinnanteee2c142012-04-11 20:14:21 +00001813atomic_exchange_explicit(atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001814{
Howard Hinnant138f5922010-12-07 20:46:14 +00001815 return __o->exchange(__d, __m);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001816}
1817
1818// atomic_compare_exchange_weak
1819
1820template <class _Tp>
Louis Dionnea1ae0032019-03-04 15:26:27 +00001821_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001822bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00001823atomic_compare_exchange_weak(volatile atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001824{
Howard Hinnant138f5922010-12-07 20:46:14 +00001825 return __o->compare_exchange_weak(*__e, __d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001826}
1827
1828template <class _Tp>
Louis Dionnea1ae0032019-03-04 15:26:27 +00001829_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001830bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00001831atomic_compare_exchange_weak(atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001832{
Howard Hinnant138f5922010-12-07 20:46:14 +00001833 return __o->compare_exchange_weak(*__e, __d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001834}
1835
1836// atomic_compare_exchange_strong
1837
1838template <class _Tp>
Louis Dionnea1ae0032019-03-04 15:26:27 +00001839_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001840bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00001841atomic_compare_exchange_strong(volatile atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001842{
Howard Hinnant138f5922010-12-07 20:46:14 +00001843 return __o->compare_exchange_strong(*__e, __d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001844}
1845
1846template <class _Tp>
Louis Dionnea1ae0032019-03-04 15:26:27 +00001847_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001848bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00001849atomic_compare_exchange_strong(atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001850{
Howard Hinnant138f5922010-12-07 20:46:14 +00001851 return __o->compare_exchange_strong(*__e, __d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001852}
1853
1854// atomic_compare_exchange_weak_explicit
1855
1856template <class _Tp>
Louis Dionnea1ae0032019-03-04 15:26:27 +00001857_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001858bool
1859atomic_compare_exchange_weak_explicit(volatile atomic<_Tp>* __o, _Tp* __e,
1860 _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001861 memory_order __s, memory_order __f) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001862 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001863{
Howard Hinnant138f5922010-12-07 20:46:14 +00001864 return __o->compare_exchange_weak(*__e, __d, __s, __f);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001865}
1866
1867template <class _Tp>
Louis Dionnea1ae0032019-03-04 15:26:27 +00001868_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001869bool
1870atomic_compare_exchange_weak_explicit(atomic<_Tp>* __o, _Tp* __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001871 memory_order __s, memory_order __f) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001872 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001873{
Howard Hinnant138f5922010-12-07 20:46:14 +00001874 return __o->compare_exchange_weak(*__e, __d, __s, __f);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001875}
1876
1877// atomic_compare_exchange_strong_explicit
1878
1879template <class _Tp>
Louis Dionnea1ae0032019-03-04 15:26:27 +00001880_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001881bool
1882atomic_compare_exchange_strong_explicit(volatile atomic<_Tp>* __o,
1883 _Tp* __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001884 memory_order __s, memory_order __f) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001885 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001886{
Howard Hinnant138f5922010-12-07 20:46:14 +00001887 return __o->compare_exchange_strong(*__e, __d, __s, __f);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001888}
1889
1890template <class _Tp>
Louis Dionnea1ae0032019-03-04 15:26:27 +00001891_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001892bool
1893atomic_compare_exchange_strong_explicit(atomic<_Tp>* __o, _Tp* __e,
1894 _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001895 memory_order __s, memory_order __f) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001896 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001897{
Howard Hinnant138f5922010-12-07 20:46:14 +00001898 return __o->compare_exchange_strong(*__e, __d, __s, __f);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001899}
1900
Howard Hinnant138f5922010-12-07 20:46:14 +00001901// atomic_fetch_add
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001902
1903template <class _Tp>
Louis Dionnea1ae0032019-03-04 15:26:27 +00001904_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00001905typename enable_if
1906<
1907 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1908 _Tp
1909>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00001910atomic_fetch_add(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001911{
Howard Hinnant138f5922010-12-07 20:46:14 +00001912 return __o->fetch_add(__op);
1913}
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001914
Howard Hinnant138f5922010-12-07 20:46:14 +00001915template <class _Tp>
Louis Dionnea1ae0032019-03-04 15:26:27 +00001916_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00001917typename enable_if
1918<
1919 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1920 _Tp
1921>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00001922atomic_fetch_add(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00001923{
1924 return __o->fetch_add(__op);
1925}
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001926
Howard Hinnant138f5922010-12-07 20:46:14 +00001927template <class _Tp>
Louis Dionnea1ae0032019-03-04 15:26:27 +00001928_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00001929_Tp*
Howard Hinnanteee2c142012-04-11 20:14:21 +00001930atomic_fetch_add(volatile atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00001931{
1932 return __o->fetch_add(__op);
1933}
1934
1935template <class _Tp>
Louis Dionnea1ae0032019-03-04 15:26:27 +00001936_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00001937_Tp*
Howard Hinnanteee2c142012-04-11 20:14:21 +00001938atomic_fetch_add(atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00001939{
1940 return __o->fetch_add(__op);
1941}
1942
1943// atomic_fetch_add_explicit
1944
1945template <class _Tp>
Louis Dionnea1ae0032019-03-04 15:26:27 +00001946_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00001947typename enable_if
1948<
1949 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1950 _Tp
1951>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00001952atomic_fetch_add_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00001953{
1954 return __o->fetch_add(__op, __m);
1955}
1956
1957template <class _Tp>
Louis Dionnea1ae0032019-03-04 15:26:27 +00001958_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00001959typename enable_if
1960<
1961 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1962 _Tp
1963>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00001964atomic_fetch_add_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00001965{
1966 return __o->fetch_add(__op, __m);
1967}
1968
1969template <class _Tp>
Louis Dionnea1ae0032019-03-04 15:26:27 +00001970_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00001971_Tp*
1972atomic_fetch_add_explicit(volatile atomic<_Tp*>* __o, ptrdiff_t __op,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001973 memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00001974{
1975 return __o->fetch_add(__op, __m);
1976}
1977
1978template <class _Tp>
Louis Dionnea1ae0032019-03-04 15:26:27 +00001979_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00001980_Tp*
Howard Hinnanteee2c142012-04-11 20:14:21 +00001981atomic_fetch_add_explicit(atomic<_Tp*>* __o, ptrdiff_t __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00001982{
1983 return __o->fetch_add(__op, __m);
1984}
1985
1986// atomic_fetch_sub
1987
1988template <class _Tp>
Louis Dionnea1ae0032019-03-04 15:26:27 +00001989_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00001990typename enable_if
1991<
1992 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1993 _Tp
1994>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00001995atomic_fetch_sub(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00001996{
1997 return __o->fetch_sub(__op);
1998}
1999
2000template <class _Tp>
Louis Dionnea1ae0032019-03-04 15:26:27 +00002001_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002002typename enable_if
2003<
2004 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2005 _Tp
2006>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00002007atomic_fetch_sub(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002008{
2009 return __o->fetch_sub(__op);
2010}
2011
2012template <class _Tp>
Louis Dionnea1ae0032019-03-04 15:26:27 +00002013_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002014_Tp*
Howard Hinnanteee2c142012-04-11 20:14:21 +00002015atomic_fetch_sub(volatile atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002016{
2017 return __o->fetch_sub(__op);
2018}
2019
2020template <class _Tp>
Louis Dionnea1ae0032019-03-04 15:26:27 +00002021_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002022_Tp*
Howard Hinnanteee2c142012-04-11 20:14:21 +00002023atomic_fetch_sub(atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002024{
2025 return __o->fetch_sub(__op);
2026}
2027
2028// atomic_fetch_sub_explicit
2029
2030template <class _Tp>
Louis Dionnea1ae0032019-03-04 15:26:27 +00002031_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002032typename enable_if
2033<
2034 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2035 _Tp
2036>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00002037atomic_fetch_sub_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002038{
2039 return __o->fetch_sub(__op, __m);
2040}
2041
2042template <class _Tp>
Louis Dionnea1ae0032019-03-04 15:26:27 +00002043_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002044typename enable_if
2045<
2046 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2047 _Tp
2048>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00002049atomic_fetch_sub_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002050{
2051 return __o->fetch_sub(__op, __m);
2052}
2053
2054template <class _Tp>
Louis Dionnea1ae0032019-03-04 15:26:27 +00002055_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002056_Tp*
2057atomic_fetch_sub_explicit(volatile atomic<_Tp*>* __o, ptrdiff_t __op,
Howard Hinnanteee2c142012-04-11 20:14:21 +00002058 memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002059{
2060 return __o->fetch_sub(__op, __m);
2061}
2062
2063template <class _Tp>
Louis Dionnea1ae0032019-03-04 15:26:27 +00002064_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002065_Tp*
Howard Hinnanteee2c142012-04-11 20:14:21 +00002066atomic_fetch_sub_explicit(atomic<_Tp*>* __o, ptrdiff_t __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002067{
2068 return __o->fetch_sub(__op, __m);
2069}
2070
2071// atomic_fetch_and
2072
2073template <class _Tp>
Louis Dionnea1ae0032019-03-04 15:26:27 +00002074_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002075typename enable_if
2076<
2077 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2078 _Tp
2079>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00002080atomic_fetch_and(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002081{
2082 return __o->fetch_and(__op);
2083}
2084
2085template <class _Tp>
Louis Dionnea1ae0032019-03-04 15:26:27 +00002086_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002087typename enable_if
2088<
2089 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2090 _Tp
2091>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00002092atomic_fetch_and(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002093{
2094 return __o->fetch_and(__op);
2095}
2096
2097// atomic_fetch_and_explicit
2098
2099template <class _Tp>
Louis Dionnea1ae0032019-03-04 15:26:27 +00002100_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002101typename enable_if
2102<
2103 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2104 _Tp
2105>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00002106atomic_fetch_and_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002107{
2108 return __o->fetch_and(__op, __m);
2109}
2110
2111template <class _Tp>
Louis Dionnea1ae0032019-03-04 15:26:27 +00002112_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002113typename enable_if
2114<
2115 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2116 _Tp
2117>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00002118atomic_fetch_and_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002119{
2120 return __o->fetch_and(__op, __m);
2121}
2122
2123// atomic_fetch_or
2124
2125template <class _Tp>
Louis Dionnea1ae0032019-03-04 15:26:27 +00002126_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002127typename enable_if
2128<
2129 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2130 _Tp
2131>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00002132atomic_fetch_or(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002133{
2134 return __o->fetch_or(__op);
2135}
2136
2137template <class _Tp>
Louis Dionnea1ae0032019-03-04 15:26:27 +00002138_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002139typename enable_if
2140<
2141 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2142 _Tp
2143>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00002144atomic_fetch_or(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002145{
2146 return __o->fetch_or(__op);
2147}
2148
2149// atomic_fetch_or_explicit
2150
2151template <class _Tp>
Louis Dionnea1ae0032019-03-04 15:26:27 +00002152_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002153typename enable_if
2154<
2155 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2156 _Tp
2157>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00002158atomic_fetch_or_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002159{
2160 return __o->fetch_or(__op, __m);
2161}
2162
2163template <class _Tp>
Louis Dionnea1ae0032019-03-04 15:26:27 +00002164_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002165typename enable_if
2166<
2167 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2168 _Tp
2169>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00002170atomic_fetch_or_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002171{
2172 return __o->fetch_or(__op, __m);
2173}
2174
2175// atomic_fetch_xor
2176
2177template <class _Tp>
Louis Dionnea1ae0032019-03-04 15:26:27 +00002178_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002179typename enable_if
2180<
2181 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2182 _Tp
2183>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00002184atomic_fetch_xor(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002185{
2186 return __o->fetch_xor(__op);
2187}
2188
2189template <class _Tp>
Louis Dionnea1ae0032019-03-04 15:26:27 +00002190_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002191typename enable_if
2192<
2193 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2194 _Tp
2195>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00002196atomic_fetch_xor(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002197{
2198 return __o->fetch_xor(__op);
2199}
2200
2201// atomic_fetch_xor_explicit
2202
2203template <class _Tp>
Louis Dionnea1ae0032019-03-04 15:26:27 +00002204_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002205typename enable_if
2206<
2207 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2208 _Tp
2209>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00002210atomic_fetch_xor_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002211{
2212 return __o->fetch_xor(__op, __m);
2213}
2214
2215template <class _Tp>
Louis Dionnea1ae0032019-03-04 15:26:27 +00002216_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002217typename enable_if
2218<
2219 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2220 _Tp
2221>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00002222atomic_fetch_xor_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002223{
2224 return __o->fetch_xor(__op, __m);
2225}
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002226
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002227// flag type and operations
2228
2229typedef struct atomic_flag
2230{
Louis Dionnea1ae0032019-03-04 15:26:27 +00002231 __cxx_atomic_impl<_LIBCPP_ATOMIC_FLAG_TYPE> __a_;
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002232
2233 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00002234 bool test_and_set(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Louis Dionnea1ae0032019-03-04 15:26:27 +00002235 {return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);}
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002236 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00002237 bool test_and_set(memory_order __m = memory_order_seq_cst) _NOEXCEPT
Louis Dionnea1ae0032019-03-04 15:26:27 +00002238 {return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);}
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002239 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00002240 void clear(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Louis Dionnea1ae0032019-03-04 15:26:27 +00002241 {__cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);}
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002242 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00002243 void clear(memory_order __m = memory_order_seq_cst) _NOEXCEPT
Louis Dionnea1ae0032019-03-04 15:26:27 +00002244 {__cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);}
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002245
2246 _LIBCPP_INLINE_VISIBILITY
Louis Dionnea1ae0032019-03-04 15:26:27 +00002247 atomic_flag() _NOEXCEPT _LIBCPP_DEFAULT
Howard Hinnant3d284222013-05-02 20:18:43 +00002248
Marshall Clowcf990752018-04-25 14:27:29 +00002249 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
Eric Fiselierfec26a92016-05-03 02:12:26 +00002250 atomic_flag(bool __b) _NOEXCEPT : __a_(__b) {} // EXTENSION
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002251
Eric Fiselier2d8515f2017-01-06 20:58:25 +00002252#ifndef _LIBCPP_CXX03_LANG
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002253 atomic_flag(const atomic_flag&) = delete;
2254 atomic_flag& operator=(const atomic_flag&) = delete;
2255 atomic_flag& operator=(const atomic_flag&) volatile = delete;
Eric Fiselier2d8515f2017-01-06 20:58:25 +00002256#else
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002257private:
2258 atomic_flag(const atomic_flag&);
2259 atomic_flag& operator=(const atomic_flag&);
2260 atomic_flag& operator=(const atomic_flag&) volatile;
Eric Fiselier2d8515f2017-01-06 20:58:25 +00002261#endif
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002262} atomic_flag;
2263
2264inline _LIBCPP_INLINE_VISIBILITY
2265bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00002266atomic_flag_test_and_set(volatile atomic_flag* __o) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002267{
2268 return __o->test_and_set();
2269}
2270
2271inline _LIBCPP_INLINE_VISIBILITY
2272bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00002273atomic_flag_test_and_set(atomic_flag* __o) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002274{
2275 return __o->test_and_set();
2276}
2277
2278inline _LIBCPP_INLINE_VISIBILITY
2279bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00002280atomic_flag_test_and_set_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002281{
2282 return __o->test_and_set(__m);
2283}
2284
2285inline _LIBCPP_INLINE_VISIBILITY
2286bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00002287atomic_flag_test_and_set_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002288{
2289 return __o->test_and_set(__m);
2290}
2291
2292inline _LIBCPP_INLINE_VISIBILITY
2293void
Howard Hinnanteee2c142012-04-11 20:14:21 +00002294atomic_flag_clear(volatile atomic_flag* __o) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002295{
2296 __o->clear();
2297}
2298
2299inline _LIBCPP_INLINE_VISIBILITY
2300void
Howard Hinnanteee2c142012-04-11 20:14:21 +00002301atomic_flag_clear(atomic_flag* __o) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002302{
2303 __o->clear();
2304}
2305
2306inline _LIBCPP_INLINE_VISIBILITY
2307void
Howard Hinnanteee2c142012-04-11 20:14:21 +00002308atomic_flag_clear_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002309{
2310 __o->clear(__m);
2311}
2312
2313inline _LIBCPP_INLINE_VISIBILITY
2314void
Howard Hinnanteee2c142012-04-11 20:14:21 +00002315atomic_flag_clear_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002316{
2317 __o->clear(__m);
2318}
2319
2320// fences
2321
2322inline _LIBCPP_INLINE_VISIBILITY
2323void
Howard Hinnanteee2c142012-04-11 20:14:21 +00002324atomic_thread_fence(memory_order __m) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002325{
Louis Dionnea1ae0032019-03-04 15:26:27 +00002326 __cxx_atomic_thread_fence(__m);
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002327}
2328
2329inline _LIBCPP_INLINE_VISIBILITY
2330void
Howard Hinnanteee2c142012-04-11 20:14:21 +00002331atomic_signal_fence(memory_order __m) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002332{
Louis Dionnea1ae0032019-03-04 15:26:27 +00002333 __cxx_atomic_signal_fence(__m);
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002334}
2335
Howard Hinnant96e4cd62010-12-07 23:24:41 +00002336// Atomics for standard typedef types
2337
Howard Hinnantf0af8d92013-01-04 18:58:50 +00002338typedef atomic<bool> atomic_bool;
Howard Hinnant96e4cd62010-12-07 23:24:41 +00002339typedef atomic<char> atomic_char;
2340typedef atomic<signed char> atomic_schar;
2341typedef atomic<unsigned char> atomic_uchar;
2342typedef atomic<short> atomic_short;
2343typedef atomic<unsigned short> atomic_ushort;
2344typedef atomic<int> atomic_int;
2345typedef atomic<unsigned int> atomic_uint;
2346typedef atomic<long> atomic_long;
2347typedef atomic<unsigned long> atomic_ulong;
2348typedef atomic<long long> atomic_llong;
2349typedef atomic<unsigned long long> atomic_ullong;
2350typedef atomic<char16_t> atomic_char16_t;
2351typedef atomic<char32_t> atomic_char32_t;
2352typedef atomic<wchar_t> atomic_wchar_t;
2353
2354typedef atomic<int_least8_t> atomic_int_least8_t;
2355typedef atomic<uint_least8_t> atomic_uint_least8_t;
2356typedef atomic<int_least16_t> atomic_int_least16_t;
2357typedef atomic<uint_least16_t> atomic_uint_least16_t;
2358typedef atomic<int_least32_t> atomic_int_least32_t;
2359typedef atomic<uint_least32_t> atomic_uint_least32_t;
2360typedef atomic<int_least64_t> atomic_int_least64_t;
2361typedef atomic<uint_least64_t> atomic_uint_least64_t;
2362
2363typedef atomic<int_fast8_t> atomic_int_fast8_t;
2364typedef atomic<uint_fast8_t> atomic_uint_fast8_t;
2365typedef atomic<int_fast16_t> atomic_int_fast16_t;
2366typedef atomic<uint_fast16_t> atomic_uint_fast16_t;
2367typedef atomic<int_fast32_t> atomic_int_fast32_t;
2368typedef atomic<uint_fast32_t> atomic_uint_fast32_t;
2369typedef atomic<int_fast64_t> atomic_int_fast64_t;
2370typedef atomic<uint_fast64_t> atomic_uint_fast64_t;
2371
Marshall Clowf710afc2016-06-30 15:28:38 +00002372typedef atomic< int8_t> atomic_int8_t;
2373typedef atomic<uint8_t> atomic_uint8_t;
2374typedef atomic< int16_t> atomic_int16_t;
2375typedef atomic<uint16_t> atomic_uint16_t;
2376typedef atomic< int32_t> atomic_int32_t;
2377typedef atomic<uint32_t> atomic_uint32_t;
2378typedef atomic< int64_t> atomic_int64_t;
2379typedef atomic<uint64_t> atomic_uint64_t;
2380
Howard Hinnant96e4cd62010-12-07 23:24:41 +00002381typedef atomic<intptr_t> atomic_intptr_t;
2382typedef atomic<uintptr_t> atomic_uintptr_t;
2383typedef atomic<size_t> atomic_size_t;
2384typedef atomic<ptrdiff_t> atomic_ptrdiff_t;
2385typedef atomic<intmax_t> atomic_intmax_t;
2386typedef atomic<uintmax_t> atomic_uintmax_t;
2387
Howard Hinnantf1f066a2010-09-29 21:20:03 +00002388#define ATOMIC_FLAG_INIT {false}
Howard Hinnant953c31d2010-10-04 18:52:54 +00002389#define ATOMIC_VAR_INIT(__v) {__v}
2390
Howard Hinnant71be7292010-09-27 21:17:38 +00002391_LIBCPP_END_NAMESPACE_STD
2392
Howard Hinnant71be7292010-09-27 21:17:38 +00002393#endif // _LIBCPP_ATOMIC