blob: a10e596d498161dd2258a4ed9a82cce63decab43 [file] [log] [blame]
Howard Hinnant71be7292010-09-27 21:17:38 +00001// -*- C++ -*-
2//===--------------------------- atomic -----------------------------------===//
3//
Chandler Carruth7642bb12019-01-19 08:50:56 +00004// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Howard Hinnant71be7292010-09-27 21:17:38 +00007//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP_ATOMIC
11#define _LIBCPP_ATOMIC
12
13/*
14 atomic synopsis
15
16namespace std
17{
18
Olivier Girouxdf5bfa32020-09-09 10:00:09 -070019// feature test macro [version.syn]
JF Bastienfdb42c22016-03-25 15:48:21 +000020
Olivier Girouxdf5bfa32020-09-09 10:00:09 -070021#define __cpp_lib_atomic_is_always_lock_free
22#define __cpp_lib_atomic_flag_test
23#define __cpp_lib_atomic_lock_free_type_aliases
24#define __cpp_lib_atomic_wait
JF Bastienfdb42c22016-03-25 15:48:21 +000025
Davide Italiano011f80a2019-03-05 18:40:49 +000026 // order and consistency
Howard Hinnant71be7292010-09-27 21:17:38 +000027
Davide Italiano011f80a2019-03-05 18:40:49 +000028 enum memory_order: unspecified // enum class in C++20
29 {
30 relaxed,
31 consume, // load-consume
32 acquire, // load-acquire
33 release, // store-release
34 acq_rel, // store-release load-acquire
35 seq_cst // store-release load-acquire
36 };
37
38 inline constexpr auto memory_order_relaxed = memory_order::relaxed;
39 inline constexpr auto memory_order_consume = memory_order::consume;
40 inline constexpr auto memory_order_acquire = memory_order::acquire;
41 inline constexpr auto memory_order_release = memory_order::release;
42 inline constexpr auto memory_order_acq_rel = memory_order::acq_rel;
43 inline constexpr auto memory_order_seq_cst = memory_order::seq_cst;
Howard Hinnant71be7292010-09-27 21:17:38 +000044
Howard Hinnanteee2c142012-04-11 20:14:21 +000045template <class T> T kill_dependency(T y) noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +000046
47// lock-free property
48
Howard Hinnant931e3402013-01-21 20:39:41 +000049#define ATOMIC_BOOL_LOCK_FREE unspecified
Howard Hinnant71be7292010-09-27 21:17:38 +000050#define ATOMIC_CHAR_LOCK_FREE unspecified
Marek Kurdej91bebaa2020-11-24 21:07:06 +010051#define ATOMIC_CHAR8_T_LOCK_FREE unspecified // C++20
Howard Hinnant71be7292010-09-27 21:17:38 +000052#define ATOMIC_CHAR16_T_LOCK_FREE unspecified
53#define ATOMIC_CHAR32_T_LOCK_FREE unspecified
54#define ATOMIC_WCHAR_T_LOCK_FREE unspecified
55#define ATOMIC_SHORT_LOCK_FREE unspecified
56#define ATOMIC_INT_LOCK_FREE unspecified
57#define ATOMIC_LONG_LOCK_FREE unspecified
58#define ATOMIC_LLONG_LOCK_FREE unspecified
Howard Hinnant931e3402013-01-21 20:39:41 +000059#define ATOMIC_POINTER_LOCK_FREE unspecified
Howard Hinnant71be7292010-09-27 21:17:38 +000060
Howard Hinnant71be7292010-09-27 21:17:38 +000061template <class T>
62struct atomic
63{
Olivier Giroux6031a712020-06-01 14:30:13 -070064 using value_type = T;
65
JF Bastienfdb42c22016-03-25 15:48:21 +000066 static constexpr bool is_always_lock_free;
Howard Hinnanteee2c142012-04-11 20:14:21 +000067 bool is_lock_free() const volatile noexcept;
68 bool is_lock_free() const noexcept;
Olivier Giroux6031a712020-06-01 14:30:13 -070069
Raul Tambre4e0e88f2021-06-06 19:02:20 +030070 atomic() noexcept = default; // until C++20
71 constexpr atomic() noexcept(is_nothrow_default_constructible_v<T>); // since C++20
Olivier Giroux6031a712020-06-01 14:30:13 -070072 constexpr atomic(T desr) noexcept;
73 atomic(const atomic&) = delete;
74 atomic& operator=(const atomic&) = delete;
75 atomic& operator=(const atomic&) volatile = delete;
76
Howard Hinnanteee2c142012-04-11 20:14:21 +000077 T load(memory_order m = memory_order_seq_cst) const volatile noexcept;
78 T load(memory_order m = memory_order_seq_cst) const noexcept;
79 operator T() const volatile noexcept;
80 operator T() const noexcept;
Olivier Giroux6031a712020-06-01 14:30:13 -070081 void store(T desr, memory_order m = memory_order_seq_cst) volatile noexcept;
82 void store(T desr, memory_order m = memory_order_seq_cst) noexcept;
83 T operator=(T) volatile noexcept;
84 T operator=(T) noexcept;
85
Howard Hinnanteee2c142012-04-11 20:14:21 +000086 T exchange(T desr, memory_order m = memory_order_seq_cst) volatile noexcept;
87 T exchange(T desr, memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +000088 bool compare_exchange_weak(T& expc, T desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +000089 memory_order s, memory_order f) volatile noexcept;
90 bool compare_exchange_weak(T& expc, T desr, memory_order s, memory_order f) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +000091 bool compare_exchange_strong(T& expc, T desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +000092 memory_order s, memory_order f) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +000093 bool compare_exchange_strong(T& expc, T desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +000094 memory_order s, memory_order f) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +000095 bool compare_exchange_weak(T& expc, T desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +000096 memory_order m = memory_order_seq_cst) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +000097 bool compare_exchange_weak(T& expc, T desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +000098 memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +000099 bool compare_exchange_strong(T& expc, T desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000100 memory_order m = memory_order_seq_cst) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000101 bool compare_exchange_strong(T& expc, T desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000102 memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +0000103
Olivier Giroux6031a712020-06-01 14:30:13 -0700104 void wait(T, memory_order = memory_order::seq_cst) const volatile noexcept;
105 void wait(T, memory_order = memory_order::seq_cst) const noexcept;
106 void notify_one() volatile noexcept;
107 void notify_one() noexcept;
108 void notify_all() volatile noexcept;
109 void notify_all() noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +0000110};
111
112template <>
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000113struct atomic<integral>
Howard Hinnant71be7292010-09-27 21:17:38 +0000114{
Olivier Giroux6031a712020-06-01 14:30:13 -0700115 using value_type = integral;
Olivier Girouxdf5bfa32020-09-09 10:00:09 -0700116 using difference_type = value_type;
Olivier Giroux6031a712020-06-01 14:30:13 -0700117
JF Bastienfdb42c22016-03-25 15:48:21 +0000118 static constexpr bool is_always_lock_free;
Howard Hinnanteee2c142012-04-11 20:14:21 +0000119 bool is_lock_free() const volatile noexcept;
120 bool is_lock_free() const noexcept;
Olivier Giroux6031a712020-06-01 14:30:13 -0700121
122 atomic() noexcept = default;
123 constexpr atomic(integral desr) noexcept;
124 atomic(const atomic&) = delete;
125 atomic& operator=(const atomic&) = delete;
126 atomic& operator=(const atomic&) volatile = delete;
127
Howard Hinnanteee2c142012-04-11 20:14:21 +0000128 integral load(memory_order m = memory_order_seq_cst) const volatile noexcept;
129 integral load(memory_order m = memory_order_seq_cst) const noexcept;
130 operator integral() const volatile noexcept;
131 operator integral() const noexcept;
Olivier Giroux6031a712020-06-01 14:30:13 -0700132 void store(integral desr, memory_order m = memory_order_seq_cst) volatile noexcept;
133 void store(integral desr, memory_order m = memory_order_seq_cst) noexcept;
134 integral operator=(integral desr) volatile noexcept;
135 integral operator=(integral desr) noexcept;
136
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000137 integral exchange(integral desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000138 memory_order m = memory_order_seq_cst) volatile noexcept;
139 integral exchange(integral desr, memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000140 bool compare_exchange_weak(integral& expc, integral desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000141 memory_order s, memory_order f) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000142 bool compare_exchange_weak(integral& expc, integral desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000143 memory_order s, memory_order f) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000144 bool compare_exchange_strong(integral& expc, integral desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000145 memory_order s, memory_order f) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000146 bool compare_exchange_strong(integral& expc, integral desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000147 memory_order s, memory_order f) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000148 bool compare_exchange_weak(integral& expc, integral desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000149 memory_order m = memory_order_seq_cst) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000150 bool compare_exchange_weak(integral& expc, integral desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000151 memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000152 bool compare_exchange_strong(integral& expc, integral desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000153 memory_order m = memory_order_seq_cst) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000154 bool compare_exchange_strong(integral& expc, integral desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000155 memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +0000156
Olivier Giroux6031a712020-06-01 14:30:13 -0700157 integral fetch_add(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
Howard Hinnanteee2c142012-04-11 20:14:21 +0000158 integral fetch_add(integral op, memory_order m = memory_order_seq_cst) noexcept;
Olivier Giroux6031a712020-06-01 14:30:13 -0700159 integral fetch_sub(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
Howard Hinnanteee2c142012-04-11 20:14:21 +0000160 integral fetch_sub(integral op, memory_order m = memory_order_seq_cst) noexcept;
Olivier Giroux6031a712020-06-01 14:30:13 -0700161 integral fetch_and(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
Howard Hinnanteee2c142012-04-11 20:14:21 +0000162 integral fetch_and(integral op, memory_order m = memory_order_seq_cst) noexcept;
Olivier Giroux6031a712020-06-01 14:30:13 -0700163 integral fetch_or(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
Howard Hinnanteee2c142012-04-11 20:14:21 +0000164 integral fetch_or(integral op, memory_order m = memory_order_seq_cst) noexcept;
Olivier Giroux6031a712020-06-01 14:30:13 -0700165 integral fetch_xor(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
Howard Hinnanteee2c142012-04-11 20:14:21 +0000166 integral fetch_xor(integral op, memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +0000167
Howard Hinnanteee2c142012-04-11 20:14:21 +0000168 integral operator++(int) volatile noexcept;
169 integral operator++(int) noexcept;
170 integral operator--(int) volatile noexcept;
171 integral operator--(int) noexcept;
172 integral operator++() volatile noexcept;
173 integral operator++() noexcept;
174 integral operator--() volatile noexcept;
175 integral operator--() noexcept;
176 integral operator+=(integral op) volatile noexcept;
177 integral operator+=(integral op) noexcept;
178 integral operator-=(integral op) volatile noexcept;
179 integral operator-=(integral op) noexcept;
180 integral operator&=(integral op) volatile noexcept;
181 integral operator&=(integral op) noexcept;
182 integral operator|=(integral op) volatile noexcept;
183 integral operator|=(integral op) noexcept;
184 integral operator^=(integral op) volatile noexcept;
185 integral operator^=(integral op) noexcept;
Olivier Giroux6031a712020-06-01 14:30:13 -0700186
187 void wait(integral, memory_order = memory_order::seq_cst) const volatile noexcept;
188 void wait(integral, memory_order = memory_order::seq_cst) const noexcept;
189 void notify_one() volatile noexcept;
190 void notify_one() noexcept;
191 void notify_all() volatile noexcept;
192 void notify_all() noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +0000193};
194
195template <class T>
196struct atomic<T*>
Howard Hinnant71be7292010-09-27 21:17:38 +0000197{
Olivier Giroux6031a712020-06-01 14:30:13 -0700198 using value_type = T*;
Olivier Girouxdf5bfa32020-09-09 10:00:09 -0700199 using difference_type = ptrdiff_t;
Olivier Giroux6031a712020-06-01 14:30:13 -0700200
JF Bastienfdb42c22016-03-25 15:48:21 +0000201 static constexpr bool is_always_lock_free;
Howard Hinnanteee2c142012-04-11 20:14:21 +0000202 bool is_lock_free() const volatile noexcept;
203 bool is_lock_free() const noexcept;
Olivier Giroux6031a712020-06-01 14:30:13 -0700204
Raul Tambre4e0e88f2021-06-06 19:02:20 +0300205 atomic() noexcept = default; // until C++20
206 constexpr atomic() noexcept; // since C++20
Olivier Giroux6031a712020-06-01 14:30:13 -0700207 constexpr atomic(T* desr) noexcept;
208 atomic(const atomic&) = delete;
209 atomic& operator=(const atomic&) = delete;
210 atomic& operator=(const atomic&) volatile = delete;
211
Howard Hinnanteee2c142012-04-11 20:14:21 +0000212 T* load(memory_order m = memory_order_seq_cst) const volatile noexcept;
213 T* load(memory_order m = memory_order_seq_cst) const noexcept;
214 operator T*() const volatile noexcept;
215 operator T*() const noexcept;
Olivier Giroux6031a712020-06-01 14:30:13 -0700216 void store(T* desr, memory_order m = memory_order_seq_cst) volatile noexcept;
217 void store(T* desr, memory_order m = memory_order_seq_cst) noexcept;
218 T* operator=(T*) volatile noexcept;
219 T* operator=(T*) noexcept;
220
Howard Hinnanteee2c142012-04-11 20:14:21 +0000221 T* exchange(T* desr, memory_order m = memory_order_seq_cst) volatile noexcept;
222 T* exchange(T* desr, memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000223 bool compare_exchange_weak(T*& expc, T* desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000224 memory_order s, memory_order f) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000225 bool compare_exchange_weak(T*& expc, T* desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000226 memory_order s, memory_order f) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000227 bool compare_exchange_strong(T*& expc, T* desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000228 memory_order s, memory_order f) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000229 bool compare_exchange_strong(T*& expc, T* desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000230 memory_order s, memory_order f) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000231 bool compare_exchange_weak(T*& expc, T* desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000232 memory_order m = memory_order_seq_cst) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000233 bool compare_exchange_weak(T*& expc, T* desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000234 memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000235 bool compare_exchange_strong(T*& expc, T* desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000236 memory_order m = memory_order_seq_cst) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000237 bool compare_exchange_strong(T*& expc, T* desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000238 memory_order m = memory_order_seq_cst) noexcept;
239 T* fetch_add(ptrdiff_t op, memory_order m = memory_order_seq_cst) volatile noexcept;
240 T* fetch_add(ptrdiff_t op, memory_order m = memory_order_seq_cst) noexcept;
241 T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst) volatile noexcept;
242 T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000243
Howard Hinnanteee2c142012-04-11 20:14:21 +0000244 T* operator++(int) volatile noexcept;
245 T* operator++(int) noexcept;
246 T* operator--(int) volatile noexcept;
247 T* operator--(int) noexcept;
248 T* operator++() volatile noexcept;
249 T* operator++() noexcept;
250 T* operator--() volatile noexcept;
251 T* operator--() noexcept;
252 T* operator+=(ptrdiff_t op) volatile noexcept;
253 T* operator+=(ptrdiff_t op) noexcept;
254 T* operator-=(ptrdiff_t op) volatile noexcept;
255 T* operator-=(ptrdiff_t op) noexcept;
Olivier Giroux6031a712020-06-01 14:30:13 -0700256
257 void wait(T*, memory_order = memory_order::seq_cst) const volatile noexcept;
258 void wait(T*, memory_order = memory_order::seq_cst) const noexcept;
259 void notify_one() volatile noexcept;
260 void notify_one() noexcept;
261 void notify_all() volatile noexcept;
262 void notify_all() noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +0000263};
264
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000265
266template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700267 bool atomic_is_lock_free(const volatile atomic<T>* obj) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000268
269template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700270 bool atomic_is_lock_free(const atomic<T>* obj) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000271
272template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700273 void atomic_store(volatile atomic<T>* obj, T desr) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000274
275template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700276 void atomic_store(atomic<T>* obj, T desr) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000277
278template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700279 void atomic_store_explicit(volatile atomic<T>* obj, T desr, memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000280
281template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700282 void atomic_store_explicit(atomic<T>* obj, T desr, memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000283
284template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700285 T atomic_load(const volatile atomic<T>* obj) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000286
287template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700288 T atomic_load(const atomic<T>* obj) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000289
290template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700291 T atomic_load_explicit(const volatile atomic<T>* obj, memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000292
293template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700294 T atomic_load_explicit(const atomic<T>* obj, memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000295
296template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700297 T atomic_exchange(volatile atomic<T>* obj, T desr) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000298
299template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700300 T atomic_exchange(atomic<T>* obj, T desr) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000301
302template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700303 T atomic_exchange_explicit(volatile atomic<T>* obj, T desr, memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000304
305template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700306 T atomic_exchange_explicit(atomic<T>* obj, T desr, memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000307
308template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700309 bool atomic_compare_exchange_weak(volatile atomic<T>* obj, T* expc, T desr) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000310
311template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700312 bool atomic_compare_exchange_weak(atomic<T>* obj, T* expc, T desr) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000313
314template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700315 bool atomic_compare_exchange_strong(volatile atomic<T>* obj, T* expc, T desr) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000316
317template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700318 bool atomic_compare_exchange_strong(atomic<T>* obj, T* expc, T desr) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000319
320template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700321 bool atomic_compare_exchange_weak_explicit(volatile atomic<T>* obj, T* expc,
322 T desr,
323 memory_order s, memory_order f) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000324
325template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700326 bool atomic_compare_exchange_weak_explicit(atomic<T>* obj, T* expc, T desr,
327 memory_order s, memory_order f) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000328
329template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700330 bool atomic_compare_exchange_strong_explicit(volatile atomic<T>* obj,
331 T* expc, T desr,
332 memory_order s, memory_order f) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000333
334template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700335 bool atomic_compare_exchange_strong_explicit(atomic<T>* obj, T* expc,
336 T desr,
337 memory_order s, memory_order f) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000338
339template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700340 void atomic_wait(const volatile atomic<T>* obj, T old) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000341
342template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700343 void atomic_wait(const atomic<T>* obj, T old) noexcept;
344
345template <class T>
346 void atomic_wait_explicit(const volatile atomic<T>* obj, T old, memory_order m) noexcept;
347
348template <class T>
349 void atomic_wait_explicit(const atomic<T>* obj, T old, memory_order m) noexcept;
350
351template <class T>
352 void atomic_one(volatile atomic<T>* obj) noexcept;
353
354template <class T>
355 void atomic_one(atomic<T>* obj) noexcept;
356
357template <class T>
358 void atomic_all(volatile atomic<T>* obj) noexcept;
359
360template <class T>
361 void atomic_all(atomic<T>* obj) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000362
363template <class Integral>
Olivier Giroux6031a712020-06-01 14:30:13 -0700364 Integral atomic_fetch_add(volatile atomic<Integral>* obj, Integral op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000365
366template <class Integral>
Olivier Giroux6031a712020-06-01 14:30:13 -0700367 Integral atomic_fetch_add(atomic<Integral>* obj, Integral op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000368
369template <class Integral>
Olivier Giroux6031a712020-06-01 14:30:13 -0700370 Integral atomic_fetch_add_explicit(volatile atomic<Integral>* obj, Integral op,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000371 memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000372template <class Integral>
Olivier Giroux6031a712020-06-01 14:30:13 -0700373 Integral atomic_fetch_add_explicit(atomic<Integral>* obj, Integral op,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000374 memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000375template <class Integral>
Olivier Giroux6031a712020-06-01 14:30:13 -0700376 Integral atomic_fetch_sub(volatile atomic<Integral>* obj, Integral op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000377
378template <class Integral>
Olivier Giroux6031a712020-06-01 14:30:13 -0700379 Integral atomic_fetch_sub(atomic<Integral>* obj, Integral op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000380
381template <class Integral>
Olivier Giroux6031a712020-06-01 14:30:13 -0700382 Integral atomic_fetch_sub_explicit(volatile atomic<Integral>* obj, Integral op,
383 memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000384
385template <class Integral>
Olivier Giroux6031a712020-06-01 14:30:13 -0700386 Integral atomic_fetch_sub_explicit(atomic<Integral>* obj, Integral op,
387 memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000388
389template <class Integral>
Olivier Giroux6031a712020-06-01 14:30:13 -0700390 Integral atomic_fetch_and(volatile atomic<Integral>* obj, Integral op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000391
392template <class Integral>
Olivier Giroux6031a712020-06-01 14:30:13 -0700393 Integral atomic_fetch_and(atomic<Integral>* obj, Integral op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000394
395template <class Integral>
Olivier Giroux6031a712020-06-01 14:30:13 -0700396 Integral atomic_fetch_and_explicit(volatile atomic<Integral>* obj, Integral op,
397 memory_order m) noexcept;
398
399template <class Integral>
400 Integral atomic_fetch_and_explicit(atomic<Integral>* obj, Integral op,
401 memory_order m) noexcept;
402
403template <class Integral>
404 Integral atomic_fetch_or(volatile atomic<Integral>* obj, Integral op) noexcept;
405
406template <class Integral>
407 Integral atomic_fetch_or(atomic<Integral>* obj, Integral op) noexcept;
408
409template <class Integral>
410 Integral atomic_fetch_or_explicit(volatile atomic<Integral>* obj, Integral op,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000411 memory_order m) noexcept;
Olivier Giroux6031a712020-06-01 14:30:13 -0700412
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000413template <class Integral>
Olivier Giroux6031a712020-06-01 14:30:13 -0700414 Integral atomic_fetch_or_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 +0000416
417template <class Integral>
Olivier Giroux6031a712020-06-01 14:30:13 -0700418 Integral atomic_fetch_xor(volatile atomic<Integral>* obj, Integral op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000419
420template <class Integral>
Olivier Giroux6031a712020-06-01 14:30:13 -0700421 Integral atomic_fetch_xor(atomic<Integral>* obj, Integral op) noexcept;
422
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000423template <class Integral>
Olivier Giroux6031a712020-06-01 14:30:13 -0700424 Integral atomic_fetch_xor_explicit(volatile atomic<Integral>* obj, Integral op,
425 memory_order m) noexcept;
426
427template <class Integral>
428 Integral atomic_fetch_xor_explicit(atomic<Integral>* obj, Integral op,
429 memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000430
431template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700432 T* atomic_fetch_add(volatile atomic<T*>* obj, ptrdiff_t op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000433
434template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700435 T* atomic_fetch_add(atomic<T*>* obj, ptrdiff_t op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000436
437template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700438 T* atomic_fetch_add_explicit(volatile atomic<T*>* obj, ptrdiff_t op,
439 memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000440
441template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700442 T* atomic_fetch_add_explicit(atomic<T*>* obj, ptrdiff_t op, memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000443
444template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700445 T* atomic_fetch_sub(volatile atomic<T*>* obj, ptrdiff_t op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000446
447template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700448 T* atomic_fetch_sub(atomic<T*>* obj, ptrdiff_t op) noexcept;
449
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000450template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700451 T* atomic_fetch_sub_explicit(volatile atomic<T*>* obj, ptrdiff_t op,
452 memory_order m) noexcept;
453
454template <class T>
455 T* atomic_fetch_sub_explicit(atomic<T*>* obj, ptrdiff_t op, memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000456
457// Atomics for standard typedef types
458
Howard Hinnantf0af8d92013-01-04 18:58:50 +0000459typedef atomic<bool> atomic_bool;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000460typedef atomic<char> atomic_char;
461typedef atomic<signed char> atomic_schar;
462typedef atomic<unsigned char> atomic_uchar;
463typedef atomic<short> atomic_short;
464typedef atomic<unsigned short> atomic_ushort;
465typedef atomic<int> atomic_int;
466typedef atomic<unsigned int> atomic_uint;
467typedef atomic<long> atomic_long;
468typedef atomic<unsigned long> atomic_ulong;
469typedef atomic<long long> atomic_llong;
470typedef atomic<unsigned long long> atomic_ullong;
Marek Kurdej91bebaa2020-11-24 21:07:06 +0100471typedef atomic<char8_t> atomic_char8_t; // C++20
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000472typedef atomic<char16_t> atomic_char16_t;
473typedef atomic<char32_t> atomic_char32_t;
474typedef atomic<wchar_t> atomic_wchar_t;
475
476typedef atomic<int_least8_t> atomic_int_least8_t;
477typedef atomic<uint_least8_t> atomic_uint_least8_t;
478typedef atomic<int_least16_t> atomic_int_least16_t;
479typedef atomic<uint_least16_t> atomic_uint_least16_t;
480typedef atomic<int_least32_t> atomic_int_least32_t;
481typedef atomic<uint_least32_t> atomic_uint_least32_t;
482typedef atomic<int_least64_t> atomic_int_least64_t;
483typedef atomic<uint_least64_t> atomic_uint_least64_t;
484
485typedef atomic<int_fast8_t> atomic_int_fast8_t;
486typedef atomic<uint_fast8_t> atomic_uint_fast8_t;
487typedef atomic<int_fast16_t> atomic_int_fast16_t;
488typedef atomic<uint_fast16_t> atomic_uint_fast16_t;
Louis Dionneb39adc52020-11-04 14:07:59 -0500489typedef atomic<int_fast32_t> atomic_int_fast32_t;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000490typedef atomic<uint_fast32_t> atomic_uint_fast32_t;
491typedef atomic<int_fast64_t> atomic_int_fast64_t;
492typedef atomic<uint_fast64_t> atomic_uint_fast64_t;
493
Marshall Clowf710afc2016-06-30 15:28:38 +0000494typedef atomic<int8_t> atomic_int8_t;
495typedef atomic<uint8_t> atomic_uint8_t;
496typedef atomic<int16_t> atomic_int16_t;
497typedef atomic<uint16_t> atomic_uint16_t;
498typedef atomic<int32_t> atomic_int32_t;
499typedef atomic<uint32_t> atomic_uint32_t;
500typedef atomic<int64_t> atomic_int64_t;
501typedef atomic<uint64_t> atomic_uint64_t;
502
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000503typedef atomic<intptr_t> atomic_intptr_t;
504typedef atomic<uintptr_t> atomic_uintptr_t;
505typedef atomic<size_t> atomic_size_t;
506typedef atomic<ptrdiff_t> atomic_ptrdiff_t;
507typedef atomic<intmax_t> atomic_intmax_t;
508typedef atomic<uintmax_t> atomic_uintmax_t;
509
Olivier Giroux6031a712020-06-01 14:30:13 -0700510// flag type and operations
511
512typedef struct atomic_flag
513{
Raul Tambre4e0e88f2021-06-06 19:02:20 +0300514 atomic_flag() noexcept = default; // until C++20
515 constexpr atomic_flag() noexcept; // since C++20
Olivier Giroux6031a712020-06-01 14:30:13 -0700516 atomic_flag(const atomic_flag&) = delete;
517 atomic_flag& operator=(const atomic_flag&) = delete;
518 atomic_flag& operator=(const atomic_flag&) volatile = delete;
519
520 bool test(memory_order m = memory_order_seq_cst) volatile noexcept;
521 bool test(memory_order m = memory_order_seq_cst) noexcept;
522 bool test_and_set(memory_order m = memory_order_seq_cst) volatile noexcept;
523 bool test_and_set(memory_order m = memory_order_seq_cst) noexcept;
524 void clear(memory_order m = memory_order_seq_cst) volatile noexcept;
525 void clear(memory_order m = memory_order_seq_cst) noexcept;
526
527 void wait(bool, memory_order = memory_order::seq_cst) const volatile noexcept;
528 void wait(bool, memory_order = memory_order::seq_cst) const noexcept;
529 void notify_one() volatile noexcept;
530 void notify_one() noexcept;
531 void notify_all() volatile noexcept;
532 void notify_all() noexcept;
533} atomic_flag;
534
535bool atomic_flag_test(volatile atomic_flag* obj) noexcept;
536bool atomic_flag_test(atomic_flag* obj) noexcept;
537bool atomic_flag_test_explicit(volatile atomic_flag* obj,
538 memory_order m) noexcept;
539bool atomic_flag_test_explicit(atomic_flag* obj, memory_order m) noexcept;
540bool atomic_flag_test_and_set(volatile atomic_flag* obj) noexcept;
541bool atomic_flag_test_and_set(atomic_flag* obj) noexcept;
542bool atomic_flag_test_and_set_explicit(volatile atomic_flag* obj,
543 memory_order m) noexcept;
544bool atomic_flag_test_and_set_explicit(atomic_flag* obj, memory_order m) noexcept;
545void atomic_flag_clear(volatile atomic_flag* obj) noexcept;
546void atomic_flag_clear(atomic_flag* obj) noexcept;
547void atomic_flag_clear_explicit(volatile atomic_flag* obj, memory_order m) noexcept;
548void atomic_flag_clear_explicit(atomic_flag* obj, memory_order m) noexcept;
549
550void atomic_wait(const volatile atomic_flag* obj, T old) noexcept;
551void atomic_wait(const atomic_flag* obj, T old) noexcept;
552void atomic_wait_explicit(const volatile atomic_flag* obj, T old, memory_order m) noexcept;
553void atomic_wait_explicit(const atomic_flag* obj, T old, memory_order m) noexcept;
554void atomic_one(volatile atomic_flag* obj) noexcept;
555void atomic_one(atomic_flag* obj) noexcept;
556void atomic_all(volatile atomic_flag* obj) noexcept;
557void atomic_all(atomic_flag* obj) noexcept;
558
Howard Hinnant71be7292010-09-27 21:17:38 +0000559// fences
560
Howard Hinnanteee2c142012-04-11 20:14:21 +0000561void atomic_thread_fence(memory_order m) noexcept;
562void atomic_signal_fence(memory_order m) noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +0000563
Olivier Giroux6031a712020-06-01 14:30:13 -0700564// deprecated
565
566template <class T>
567 void atomic_init(volatile atomic<T>* obj, typename atomic<T>::value_type desr) noexcept;
568
569template <class T>
570 void atomic_init(atomic<T>* obj, typename atomic<T>::value_type desr) noexcept;
571
572#define ATOMIC_VAR_INIT(value) see below
573
574#define ATOMIC_FLAG_INIT see below
575
Howard Hinnant71be7292010-09-27 21:17:38 +0000576} // std
577
578*/
579
Louis Dionne73912b22020-11-04 15:01:25 -0500580#include <__availability>
Arthur O'Dwyeref181602021-05-19 11:57:04 -0400581#include <__config>
Olivier Giroux161e6e82020-02-18 09:58:34 -0500582#include <__threading_support>
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000583#include <cstddef>
584#include <cstdint>
Olivier Giroux161e6e82020-02-18 09:58:34 -0500585#include <cstring>
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000586#include <type_traits>
Marshall Clow0a1e7502018-09-12 19:41:40 +0000587#include <version>
Howard Hinnant71be7292010-09-27 21:17:38 +0000588
Howard Hinnantaaaa52b2011-10-17 20:05:10 +0000589#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
Howard Hinnant71be7292010-09-27 21:17:38 +0000590#pragma GCC system_header
Howard Hinnantaaaa52b2011-10-17 20:05:10 +0000591#endif
Howard Hinnant71be7292010-09-27 21:17:38 +0000592
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000593#ifdef _LIBCPP_HAS_NO_THREADS
Davide Italiano011f80a2019-03-05 18:40:49 +0000594# error <atomic> is not supported on this single threaded system
Eric Fiselier8020b6c2015-08-19 17:21:46 +0000595#endif
Davide Italiano011f80a2019-03-05 18:40:49 +0000596#ifdef _LIBCPP_HAS_NO_ATOMIC_HEADER
597# error <atomic> is not implemented
Eric Fiselier8020b6c2015-08-19 17:21:46 +0000598#endif
Volodymyr Sapsaif3ed1fd2018-05-15 22:38:31 +0000599#ifdef kill_dependency
Davide Italiano011f80a2019-03-05 18:40:49 +0000600# error C++ standard library is incompatible with <stdatomic.h>
Volodymyr Sapsaif3ed1fd2018-05-15 22:38:31 +0000601#endif
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000602
Eric Fiselierb5ab51d2017-01-13 23:45:39 +0000603#define _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) \
604 _LIBCPP_DIAGNOSE_WARNING(__m == memory_order_consume || \
605 __m == memory_order_acquire || \
606 __m == memory_order_acq_rel, \
607 "memory order argument to atomic operation is invalid")
608
609#define _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) \
610 _LIBCPP_DIAGNOSE_WARNING(__m == memory_order_release || \
611 __m == memory_order_acq_rel, \
612 "memory order argument to atomic operation is invalid")
613
614#define _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__m, __f) \
615 _LIBCPP_DIAGNOSE_WARNING(__f == memory_order_release || \
616 __f == memory_order_acq_rel, \
617 "memory order argument to atomic operation is invalid")
618
Howard Hinnant71be7292010-09-27 21:17:38 +0000619_LIBCPP_BEGIN_NAMESPACE_STD
620
Eric Fiselierd4e3e5b2019-03-08 23:15:54 +0000621// Figure out what the underlying type for `memory_order` would be if it were
622// declared as an unscoped enum (accounting for -fshort-enums). Use this result
623// to pin the underlying type in C++20.
624enum __legacy_memory_order {
625 __mo_relaxed,
626 __mo_consume,
627 __mo_acquire,
628 __mo_release,
629 __mo_acq_rel,
630 __mo_seq_cst
631};
632
633typedef underlying_type<__legacy_memory_order>::type __memory_order_underlying_t;
634
Davide Italiano011f80a2019-03-05 18:40:49 +0000635#if _LIBCPP_STD_VER > 17
636
Eric Fiselierd4e3e5b2019-03-08 23:15:54 +0000637enum class memory_order : __memory_order_underlying_t {
638 relaxed = __mo_relaxed,
639 consume = __mo_consume,
640 acquire = __mo_acquire,
641 release = __mo_release,
642 acq_rel = __mo_acq_rel,
643 seq_cst = __mo_seq_cst
Davide Italiano011f80a2019-03-05 18:40:49 +0000644};
645
646inline constexpr auto memory_order_relaxed = memory_order::relaxed;
647inline constexpr auto memory_order_consume = memory_order::consume;
648inline constexpr auto memory_order_acquire = memory_order::acquire;
649inline constexpr auto memory_order_release = memory_order::release;
650inline constexpr auto memory_order_acq_rel = memory_order::acq_rel;
651inline constexpr auto memory_order_seq_cst = memory_order::seq_cst;
652
Davide Italiano011f80a2019-03-05 18:40:49 +0000653#else
654
655typedef enum memory_order {
Eric Fiselierd4e3e5b2019-03-08 23:15:54 +0000656 memory_order_relaxed = __mo_relaxed,
657 memory_order_consume = __mo_consume,
658 memory_order_acquire = __mo_acquire,
659 memory_order_release = __mo_release,
660 memory_order_acq_rel = __mo_acq_rel,
661 memory_order_seq_cst = __mo_seq_cst,
Howard Hinnantdca6e712010-09-28 17:13:38 +0000662} memory_order;
663
Davide Italiano011f80a2019-03-05 18:40:49 +0000664#endif // _LIBCPP_STD_VER > 17
665
Olivier Giroux161e6e82020-02-18 09:58:34 -0500666template <typename _Tp> _LIBCPP_INLINE_VISIBILITY
667bool __cxx_nonatomic_compare_equal(_Tp const& __lhs, _Tp const& __rhs) {
Arthur O'Dwyer22236632020-12-07 21:50:15 -0500668 return _VSTD::memcmp(&__lhs, &__rhs, sizeof(_Tp)) == 0;
Olivier Giroux161e6e82020-02-18 09:58:34 -0500669}
670
Eric Fiselier51525172019-03-08 23:30:26 +0000671static_assert((is_same<underlying_type<memory_order>::type, __memory_order_underlying_t>::value),
Eric Fiselierd4e3e5b2019-03-08 23:15:54 +0000672 "unexpected underlying type for std::memory_order");
Davide Italiano011f80a2019-03-05 18:40:49 +0000673
674#if defined(_LIBCPP_HAS_GCC_ATOMIC_IMP) || \
Arthur O'Dwyer2fc9b5d2021-04-17 17:03:20 -0400675 defined(_LIBCPP_ATOMIC_ONLY_USE_BUILTINS)
Davide Italiano011f80a2019-03-05 18:40:49 +0000676
677// [atomics.types.generic]p1 guarantees _Tp is trivially copyable. Because
678// the default operator= in an object is not volatile, a byte-by-byte copy
679// is required.
680template <typename _Tp, typename _Tv> _LIBCPP_INLINE_VISIBILITY
681typename enable_if<is_assignable<_Tp&, _Tv>::value>::type
682__cxx_atomic_assign_volatile(_Tp& __a_value, _Tv const& __val) {
683 __a_value = __val;
684}
685template <typename _Tp, typename _Tv> _LIBCPP_INLINE_VISIBILITY
686typename enable_if<is_assignable<_Tp&, _Tv>::value>::type
687__cxx_atomic_assign_volatile(_Tp volatile& __a_value, _Tv volatile const& __val) {
688 volatile char* __to = reinterpret_cast<volatile char*>(&__a_value);
689 volatile char* __end = __to + sizeof(_Tp);
690 volatile const char* __from = reinterpret_cast<volatile const char*>(&__val);
691 while (__to != __end)
692 *__to++ = *__from++;
693}
694
Davide Italiano31f218a2019-03-05 17:38:33 +0000695#endif
Louis Dionnea1ae0032019-03-04 15:26:27 +0000696
Davide Italiano011f80a2019-03-05 18:40:49 +0000697#if defined(_LIBCPP_HAS_GCC_ATOMIC_IMP)
698
699template <typename _Tp>
700struct __cxx_atomic_base_impl {
701
Eric Fiselier684aaca2015-10-14 08:36:22 +0000702 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier07b2b552016-11-18 06:42:17 +0000703#ifndef _LIBCPP_CXX03_LANG
Davide Italiano011f80a2019-03-05 18:40:49 +0000704 __cxx_atomic_base_impl() _NOEXCEPT = default;
Eric Fiselier684aaca2015-10-14 08:36:22 +0000705#else
Davide Italiano011f80a2019-03-05 18:40:49 +0000706 __cxx_atomic_base_impl() _NOEXCEPT : __a_value() {}
Eric Fiselier07b2b552016-11-18 06:42:17 +0000707#endif // _LIBCPP_CXX03_LANG
Davide Italiano011f80a2019-03-05 18:40:49 +0000708 _LIBCPP_CONSTEXPR explicit __cxx_atomic_base_impl(_Tp value) _NOEXCEPT
Eric Fiselier719e0442015-07-14 17:50:27 +0000709 : __a_value(value) {}
Marshall Clow290eb3f2015-01-11 06:15:59 +0000710 _Tp __a_value;
Dan Albert7b65ace2014-08-09 23:51:51 +0000711};
Dan Albert7b65ace2014-08-09 23:51:51 +0000712
Davide Italiano011f80a2019-03-05 18:40:49 +0000713_LIBCPP_INLINE_VISIBILITY inline _LIBCPP_CONSTEXPR int __to_gcc_order(memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000714 // Avoid switch statement to make this a constexpr.
715 return __order == memory_order_relaxed ? __ATOMIC_RELAXED:
716 (__order == memory_order_acquire ? __ATOMIC_ACQUIRE:
717 (__order == memory_order_release ? __ATOMIC_RELEASE:
718 (__order == memory_order_seq_cst ? __ATOMIC_SEQ_CST:
719 (__order == memory_order_acq_rel ? __ATOMIC_ACQ_REL:
720 __ATOMIC_CONSUME))));
721}
722
Davide Italiano011f80a2019-03-05 18:40:49 +0000723_LIBCPP_INLINE_VISIBILITY inline _LIBCPP_CONSTEXPR int __to_gcc_failure_order(memory_order __order) {
Dan Albert48815f22015-01-06 18:39:37 +0000724 // Avoid switch statement to make this a constexpr.
725 return __order == memory_order_relaxed ? __ATOMIC_RELAXED:
726 (__order == memory_order_acquire ? __ATOMIC_ACQUIRE:
727 (__order == memory_order_release ? __ATOMIC_RELAXED:
728 (__order == memory_order_seq_cst ? __ATOMIC_SEQ_CST:
729 (__order == memory_order_acq_rel ? __ATOMIC_ACQUIRE:
730 __ATOMIC_CONSUME))));
731}
732
Davide Italiano011f80a2019-03-05 18:40:49 +0000733template <typename _Tp>
734_LIBCPP_INLINE_VISIBILITY
735void __cxx_atomic_init(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __val) {
736 __cxx_atomic_assign_volatile(__a->__a_value, __val);
737}
Dan Albert7b65ace2014-08-09 23:51:51 +0000738
739template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000740_LIBCPP_INLINE_VISIBILITY
741void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp>* __a, _Tp __val) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000742 __a->__a_value = __val;
743}
744
Davide Italiano011f80a2019-03-05 18:40:49 +0000745_LIBCPP_INLINE_VISIBILITY inline
746void __cxx_atomic_thread_fence(memory_order __order) {
747 __atomic_thread_fence(__to_gcc_order(__order));
748}
749
750_LIBCPP_INLINE_VISIBILITY inline
751void __cxx_atomic_signal_fence(memory_order __order) {
752 __atomic_signal_fence(__to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000753}
754
755template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000756_LIBCPP_INLINE_VISIBILITY
757void __cxx_atomic_store(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __val,
758 memory_order __order) {
Dan Albert48815f22015-01-06 18:39:37 +0000759 __atomic_store(&__a->__a_value, &__val,
Davide Italiano011f80a2019-03-05 18:40:49 +0000760 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000761}
762
763template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000764_LIBCPP_INLINE_VISIBILITY
765void __cxx_atomic_store(__cxx_atomic_base_impl<_Tp>* __a, _Tp __val,
766 memory_order __order) {
767 __atomic_store(&__a->__a_value, &__val,
768 __to_gcc_order(__order));
769}
770
771template <typename _Tp>
772_LIBCPP_INLINE_VISIBILITY
773_Tp __cxx_atomic_load(const volatile __cxx_atomic_base_impl<_Tp>* __a,
774 memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000775 _Tp __ret;
776 __atomic_load(&__a->__a_value, &__ret,
Davide Italiano011f80a2019-03-05 18:40:49 +0000777 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000778 return __ret;
779}
780
781template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000782_LIBCPP_INLINE_VISIBILITY
783_Tp __cxx_atomic_load(const __cxx_atomic_base_impl<_Tp>* __a, memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000784 _Tp __ret;
785 __atomic_load(&__a->__a_value, &__ret,
Davide Italiano011f80a2019-03-05 18:40:49 +0000786 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000787 return __ret;
788}
789
790template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000791_LIBCPP_INLINE_VISIBILITY
792_Tp __cxx_atomic_exchange(volatile __cxx_atomic_base_impl<_Tp>* __a,
793 _Tp __value, memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000794 _Tp __ret;
795 __atomic_exchange(&__a->__a_value, &__value, &__ret,
Davide Italiano011f80a2019-03-05 18:40:49 +0000796 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000797 return __ret;
798}
799
800template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000801_LIBCPP_INLINE_VISIBILITY
802_Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp>* __a, _Tp __value,
803 memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000804 _Tp __ret;
805 __atomic_exchange(&__a->__a_value, &__value, &__ret,
Davide Italiano011f80a2019-03-05 18:40:49 +0000806 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000807 return __ret;
808}
809
810template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000811_LIBCPP_INLINE_VISIBILITY
812bool __cxx_atomic_compare_exchange_strong(
813 volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value,
JF Bastien6e412d92018-05-26 19:44:45 +0000814 memory_order __success, memory_order __failure) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000815 return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
816 false,
Davide Italiano011f80a2019-03-05 18:40:49 +0000817 __to_gcc_order(__success),
818 __to_gcc_failure_order(__failure));
Dan Albert7b65ace2014-08-09 23:51:51 +0000819}
820
821template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000822_LIBCPP_INLINE_VISIBILITY
823bool __cxx_atomic_compare_exchange_strong(
824 __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success,
JF Bastien6e412d92018-05-26 19:44:45 +0000825 memory_order __failure) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000826 return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
827 false,
Davide Italiano011f80a2019-03-05 18:40:49 +0000828 __to_gcc_order(__success),
829 __to_gcc_failure_order(__failure));
Dan Albert7b65ace2014-08-09 23:51:51 +0000830}
831
832template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000833_LIBCPP_INLINE_VISIBILITY
834bool __cxx_atomic_compare_exchange_weak(
835 volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value,
JF Bastien6e412d92018-05-26 19:44:45 +0000836 memory_order __success, memory_order __failure) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000837 return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
838 true,
Davide Italiano011f80a2019-03-05 18:40:49 +0000839 __to_gcc_order(__success),
840 __to_gcc_failure_order(__failure));
Dan Albert7b65ace2014-08-09 23:51:51 +0000841}
842
843template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000844_LIBCPP_INLINE_VISIBILITY
845bool __cxx_atomic_compare_exchange_weak(
846 __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success,
JF Bastien6e412d92018-05-26 19:44:45 +0000847 memory_order __failure) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000848 return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
849 true,
Davide Italiano011f80a2019-03-05 18:40:49 +0000850 __to_gcc_order(__success),
851 __to_gcc_failure_order(__failure));
Dan Albert7b65ace2014-08-09 23:51:51 +0000852}
853
854template <typename _Tp>
855struct __skip_amt { enum {value = 1}; };
856
857template <typename _Tp>
858struct __skip_amt<_Tp*> { enum {value = sizeof(_Tp)}; };
859
860// FIXME: Haven't figured out what the spec says about using arrays with
861// atomic_fetch_add. Force a failure rather than creating bad behavior.
862template <typename _Tp>
863struct __skip_amt<_Tp[]> { };
864template <typename _Tp, int n>
865struct __skip_amt<_Tp[n]> { };
866
867template <typename _Tp, typename _Td>
Davide Italiano011f80a2019-03-05 18:40:49 +0000868_LIBCPP_INLINE_VISIBILITY
869_Tp __cxx_atomic_fetch_add(volatile __cxx_atomic_base_impl<_Tp>* __a,
870 _Td __delta, memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000871 return __atomic_fetch_add(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
Davide Italiano011f80a2019-03-05 18:40:49 +0000872 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000873}
874
875template <typename _Tp, typename _Td>
Davide Italiano011f80a2019-03-05 18:40:49 +0000876_LIBCPP_INLINE_VISIBILITY
877_Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp>* __a, _Td __delta,
878 memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000879 return __atomic_fetch_add(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
Davide Italiano011f80a2019-03-05 18:40:49 +0000880 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000881}
882
883template <typename _Tp, typename _Td>
Davide Italiano011f80a2019-03-05 18:40:49 +0000884_LIBCPP_INLINE_VISIBILITY
885_Tp __cxx_atomic_fetch_sub(volatile __cxx_atomic_base_impl<_Tp>* __a,
886 _Td __delta, memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000887 return __atomic_fetch_sub(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
Davide Italiano011f80a2019-03-05 18:40:49 +0000888 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000889}
890
891template <typename _Tp, typename _Td>
Davide Italiano011f80a2019-03-05 18:40:49 +0000892_LIBCPP_INLINE_VISIBILITY
893_Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp>* __a, _Td __delta,
894 memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000895 return __atomic_fetch_sub(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
Davide Italiano011f80a2019-03-05 18:40:49 +0000896 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000897}
898
899template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000900_LIBCPP_INLINE_VISIBILITY
901_Tp __cxx_atomic_fetch_and(volatile __cxx_atomic_base_impl<_Tp>* __a,
902 _Tp __pattern, memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000903 return __atomic_fetch_and(&__a->__a_value, __pattern,
Davide Italiano011f80a2019-03-05 18:40:49 +0000904 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000905}
906
907template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000908_LIBCPP_INLINE_VISIBILITY
909_Tp __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp>* __a,
910 _Tp __pattern, memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000911 return __atomic_fetch_and(&__a->__a_value, __pattern,
Davide Italiano011f80a2019-03-05 18:40:49 +0000912 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000913}
914
915template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000916_LIBCPP_INLINE_VISIBILITY
917_Tp __cxx_atomic_fetch_or(volatile __cxx_atomic_base_impl<_Tp>* __a,
918 _Tp __pattern, memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000919 return __atomic_fetch_or(&__a->__a_value, __pattern,
Davide Italiano011f80a2019-03-05 18:40:49 +0000920 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000921}
922
923template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000924_LIBCPP_INLINE_VISIBILITY
925_Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern,
926 memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000927 return __atomic_fetch_or(&__a->__a_value, __pattern,
Davide Italiano011f80a2019-03-05 18:40:49 +0000928 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000929}
930
931template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000932_LIBCPP_INLINE_VISIBILITY
933_Tp __cxx_atomic_fetch_xor(volatile __cxx_atomic_base_impl<_Tp>* __a,
934 _Tp __pattern, memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000935 return __atomic_fetch_xor(&__a->__a_value, __pattern,
Davide Italiano011f80a2019-03-05 18:40:49 +0000936 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000937}
938
939template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000940_LIBCPP_INLINE_VISIBILITY
941_Tp __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern,
942 memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000943 return __atomic_fetch_xor(&__a->__a_value, __pattern,
Davide Italiano011f80a2019-03-05 18:40:49 +0000944 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000945}
Davide Italiano011f80a2019-03-05 18:40:49 +0000946
947#define __cxx_atomic_is_lock_free(__s) __atomic_is_lock_free(__s, 0)
948
949#elif defined(_LIBCPP_HAS_C_ATOMIC_IMP)
950
951template <typename _Tp>
952struct __cxx_atomic_base_impl {
953
954 _LIBCPP_INLINE_VISIBILITY
955#ifndef _LIBCPP_CXX03_LANG
956 __cxx_atomic_base_impl() _NOEXCEPT = default;
957#else
958 __cxx_atomic_base_impl() _NOEXCEPT : __a_value() {}
959#endif // _LIBCPP_CXX03_LANG
960 _LIBCPP_CONSTEXPR explicit __cxx_atomic_base_impl(_Tp value) _NOEXCEPT
961 : __a_value(value) {}
Louis Dionnefaa17452019-09-04 12:44:19 +0000962 _LIBCPP_DISABLE_EXTENSION_WARNING _Atomic(_Tp) __a_value;
Davide Italiano011f80a2019-03-05 18:40:49 +0000963};
964
965#define __cxx_atomic_is_lock_free(__s) __c11_atomic_is_lock_free(__s)
966
967_LIBCPP_INLINE_VISIBILITY inline
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000968void __cxx_atomic_thread_fence(memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +0000969 __c11_atomic_thread_fence(static_cast<__memory_order_underlying_t>(__order));
970}
971
972_LIBCPP_INLINE_VISIBILITY inline
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000973void __cxx_atomic_signal_fence(memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +0000974 __c11_atomic_signal_fence(static_cast<__memory_order_underlying_t>(__order));
975}
976
977template<class _Tp>
978_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000979void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __val) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +0000980 __c11_atomic_init(&__a->__a_value, __val);
981}
982template<class _Tp>
983_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000984void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp> * __a, _Tp __val) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +0000985 __c11_atomic_init(&__a->__a_value, __val);
986}
987
988template<class _Tp>
989_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000990void __cxx_atomic_store(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __val, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +0000991 __c11_atomic_store(&__a->__a_value, __val, static_cast<__memory_order_underlying_t>(__order));
992}
993template<class _Tp>
994_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000995void __cxx_atomic_store(__cxx_atomic_base_impl<_Tp> * __a, _Tp __val, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +0000996 __c11_atomic_store(&__a->__a_value, __val, static_cast<__memory_order_underlying_t>(__order));
997}
998
999template<class _Tp>
1000_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001001_Tp __cxx_atomic_load(__cxx_atomic_base_impl<_Tp> const volatile* __a, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +00001002 using __ptr_type = typename remove_const<decltype(__a->__a_value)>::type*;
1003 return __c11_atomic_load(const_cast<__ptr_type>(&__a->__a_value), static_cast<__memory_order_underlying_t>(__order));
1004}
1005template<class _Tp>
1006_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001007_Tp __cxx_atomic_load(__cxx_atomic_base_impl<_Tp> const* __a, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +00001008 using __ptr_type = typename remove_const<decltype(__a->__a_value)>::type*;
1009 return __c11_atomic_load(const_cast<__ptr_type>(&__a->__a_value), static_cast<__memory_order_underlying_t>(__order));
1010}
1011
1012template<class _Tp>
1013_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001014_Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __value, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +00001015 return __c11_atomic_exchange(&__a->__a_value, __value, static_cast<__memory_order_underlying_t>(__order));
1016}
1017template<class _Tp>
1018_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001019_Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp> * __a, _Tp __value, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +00001020 return __c11_atomic_exchange(&__a->__a_value, __value, static_cast<__memory_order_underlying_t>(__order));
1021}
1022
Jordan Rupprechtd2e31a82021-06-15 07:55:23 -07001023_LIBCPP_INLINE_VISIBILITY inline _LIBCPP_CONSTEXPR memory_order __to_failure_order(memory_order __order) {
1024 // Avoid switch statement to make this a constexpr.
1025 return __order == memory_order_release ? memory_order_relaxed:
1026 (__order == memory_order_acq_rel ? memory_order_acquire:
1027 __order);
1028}
1029
Davide Italiano011f80a2019-03-05 18:40:49 +00001030template<class _Tp>
1031_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001032bool __cxx_atomic_compare_exchange_strong(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT {
Jordan Rupprechtd2e31a82021-06-15 07:55:23 -07001033 return __c11_atomic_compare_exchange_strong(&__a->__a_value, __expected, __value, static_cast<__memory_order_underlying_t>(__success), static_cast<__memory_order_underlying_t>(__to_failure_order(__failure)));
Davide Italiano011f80a2019-03-05 18:40:49 +00001034}
1035template<class _Tp>
1036_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001037bool __cxx_atomic_compare_exchange_strong(__cxx_atomic_base_impl<_Tp> * __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT {
Jordan Rupprechtd2e31a82021-06-15 07:55:23 -07001038 return __c11_atomic_compare_exchange_strong(&__a->__a_value, __expected, __value, static_cast<__memory_order_underlying_t>(__success), static_cast<__memory_order_underlying_t>(__to_failure_order(__failure)));
Davide Italiano011f80a2019-03-05 18:40:49 +00001039}
1040
1041template<class _Tp>
1042_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001043bool __cxx_atomic_compare_exchange_weak(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT {
Jordan Rupprechtd2e31a82021-06-15 07:55:23 -07001044 return __c11_atomic_compare_exchange_weak(&__a->__a_value, __expected, __value, static_cast<__memory_order_underlying_t>(__success), static_cast<__memory_order_underlying_t>(__to_failure_order(__failure)));
Davide Italiano011f80a2019-03-05 18:40:49 +00001045}
1046template<class _Tp>
1047_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001048bool __cxx_atomic_compare_exchange_weak(__cxx_atomic_base_impl<_Tp> * __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT {
Jordan Rupprechtd2e31a82021-06-15 07:55:23 -07001049 return __c11_atomic_compare_exchange_weak(&__a->__a_value, __expected, __value, static_cast<__memory_order_underlying_t>(__success), static_cast<__memory_order_underlying_t>(__to_failure_order(__failure)));
Davide Italiano011f80a2019-03-05 18:40:49 +00001050}
1051
1052template<class _Tp>
1053_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001054_Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __delta, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +00001055 return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
1056}
1057template<class _Tp>
1058_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001059_Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp> * __a, _Tp __delta, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +00001060 return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
1061}
1062
1063template<class _Tp>
1064_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001065_Tp* __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp*> volatile* __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +00001066 return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
1067}
1068template<class _Tp>
1069_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001070_Tp* __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp*> * __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +00001071 return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
1072}
1073
1074template<class _Tp>
1075_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001076_Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __delta, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +00001077 return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
1078}
1079template<class _Tp>
1080_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001081_Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp> * __a, _Tp __delta, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +00001082 return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
1083}
1084template<class _Tp>
1085_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001086_Tp* __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp*> volatile* __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +00001087 return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
1088}
1089template<class _Tp>
1090_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001091_Tp* __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp*> * __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +00001092 return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
1093}
1094
1095template<class _Tp>
1096_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001097_Tp __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +00001098 return __c11_atomic_fetch_and(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
1099}
1100template<class _Tp>
1101_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001102_Tp __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +00001103 return __c11_atomic_fetch_and(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
1104}
1105
1106template<class _Tp>
1107_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001108_Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +00001109 return __c11_atomic_fetch_or(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
1110}
1111template<class _Tp>
1112_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001113_Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +00001114 return __c11_atomic_fetch_or(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
1115}
1116
1117template<class _Tp>
1118_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001119_Tp __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +00001120 return __c11_atomic_fetch_xor(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
1121}
1122template<class _Tp>
1123_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001124_Tp __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +00001125 return __c11_atomic_fetch_xor(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
1126}
1127
1128#endif // _LIBCPP_HAS_GCC_ATOMIC_IMP, _LIBCPP_HAS_C_ATOMIC_IMP
Dan Albert7b65ace2014-08-09 23:51:51 +00001129
Howard Hinnantdca6e712010-09-28 17:13:38 +00001130template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001131_LIBCPP_INLINE_VISIBILITY
1132_Tp kill_dependency(_Tp __y) _NOEXCEPT
Howard Hinnantdca6e712010-09-28 17:13:38 +00001133{
1134 return __y;
1135}
Howard Hinnant71be7292010-09-27 21:17:38 +00001136
Eric Fiselierbed42df2017-04-20 23:22:46 +00001137#if defined(__CLANG_ATOMIC_BOOL_LOCK_FREE)
1138# define ATOMIC_BOOL_LOCK_FREE __CLANG_ATOMIC_BOOL_LOCK_FREE
1139# define ATOMIC_CHAR_LOCK_FREE __CLANG_ATOMIC_CHAR_LOCK_FREE
Arthur O'Dwyerafa5d5f2021-04-18 21:47:08 -04001140#ifndef _LIBCPP_HAS_NO_CHAR8_T
Marek Kurdej91bebaa2020-11-24 21:07:06 +01001141# define ATOMIC_CHAR8_T_LOCK_FREE __CLANG_ATOMIC_CHAR8_T_LOCK_FREE
1142#endif
Eric Fiselierbed42df2017-04-20 23:22:46 +00001143# define ATOMIC_CHAR16_T_LOCK_FREE __CLANG_ATOMIC_CHAR16_T_LOCK_FREE
1144# define ATOMIC_CHAR32_T_LOCK_FREE __CLANG_ATOMIC_CHAR32_T_LOCK_FREE
1145# define ATOMIC_WCHAR_T_LOCK_FREE __CLANG_ATOMIC_WCHAR_T_LOCK_FREE
1146# define ATOMIC_SHORT_LOCK_FREE __CLANG_ATOMIC_SHORT_LOCK_FREE
1147# define ATOMIC_INT_LOCK_FREE __CLANG_ATOMIC_INT_LOCK_FREE
1148# define ATOMIC_LONG_LOCK_FREE __CLANG_ATOMIC_LONG_LOCK_FREE
1149# define ATOMIC_LLONG_LOCK_FREE __CLANG_ATOMIC_LLONG_LOCK_FREE
1150# define ATOMIC_POINTER_LOCK_FREE __CLANG_ATOMIC_POINTER_LOCK_FREE
Davide Italiano011f80a2019-03-05 18:40:49 +00001151#elif defined(__GCC_ATOMIC_BOOL_LOCK_FREE)
Eric Fiselierbed42df2017-04-20 23:22:46 +00001152# define ATOMIC_BOOL_LOCK_FREE __GCC_ATOMIC_BOOL_LOCK_FREE
1153# define ATOMIC_CHAR_LOCK_FREE __GCC_ATOMIC_CHAR_LOCK_FREE
Arthur O'Dwyerafa5d5f2021-04-18 21:47:08 -04001154#ifndef _LIBCPP_HAS_NO_CHAR8_T
Marek Kurdej91bebaa2020-11-24 21:07:06 +01001155# define ATOMIC_CHAR8_T_LOCK_FREE __GCC_ATOMIC_CHAR8_T_LOCK_FREE
1156#endif
Eric Fiselierbed42df2017-04-20 23:22:46 +00001157# define ATOMIC_CHAR16_T_LOCK_FREE __GCC_ATOMIC_CHAR16_T_LOCK_FREE
1158# define ATOMIC_CHAR32_T_LOCK_FREE __GCC_ATOMIC_CHAR32_T_LOCK_FREE
1159# define ATOMIC_WCHAR_T_LOCK_FREE __GCC_ATOMIC_WCHAR_T_LOCK_FREE
1160# define ATOMIC_SHORT_LOCK_FREE __GCC_ATOMIC_SHORT_LOCK_FREE
1161# define ATOMIC_INT_LOCK_FREE __GCC_ATOMIC_INT_LOCK_FREE
1162# define ATOMIC_LONG_LOCK_FREE __GCC_ATOMIC_LONG_LOCK_FREE
1163# define ATOMIC_LLONG_LOCK_FREE __GCC_ATOMIC_LLONG_LOCK_FREE
1164# define ATOMIC_POINTER_LOCK_FREE __GCC_ATOMIC_POINTER_LOCK_FREE
1165#endif
JF Bastienfdb42c22016-03-25 15:48:21 +00001166
Davide Italiano011f80a2019-03-05 18:40:49 +00001167#ifdef _LIBCPP_ATOMIC_ONLY_USE_BUILTINS
1168
1169template<typename _Tp>
1170struct __cxx_atomic_lock_impl {
1171
1172 _LIBCPP_INLINE_VISIBILITY
1173 __cxx_atomic_lock_impl() _NOEXCEPT
1174 : __a_value(), __a_lock(0) {}
1175 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR explicit
1176 __cxx_atomic_lock_impl(_Tp value) _NOEXCEPT
1177 : __a_value(value), __a_lock(0) {}
1178
1179 _Tp __a_value;
1180 mutable __cxx_atomic_base_impl<_LIBCPP_ATOMIC_FLAG_TYPE> __a_lock;
1181
1182 _LIBCPP_INLINE_VISIBILITY void __lock() const volatile {
1183 while(1 == __cxx_atomic_exchange(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(true), memory_order_acquire))
1184 /*spin*/;
1185 }
1186 _LIBCPP_INLINE_VISIBILITY void __lock() const {
1187 while(1 == __cxx_atomic_exchange(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(true), memory_order_acquire))
1188 /*spin*/;
1189 }
1190 _LIBCPP_INLINE_VISIBILITY void __unlock() const volatile {
1191 __cxx_atomic_store(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(false), memory_order_release);
1192 }
1193 _LIBCPP_INLINE_VISIBILITY void __unlock() const {
1194 __cxx_atomic_store(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(false), memory_order_release);
1195 }
1196 _LIBCPP_INLINE_VISIBILITY _Tp __read() const volatile {
1197 __lock();
1198 _Tp __old;
1199 __cxx_atomic_assign_volatile(__old, __a_value);
1200 __unlock();
1201 return __old;
1202 }
1203 _LIBCPP_INLINE_VISIBILITY _Tp __read() const {
1204 __lock();
1205 _Tp __old = __a_value;
1206 __unlock();
1207 return __old;
1208 }
1209};
1210
1211template <typename _Tp>
1212_LIBCPP_INLINE_VISIBILITY
1213void __cxx_atomic_init(volatile __cxx_atomic_lock_impl<_Tp>* __a, _Tp __val) {
1214 __cxx_atomic_assign_volatile(__a->__a_value, __val);
1215}
1216template <typename _Tp>
1217_LIBCPP_INLINE_VISIBILITY
1218void __cxx_atomic_init(__cxx_atomic_lock_impl<_Tp>* __a, _Tp __val) {
1219 __a->__a_value = __val;
1220}
1221
1222template <typename _Tp>
1223_LIBCPP_INLINE_VISIBILITY
1224void __cxx_atomic_store(volatile __cxx_atomic_lock_impl<_Tp>* __a, _Tp __val, memory_order) {
1225 __a->__lock();
1226 __cxx_atomic_assign_volatile(__a->__a_value, __val);
1227 __a->__unlock();
1228}
1229template <typename _Tp>
1230_LIBCPP_INLINE_VISIBILITY
1231void __cxx_atomic_store(__cxx_atomic_lock_impl<_Tp>* __a, _Tp __val, memory_order) {
1232 __a->__lock();
1233 __a->__a_value = __val;
1234 __a->__unlock();
1235}
1236
1237template <typename _Tp>
1238_LIBCPP_INLINE_VISIBILITY
1239_Tp __cxx_atomic_load(const volatile __cxx_atomic_lock_impl<_Tp>* __a, memory_order) {
1240 return __a->__read();
1241}
1242template <typename _Tp>
1243_LIBCPP_INLINE_VISIBILITY
1244_Tp __cxx_atomic_load(const __cxx_atomic_lock_impl<_Tp>* __a, memory_order) {
1245 return __a->__read();
1246}
1247
1248template <typename _Tp>
1249_LIBCPP_INLINE_VISIBILITY
1250_Tp __cxx_atomic_exchange(volatile __cxx_atomic_lock_impl<_Tp>* __a, _Tp __value, 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, __value);
1255 __a->__unlock();
1256 return __old;
1257}
1258template <typename _Tp>
1259_LIBCPP_INLINE_VISIBILITY
1260_Tp __cxx_atomic_exchange(__cxx_atomic_lock_impl<_Tp>* __a, _Tp __value, memory_order) {
1261 __a->__lock();
1262 _Tp __old = __a->__a_value;
1263 __a->__a_value = __value;
1264 __a->__unlock();
1265 return __old;
1266}
1267
1268template <typename _Tp>
1269_LIBCPP_INLINE_VISIBILITY
1270bool __cxx_atomic_compare_exchange_strong(volatile __cxx_atomic_lock_impl<_Tp>* __a,
1271 _Tp* __expected, _Tp __value, memory_order, memory_order) {
Olivier Giroux161e6e82020-02-18 09:58:34 -05001272 _Tp __temp;
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07001273 __a->__lock();
Olivier Giroux161e6e82020-02-18 09:58:34 -05001274 __cxx_atomic_assign_volatile(__temp, __a->__a_value);
Arthur O'Dwyer22236632020-12-07 21:50:15 -05001275 bool __ret = (_VSTD::memcmp(&__temp, __expected, sizeof(_Tp)) == 0);
Davide Italiano011f80a2019-03-05 18:40:49 +00001276 if(__ret)
1277 __cxx_atomic_assign_volatile(__a->__a_value, __value);
1278 else
1279 __cxx_atomic_assign_volatile(*__expected, __a->__a_value);
1280 __a->__unlock();
1281 return __ret;
1282}
1283template <typename _Tp>
1284_LIBCPP_INLINE_VISIBILITY
1285bool __cxx_atomic_compare_exchange_strong(__cxx_atomic_lock_impl<_Tp>* __a,
1286 _Tp* __expected, _Tp __value, memory_order, memory_order) {
1287 __a->__lock();
Arthur O'Dwyer22236632020-12-07 21:50:15 -05001288 bool __ret = (_VSTD::memcmp(&__a->__a_value, __expected, sizeof(_Tp)) == 0);
Davide Italiano011f80a2019-03-05 18:40:49 +00001289 if(__ret)
Arthur O'Dwyer22236632020-12-07 21:50:15 -05001290 _VSTD::memcpy(&__a->__a_value, &__value, sizeof(_Tp));
Davide Italiano011f80a2019-03-05 18:40:49 +00001291 else
Arthur O'Dwyer22236632020-12-07 21:50:15 -05001292 _VSTD::memcpy(__expected, &__a->__a_value, sizeof(_Tp));
Davide Italiano011f80a2019-03-05 18:40:49 +00001293 __a->__unlock();
1294 return __ret;
1295}
1296
1297template <typename _Tp>
1298_LIBCPP_INLINE_VISIBILITY
1299bool __cxx_atomic_compare_exchange_weak(volatile __cxx_atomic_lock_impl<_Tp>* __a,
1300 _Tp* __expected, _Tp __value, memory_order, memory_order) {
Olivier Giroux161e6e82020-02-18 09:58:34 -05001301 _Tp __temp;
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07001302 __a->__lock();
Olivier Giroux161e6e82020-02-18 09:58:34 -05001303 __cxx_atomic_assign_volatile(__temp, __a->__a_value);
Arthur O'Dwyer22236632020-12-07 21:50:15 -05001304 bool __ret = (_VSTD::memcmp(&__temp, __expected, sizeof(_Tp)) == 0);
Davide Italiano011f80a2019-03-05 18:40:49 +00001305 if(__ret)
1306 __cxx_atomic_assign_volatile(__a->__a_value, __value);
1307 else
1308 __cxx_atomic_assign_volatile(*__expected, __a->__a_value);
1309 __a->__unlock();
1310 return __ret;
1311}
1312template <typename _Tp>
1313_LIBCPP_INLINE_VISIBILITY
1314bool __cxx_atomic_compare_exchange_weak(__cxx_atomic_lock_impl<_Tp>* __a,
1315 _Tp* __expected, _Tp __value, memory_order, memory_order) {
1316 __a->__lock();
Arthur O'Dwyer22236632020-12-07 21:50:15 -05001317 bool __ret = (_VSTD::memcmp(&__a->__a_value, __expected, sizeof(_Tp)) == 0);
Davide Italiano011f80a2019-03-05 18:40:49 +00001318 if(__ret)
Arthur O'Dwyer22236632020-12-07 21:50:15 -05001319 _VSTD::memcpy(&__a->__a_value, &__value, sizeof(_Tp));
Davide Italiano011f80a2019-03-05 18:40:49 +00001320 else
Arthur O'Dwyer22236632020-12-07 21:50:15 -05001321 _VSTD::memcpy(__expected, &__a->__a_value, sizeof(_Tp));
Davide Italiano011f80a2019-03-05 18:40:49 +00001322 __a->__unlock();
1323 return __ret;
1324}
1325
1326template <typename _Tp, typename _Td>
1327_LIBCPP_INLINE_VISIBILITY
1328_Tp __cxx_atomic_fetch_add(volatile __cxx_atomic_lock_impl<_Tp>* __a,
1329 _Td __delta, memory_order) {
1330 __a->__lock();
1331 _Tp __old;
1332 __cxx_atomic_assign_volatile(__old, __a->__a_value);
1333 __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old + __delta));
1334 __a->__unlock();
1335 return __old;
1336}
1337template <typename _Tp, typename _Td>
1338_LIBCPP_INLINE_VISIBILITY
1339_Tp __cxx_atomic_fetch_add(__cxx_atomic_lock_impl<_Tp>* __a,
1340 _Td __delta, memory_order) {
1341 __a->__lock();
1342 _Tp __old = __a->__a_value;
1343 __a->__a_value += __delta;
1344 __a->__unlock();
1345 return __old;
1346}
1347
1348template <typename _Tp, typename _Td>
1349_LIBCPP_INLINE_VISIBILITY
1350_Tp* __cxx_atomic_fetch_add(volatile __cxx_atomic_lock_impl<_Tp*>* __a,
1351 ptrdiff_t __delta, memory_order) {
1352 __a->__lock();
1353 _Tp* __old;
1354 __cxx_atomic_assign_volatile(__old, __a->__a_value);
1355 __cxx_atomic_assign_volatile(__a->__a_value, __old + __delta);
1356 __a->__unlock();
1357 return __old;
1358}
1359template <typename _Tp, typename _Td>
1360_LIBCPP_INLINE_VISIBILITY
1361_Tp* __cxx_atomic_fetch_add(__cxx_atomic_lock_impl<_Tp*>* __a,
1362 ptrdiff_t __delta, memory_order) {
1363 __a->__lock();
1364 _Tp* __old = __a->__a_value;
1365 __a->__a_value += __delta;
1366 __a->__unlock();
1367 return __old;
1368}
1369
1370template <typename _Tp, typename _Td>
1371_LIBCPP_INLINE_VISIBILITY
1372_Tp __cxx_atomic_fetch_sub(volatile __cxx_atomic_lock_impl<_Tp>* __a,
1373 _Td __delta, memory_order) {
1374 __a->__lock();
1375 _Tp __old;
1376 __cxx_atomic_assign_volatile(__old, __a->__a_value);
1377 __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old - __delta));
1378 __a->__unlock();
1379 return __old;
1380}
1381template <typename _Tp, typename _Td>
1382_LIBCPP_INLINE_VISIBILITY
1383_Tp __cxx_atomic_fetch_sub(__cxx_atomic_lock_impl<_Tp>* __a,
1384 _Td __delta, memory_order) {
1385 __a->__lock();
1386 _Tp __old = __a->__a_value;
1387 __a->__a_value -= __delta;
1388 __a->__unlock();
1389 return __old;
1390}
1391
1392template <typename _Tp>
1393_LIBCPP_INLINE_VISIBILITY
1394_Tp __cxx_atomic_fetch_and(volatile __cxx_atomic_lock_impl<_Tp>* __a,
1395 _Tp __pattern, memory_order) {
1396 __a->__lock();
1397 _Tp __old;
1398 __cxx_atomic_assign_volatile(__old, __a->__a_value);
1399 __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old & __pattern));
1400 __a->__unlock();
1401 return __old;
1402}
1403template <typename _Tp>
1404_LIBCPP_INLINE_VISIBILITY
1405_Tp __cxx_atomic_fetch_and(__cxx_atomic_lock_impl<_Tp>* __a,
1406 _Tp __pattern, memory_order) {
1407 __a->__lock();
1408 _Tp __old = __a->__a_value;
1409 __a->__a_value &= __pattern;
1410 __a->__unlock();
1411 return __old;
1412}
1413
1414template <typename _Tp>
1415_LIBCPP_INLINE_VISIBILITY
1416_Tp __cxx_atomic_fetch_or(volatile __cxx_atomic_lock_impl<_Tp>* __a,
1417 _Tp __pattern, memory_order) {
1418 __a->__lock();
1419 _Tp __old;
1420 __cxx_atomic_assign_volatile(__old, __a->__a_value);
1421 __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old | __pattern));
1422 __a->__unlock();
1423 return __old;
1424}
1425template <typename _Tp>
1426_LIBCPP_INLINE_VISIBILITY
1427_Tp __cxx_atomic_fetch_or(__cxx_atomic_lock_impl<_Tp>* __a,
1428 _Tp __pattern, memory_order) {
1429 __a->__lock();
1430 _Tp __old = __a->__a_value;
1431 __a->__a_value |= __pattern;
1432 __a->__unlock();
1433 return __old;
1434}
1435
1436template <typename _Tp>
1437_LIBCPP_INLINE_VISIBILITY
1438_Tp __cxx_atomic_fetch_xor(volatile __cxx_atomic_lock_impl<_Tp>* __a,
1439 _Tp __pattern, memory_order) {
1440 __a->__lock();
1441 _Tp __old;
1442 __cxx_atomic_assign_volatile(__old, __a->__a_value);
1443 __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old ^ __pattern));
1444 __a->__unlock();
1445 return __old;
1446}
1447template <typename _Tp>
1448_LIBCPP_INLINE_VISIBILITY
1449_Tp __cxx_atomic_fetch_xor(__cxx_atomic_lock_impl<_Tp>* __a,
1450 _Tp __pattern, memory_order) {
1451 __a->__lock();
1452 _Tp __old = __a->__a_value;
1453 __a->__a_value ^= __pattern;
1454 __a->__unlock();
1455 return __old;
1456}
1457
1458#ifdef __cpp_lib_atomic_is_always_lock_free
1459
1460template<typename _Tp> struct __cxx_is_always_lock_free {
1461 enum { __value = __atomic_always_lock_free(sizeof(_Tp), 0) }; };
1462
1463#else
1464
1465template<typename _Tp> struct __cxx_is_always_lock_free { enum { __value = false }; };
1466// Implementations must match the C ATOMIC_*_LOCK_FREE macro values.
1467template<> struct __cxx_is_always_lock_free<bool> { enum { __value = 2 == ATOMIC_BOOL_LOCK_FREE }; };
1468template<> struct __cxx_is_always_lock_free<char> { enum { __value = 2 == ATOMIC_CHAR_LOCK_FREE }; };
1469template<> struct __cxx_is_always_lock_free<signed char> { enum { __value = 2 == ATOMIC_CHAR_LOCK_FREE }; };
1470template<> struct __cxx_is_always_lock_free<unsigned char> { enum { __value = 2 == ATOMIC_CHAR_LOCK_FREE }; };
Arthur O'Dwyerafa5d5f2021-04-18 21:47:08 -04001471#ifndef _LIBCPP_HAS_NO_CHAR8_T
Marek Kurdej91bebaa2020-11-24 21:07:06 +01001472template<> struct __cxx_is_always_lock_free<char8_t> { enum { __value = 2 == ATOMIC_CHAR8_T_LOCK_FREE }; };
1473#endif
Davide Italiano011f80a2019-03-05 18:40:49 +00001474template<> struct __cxx_is_always_lock_free<char16_t> { enum { __value = 2 == ATOMIC_CHAR16_T_LOCK_FREE }; };
1475template<> struct __cxx_is_always_lock_free<char32_t> { enum { __value = 2 == ATOMIC_CHAR32_T_LOCK_FREE }; };
Louis Dionne89258142021-08-23 15:32:36 -04001476#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Davide Italiano011f80a2019-03-05 18:40:49 +00001477template<> struct __cxx_is_always_lock_free<wchar_t> { enum { __value = 2 == ATOMIC_WCHAR_T_LOCK_FREE }; };
Louis Dionne89258142021-08-23 15:32:36 -04001478#endif
Davide Italiano011f80a2019-03-05 18:40:49 +00001479template<> struct __cxx_is_always_lock_free<short> { enum { __value = 2 == ATOMIC_SHORT_LOCK_FREE }; };
1480template<> struct __cxx_is_always_lock_free<unsigned short> { enum { __value = 2 == ATOMIC_SHORT_LOCK_FREE }; };
1481template<> struct __cxx_is_always_lock_free<int> { enum { __value = 2 == ATOMIC_INT_LOCK_FREE }; };
1482template<> struct __cxx_is_always_lock_free<unsigned int> { enum { __value = 2 == ATOMIC_INT_LOCK_FREE }; };
1483template<> struct __cxx_is_always_lock_free<long> { enum { __value = 2 == ATOMIC_LONG_LOCK_FREE }; };
1484template<> struct __cxx_is_always_lock_free<unsigned long> { enum { __value = 2 == ATOMIC_LONG_LOCK_FREE }; };
1485template<> struct __cxx_is_always_lock_free<long long> { enum { __value = 2 == ATOMIC_LLONG_LOCK_FREE }; };
1486template<> struct __cxx_is_always_lock_free<unsigned long long> { enum { __value = 2 == ATOMIC_LLONG_LOCK_FREE }; };
1487template<typename _Tp> struct __cxx_is_always_lock_free<_Tp*> { enum { __value = 2 == ATOMIC_POINTER_LOCK_FREE }; };
1488template<> struct __cxx_is_always_lock_free<std::nullptr_t> { enum { __value = 2 == ATOMIC_POINTER_LOCK_FREE }; };
1489
1490#endif //__cpp_lib_atomic_is_always_lock_free
1491
1492template <typename _Tp,
1493 typename _Base = typename conditional<__cxx_is_always_lock_free<_Tp>::__value,
1494 __cxx_atomic_base_impl<_Tp>,
1495 __cxx_atomic_lock_impl<_Tp> >::type>
1496#else
1497template <typename _Tp,
1498 typename _Base = __cxx_atomic_base_impl<_Tp> >
1499#endif //_LIBCPP_ATOMIC_ONLY_USE_BUILTINS
1500struct __cxx_atomic_impl : public _Base {
Davide Italiano011f80a2019-03-05 18:40:49 +00001501 static_assert(is_trivially_copyable<_Tp>::value,
1502 "std::atomic<Tp> requires that 'Tp' be a trivially copyable type");
Davide Italiano011f80a2019-03-05 18:40:49 +00001503
1504 _LIBCPP_INLINE_VISIBILITY __cxx_atomic_impl() _NOEXCEPT _LIBCPP_DEFAULT
1505 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR explicit __cxx_atomic_impl(_Tp value) _NOEXCEPT
1506 : _Base(value) {}
1507};
1508
Olivier Giroux161e6e82020-02-18 09:58:34 -05001509#ifdef __linux__
1510 using __cxx_contention_t = int32_t;
1511#else
1512 using __cxx_contention_t = int64_t;
1513#endif //__linux__
1514
Olivier Giroux161e6e82020-02-18 09:58:34 -05001515using __cxx_atomic_contention_t = __cxx_atomic_impl<__cxx_contention_t>;
1516
1517#ifndef _LIBCPP_HAS_NO_PLATFORM_WAIT
1518
Louis Dionne48a828b2020-02-24 10:08:41 -05001519_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_one(void const volatile*);
1520_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_all(void const volatile*);
1521_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t __libcpp_atomic_monitor(void const volatile*);
1522_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __libcpp_atomic_wait(void const volatile*, __cxx_contention_t);
Olivier Giroux161e6e82020-02-18 09:58:34 -05001523
Louis Dionne48a828b2020-02-24 10:08:41 -05001524_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_one(__cxx_atomic_contention_t const volatile*);
1525_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_all(__cxx_atomic_contention_t const volatile*);
1526_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t __libcpp_atomic_monitor(__cxx_atomic_contention_t const volatile*);
1527_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __libcpp_atomic_wait(__cxx_atomic_contention_t const volatile*, __cxx_contention_t);
Olivier Giroux161e6e82020-02-18 09:58:34 -05001528
1529template <class _Atp, class _Fn>
Louis Dionne08cd5cb2020-02-24 11:39:48 -05001530struct __libcpp_atomic_wait_backoff_impl {
1531 _Atp* __a;
1532 _Fn __test_fn;
Louis Dionne3dde4ab2020-02-24 10:09:29 -05001533 _LIBCPP_AVAILABILITY_SYNC
Louis Dionne08cd5cb2020-02-24 11:39:48 -05001534 _LIBCPP_INLINE_VISIBILITY bool operator()(chrono::nanoseconds __elapsed) const
1535 {
Olivier Giroux161e6e82020-02-18 09:58:34 -05001536 if(__elapsed > chrono::microseconds(64))
1537 {
1538 auto const __monitor = __libcpp_atomic_monitor(__a);
1539 if(__test_fn())
1540 return true;
1541 __libcpp_atomic_wait(__a, __monitor);
1542 }
1543 else if(__elapsed > chrono::microseconds(4))
1544 __libcpp_thread_yield();
1545 else
Marek Kurdejc79652f2020-11-15 16:17:52 +01001546 {} // poll
Olivier Giroux161e6e82020-02-18 09:58:34 -05001547 return false;
Louis Dionne08cd5cb2020-02-24 11:39:48 -05001548 }
1549};
1550
1551template <class _Atp, class _Fn>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05001552_LIBCPP_AVAILABILITY_SYNC
Louis Dionne08cd5cb2020-02-24 11:39:48 -05001553_LIBCPP_INLINE_VISIBILITY bool __cxx_atomic_wait(_Atp* __a, _Fn && __test_fn)
1554{
1555 __libcpp_atomic_wait_backoff_impl<_Atp, typename decay<_Fn>::type> __backoff_fn = {__a, __test_fn};
1556 return __libcpp_thread_poll_with_backoff(__test_fn, __backoff_fn);
Olivier Giroux161e6e82020-02-18 09:58:34 -05001557}
1558
1559#else // _LIBCPP_HAS_NO_PLATFORM_WAIT
1560
1561template <class _Tp>
1562_LIBCPP_INLINE_VISIBILITY void __cxx_atomic_notify_all(__cxx_atomic_impl<_Tp> const volatile*) { }
1563template <class _Tp>
1564_LIBCPP_INLINE_VISIBILITY void __cxx_atomic_notify_one(__cxx_atomic_impl<_Tp> const volatile*) { }
1565template <class _Atp, class _Fn>
1566_LIBCPP_INLINE_VISIBILITY bool __cxx_atomic_wait(_Atp*, _Fn && __test_fn)
1567{
1568 return __libcpp_thread_poll_with_backoff(__test_fn, __libcpp_timed_backoff_policy());
1569}
1570
1571#endif // _LIBCPP_HAS_NO_PLATFORM_WAIT
1572
1573template <class _Atp, class _Tp>
Louis Dionne08cd5cb2020-02-24 11:39:48 -05001574struct __cxx_atomic_wait_test_fn_impl {
1575 _Atp* __a;
1576 _Tp __val;
1577 memory_order __order;
1578 _LIBCPP_INLINE_VISIBILITY bool operator()() const
1579 {
1580 return !__cxx_nonatomic_compare_equal(__cxx_atomic_load(__a, __order), __val);
1581 }
1582};
1583
1584template <class _Atp, class _Tp>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05001585_LIBCPP_AVAILABILITY_SYNC
Olivier Giroux161e6e82020-02-18 09:58:34 -05001586_LIBCPP_INLINE_VISIBILITY bool __cxx_atomic_wait(_Atp* __a, _Tp const __val, memory_order __order)
1587{
Louis Dionne08cd5cb2020-02-24 11:39:48 -05001588 __cxx_atomic_wait_test_fn_impl<_Atp, _Tp> __test_fn = {__a, __val, __order};
Olivier Giroux161e6e82020-02-18 09:58:34 -05001589 return __cxx_atomic_wait(__a, __test_fn);
1590}
1591
Howard Hinnant138f5922010-12-07 20:46:14 +00001592// general atomic<T>
1593
1594template <class _Tp, bool = is_integral<_Tp>::value && !is_same<_Tp, bool>::value>
1595struct __atomic_base // false
1596{
Davide Italiano011f80a2019-03-05 18:40:49 +00001597 mutable __cxx_atomic_impl<_Tp> __a_;
Howard Hinnant138f5922010-12-07 20:46:14 +00001598
JF Bastienfdb42c22016-03-25 15:48:21 +00001599#if defined(__cpp_lib_atomic_is_always_lock_free)
1600 static _LIBCPP_CONSTEXPR bool is_always_lock_free = __atomic_always_lock_free(sizeof(__a_), 0);
1601#endif
1602
Howard Hinnant138f5922010-12-07 20:46:14 +00001603 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001604 bool is_lock_free() const volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001605 {return __cxx_atomic_is_lock_free(sizeof(_Tp));}
Howard Hinnant138f5922010-12-07 20:46:14 +00001606 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001607 bool is_lock_free() const _NOEXCEPT
Eric Fiselier3fd22c22015-06-13 00:23:07 +00001608 {return static_cast<__atomic_base const volatile*>(this)->is_lock_free();}
Howard Hinnant138f5922010-12-07 20:46:14 +00001609 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001610 void store(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001611 _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
Davide Italiano011f80a2019-03-05 18:40:49 +00001612 {__cxx_atomic_store(&__a_, __d, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001613 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001614 void store(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001615 _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
Davide Italiano011f80a2019-03-05 18:40:49 +00001616 {__cxx_atomic_store(&__a_, __d, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001617 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001618 _Tp load(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001619 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
Davide Italiano011f80a2019-03-05 18:40:49 +00001620 {return __cxx_atomic_load(&__a_, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001621 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001622 _Tp load(memory_order __m = memory_order_seq_cst) const _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001623 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
Davide Italiano011f80a2019-03-05 18:40:49 +00001624 {return __cxx_atomic_load(&__a_, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001625 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001626 operator _Tp() const volatile _NOEXCEPT {return load();}
Howard Hinnant138f5922010-12-07 20:46:14 +00001627 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001628 operator _Tp() const _NOEXCEPT {return load();}
Howard Hinnant138f5922010-12-07 20:46:14 +00001629 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001630 _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001631 {return __cxx_atomic_exchange(&__a_, __d, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001632 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001633 _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001634 {return __cxx_atomic_exchange(&__a_, __d, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001635 _LIBCPP_INLINE_VISIBILITY
1636 bool compare_exchange_weak(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001637 memory_order __s, memory_order __f) volatile _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001638 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Davide Italiano011f80a2019-03-05 18:40:49 +00001639 {return __cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001640 _LIBCPP_INLINE_VISIBILITY
1641 bool compare_exchange_weak(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001642 memory_order __s, memory_order __f) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001643 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Davide Italiano011f80a2019-03-05 18:40:49 +00001644 {return __cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001645 _LIBCPP_INLINE_VISIBILITY
1646 bool compare_exchange_strong(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001647 memory_order __s, memory_order __f) volatile _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001648 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Davide Italiano011f80a2019-03-05 18:40:49 +00001649 {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001650 _LIBCPP_INLINE_VISIBILITY
1651 bool compare_exchange_strong(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001652 memory_order __s, memory_order __f) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001653 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Davide Italiano011f80a2019-03-05 18:40:49 +00001654 {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001655 _LIBCPP_INLINE_VISIBILITY
1656 bool compare_exchange_weak(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001657 memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001658 {return __cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001659 _LIBCPP_INLINE_VISIBILITY
1660 bool compare_exchange_weak(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001661 memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001662 {return __cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001663 _LIBCPP_INLINE_VISIBILITY
1664 bool compare_exchange_strong(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001665 memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001666 {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001667 _LIBCPP_INLINE_VISIBILITY
1668 bool compare_exchange_strong(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001669 memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001670 {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001671
Louis Dionne3dde4ab2020-02-24 10:09:29 -05001672 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void wait(_Tp __v, memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
Olivier Giroux161e6e82020-02-18 09:58:34 -05001673 {__cxx_atomic_wait(&__a_, __v, __m);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05001674 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void wait(_Tp __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT
Olivier Giroux161e6e82020-02-18 09:58:34 -05001675 {__cxx_atomic_wait(&__a_, __v, __m);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05001676 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_one() volatile _NOEXCEPT
Olivier Giroux161e6e82020-02-18 09:58:34 -05001677 {__cxx_atomic_notify_one(&__a_);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05001678 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_one() _NOEXCEPT
Olivier Giroux161e6e82020-02-18 09:58:34 -05001679 {__cxx_atomic_notify_one(&__a_);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05001680 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_all() volatile _NOEXCEPT
Olivier Giroux161e6e82020-02-18 09:58:34 -05001681 {__cxx_atomic_notify_all(&__a_);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05001682 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_all() _NOEXCEPT
Olivier Giroux161e6e82020-02-18 09:58:34 -05001683 {__cxx_atomic_notify_all(&__a_);}
1684
Raul Tambre4e0e88f2021-06-06 19:02:20 +03001685#if _LIBCPP_STD_VER > 17
1686 _LIBCPP_INLINE_VISIBILITY constexpr
1687 __atomic_base() noexcept(is_nothrow_default_constructible_v<_Tp>) : __a_(_Tp()) {}
1688#else
Howard Hinnant138f5922010-12-07 20:46:14 +00001689 _LIBCPP_INLINE_VISIBILITY
Davide Italiano011f80a2019-03-05 18:40:49 +00001690 __atomic_base() _NOEXCEPT _LIBCPP_DEFAULT
Raul Tambre4e0e88f2021-06-06 19:02:20 +03001691#endif
Howard Hinnant3d284222013-05-02 20:18:43 +00001692
Davide Italiano011f80a2019-03-05 18:40:49 +00001693 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
1694 __atomic_base(_Tp __d) _NOEXCEPT : __a_(__d) {}
1695
Eric Fiselier2d8515f2017-01-06 20:58:25 +00001696#ifndef _LIBCPP_CXX03_LANG
Howard Hinnant138f5922010-12-07 20:46:14 +00001697 __atomic_base(const __atomic_base&) = delete;
Eric Fiselier2d8515f2017-01-06 20:58:25 +00001698#else
Howard Hinnant6ac60f82010-12-08 17:20:28 +00001699private:
Olivier Giroux161e6e82020-02-18 09:58:34 -05001700 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant6ac60f82010-12-08 17:20:28 +00001701 __atomic_base(const __atomic_base&);
Eric Fiselier2d8515f2017-01-06 20:58:25 +00001702#endif
Howard Hinnant138f5922010-12-07 20:46:14 +00001703};
1704
JF Bastienfdb42c22016-03-25 15:48:21 +00001705#if defined(__cpp_lib_atomic_is_always_lock_free)
1706template <class _Tp, bool __b>
1707_LIBCPP_CONSTEXPR bool __atomic_base<_Tp, __b>::is_always_lock_free;
1708#endif
1709
Howard Hinnant138f5922010-12-07 20:46:14 +00001710// atomic<Integral>
1711
1712template <class _Tp>
1713struct __atomic_base<_Tp, true>
1714 : public __atomic_base<_Tp, false>
1715{
1716 typedef __atomic_base<_Tp, false> __base;
Raul Tambre4e0e88f2021-06-06 19:02:20 +03001717
1718 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
Howard Hinnant3d284222013-05-02 20:18:43 +00001719 __atomic_base() _NOEXCEPT _LIBCPP_DEFAULT
Raul Tambre4e0e88f2021-06-06 19:02:20 +03001720
Howard Hinnant138f5922010-12-07 20:46:14 +00001721 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001722 _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __base(__d) {}
Howard Hinnant138f5922010-12-07 20:46:14 +00001723
1724 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001725 _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001726 {return __cxx_atomic_fetch_add(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001727 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001728 _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001729 {return __cxx_atomic_fetch_add(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001730 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001731 _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001732 {return __cxx_atomic_fetch_sub(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001733 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001734 _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001735 {return __cxx_atomic_fetch_sub(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001736 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001737 _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001738 {return __cxx_atomic_fetch_and(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001739 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001740 _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001741 {return __cxx_atomic_fetch_and(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001742 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001743 _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001744 {return __cxx_atomic_fetch_or(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001745 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001746 _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001747 {return __cxx_atomic_fetch_or(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001748 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001749 _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001750 {return __cxx_atomic_fetch_xor(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001751 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001752 _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001753 {return __cxx_atomic_fetch_xor(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001754
1755 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001756 _Tp operator++(int) volatile _NOEXCEPT {return fetch_add(_Tp(1));}
Howard Hinnant138f5922010-12-07 20:46:14 +00001757 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001758 _Tp operator++(int) _NOEXCEPT {return fetch_add(_Tp(1));}
Howard Hinnant138f5922010-12-07 20:46:14 +00001759 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001760 _Tp operator--(int) volatile _NOEXCEPT {return fetch_sub(_Tp(1));}
Howard Hinnant138f5922010-12-07 20:46:14 +00001761 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001762 _Tp operator--(int) _NOEXCEPT {return fetch_sub(_Tp(1));}
Howard Hinnant138f5922010-12-07 20:46:14 +00001763 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001764 _Tp operator++() volatile _NOEXCEPT {return fetch_add(_Tp(1)) + _Tp(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001765 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001766 _Tp operator++() _NOEXCEPT {return fetch_add(_Tp(1)) + _Tp(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001767 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001768 _Tp operator--() volatile _NOEXCEPT {return fetch_sub(_Tp(1)) - _Tp(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001769 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001770 _Tp operator--() _NOEXCEPT {return fetch_sub(_Tp(1)) - _Tp(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001771 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001772 _Tp operator+=(_Tp __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001773 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001774 _Tp operator+=(_Tp __op) _NOEXCEPT {return fetch_add(__op) + __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001775 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001776 _Tp operator-=(_Tp __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001777 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001778 _Tp operator-=(_Tp __op) _NOEXCEPT {return fetch_sub(__op) - __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001779 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001780 _Tp operator&=(_Tp __op) volatile _NOEXCEPT {return fetch_and(__op) & __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001781 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001782 _Tp operator&=(_Tp __op) _NOEXCEPT {return fetch_and(__op) & __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001783 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001784 _Tp operator|=(_Tp __op) volatile _NOEXCEPT {return fetch_or(__op) | __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001785 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001786 _Tp operator|=(_Tp __op) _NOEXCEPT {return fetch_or(__op) | __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001787 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001788 _Tp operator^=(_Tp __op) volatile _NOEXCEPT {return fetch_xor(__op) ^ __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001789 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001790 _Tp operator^=(_Tp __op) _NOEXCEPT {return fetch_xor(__op) ^ __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001791};
1792
1793// atomic<T>
1794
1795template <class _Tp>
1796struct atomic
1797 : public __atomic_base<_Tp>
1798{
1799 typedef __atomic_base<_Tp> __base;
Olivier Giroux161e6e82020-02-18 09:58:34 -05001800 typedef _Tp value_type;
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07001801 typedef value_type difference_type;
Raul Tambre4e0e88f2021-06-06 19:02:20 +03001802
1803#if _LIBCPP_STD_VER > 17
1804 _LIBCPP_INLINE_VISIBILITY
1805 atomic() = default;
1806#else
Howard Hinnant138f5922010-12-07 20:46:14 +00001807 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3d284222013-05-02 20:18:43 +00001808 atomic() _NOEXCEPT _LIBCPP_DEFAULT
Raul Tambre4e0e88f2021-06-06 19:02:20 +03001809#endif
1810
Howard Hinnant138f5922010-12-07 20:46:14 +00001811 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001812 _LIBCPP_CONSTEXPR atomic(_Tp __d) _NOEXCEPT : __base(__d) {}
Howard Hinnant96e4cd62010-12-07 23:24:41 +00001813
1814 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001815 _Tp operator=(_Tp __d) volatile _NOEXCEPT
Howard Hinnant96e4cd62010-12-07 23:24:41 +00001816 {__base::store(__d); return __d;}
1817 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001818 _Tp operator=(_Tp __d) _NOEXCEPT
Howard Hinnant96e4cd62010-12-07 23:24:41 +00001819 {__base::store(__d); return __d;}
Ruslan Arutyunyan033093f2021-02-01 10:12:09 -05001820
1821 atomic& operator=(const atomic&) = delete;
1822 atomic& operator=(const atomic&) volatile = delete;
Howard Hinnant138f5922010-12-07 20:46:14 +00001823};
1824
1825// atomic<T*>
1826
1827template <class _Tp>
1828struct atomic<_Tp*>
1829 : public __atomic_base<_Tp*>
1830{
Howard Hinnant96e4cd62010-12-07 23:24:41 +00001831 typedef __atomic_base<_Tp*> __base;
Olivier Giroux161e6e82020-02-18 09:58:34 -05001832 typedef _Tp* value_type;
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07001833 typedef ptrdiff_t difference_type;
Raul Tambre4e0e88f2021-06-06 19:02:20 +03001834
Howard Hinnant138f5922010-12-07 20:46:14 +00001835 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3d284222013-05-02 20:18:43 +00001836 atomic() _NOEXCEPT _LIBCPP_DEFAULT
Raul Tambre4e0e88f2021-06-06 19:02:20 +03001837
Howard Hinnant138f5922010-12-07 20:46:14 +00001838 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001839 _LIBCPP_CONSTEXPR atomic(_Tp* __d) _NOEXCEPT : __base(__d) {}
Howard Hinnant138f5922010-12-07 20:46:14 +00001840
1841 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001842 _Tp* operator=(_Tp* __d) volatile _NOEXCEPT
Howard Hinnant96e4cd62010-12-07 23:24:41 +00001843 {__base::store(__d); return __d;}
1844 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001845 _Tp* operator=(_Tp* __d) _NOEXCEPT
Howard Hinnant96e4cd62010-12-07 23:24:41 +00001846 {__base::store(__d); return __d;}
1847
1848 _LIBCPP_INLINE_VISIBILITY
Mark de Wever494905b2021-06-09 20:26:34 +02001849 _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
1850 // __atomic_fetch_add accepts function pointers, guard against them.
1851 static_assert(!is_function<typename remove_pointer<_Tp>::type>::value, "Pointer to function isn't allowed");
1852 return __cxx_atomic_fetch_add(&this->__a_, __op, __m);
1853 }
1854
Howard Hinnant138f5922010-12-07 20:46:14 +00001855 _LIBCPP_INLINE_VISIBILITY
Mark de Wever494905b2021-06-09 20:26:34 +02001856 _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
1857 // __atomic_fetch_add accepts function pointers, guard against them.
1858 static_assert(!is_function<typename remove_pointer<_Tp>::type>::value, "Pointer to function isn't allowed");
1859 return __cxx_atomic_fetch_add(&this->__a_, __op, __m);
1860 }
1861
Howard Hinnant138f5922010-12-07 20:46:14 +00001862 _LIBCPP_INLINE_VISIBILITY
Mark de Wever494905b2021-06-09 20:26:34 +02001863 _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
1864 // __atomic_fetch_add accepts function pointers, guard against them.
1865 static_assert(!is_function<typename remove_pointer<_Tp>::type>::value, "Pointer to function isn't allowed");
1866 return __cxx_atomic_fetch_sub(&this->__a_, __op, __m);
1867 }
1868
Howard Hinnant138f5922010-12-07 20:46:14 +00001869 _LIBCPP_INLINE_VISIBILITY
Mark de Wever494905b2021-06-09 20:26:34 +02001870 _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
1871 // __atomic_fetch_add accepts function pointers, guard against them.
1872 static_assert(!is_function<typename remove_pointer<_Tp>::type>::value, "Pointer to function isn't allowed");
1873 return __cxx_atomic_fetch_sub(&this->__a_, __op, __m);
1874 }
Howard Hinnant138f5922010-12-07 20:46:14 +00001875
1876 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001877 _Tp* operator++(int) volatile _NOEXCEPT {return fetch_add(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001878 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001879 _Tp* operator++(int) _NOEXCEPT {return fetch_add(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001880 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001881 _Tp* operator--(int) volatile _NOEXCEPT {return fetch_sub(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001882 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001883 _Tp* operator--(int) _NOEXCEPT {return fetch_sub(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001884 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001885 _Tp* operator++() volatile _NOEXCEPT {return fetch_add(1) + 1;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001886 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001887 _Tp* operator++() _NOEXCEPT {return fetch_add(1) + 1;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001888 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001889 _Tp* operator--() volatile _NOEXCEPT {return fetch_sub(1) - 1;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001890 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001891 _Tp* operator--() _NOEXCEPT {return fetch_sub(1) - 1;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001892 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001893 _Tp* operator+=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001894 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001895 _Tp* operator+=(ptrdiff_t __op) _NOEXCEPT {return fetch_add(__op) + __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001896 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001897 _Tp* operator-=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001898 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001899 _Tp* operator-=(ptrdiff_t __op) _NOEXCEPT {return fetch_sub(__op) - __op;}
Ruslan Arutyunyan033093f2021-02-01 10:12:09 -05001900
1901 atomic& operator=(const atomic&) = delete;
1902 atomic& operator=(const atomic&) volatile = delete;
Howard Hinnant138f5922010-12-07 20:46:14 +00001903};
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001904
1905// atomic_is_lock_free
1906
1907template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001908_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001909bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00001910atomic_is_lock_free(const volatile atomic<_Tp>* __o) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001911{
Howard Hinnant138f5922010-12-07 20:46:14 +00001912 return __o->is_lock_free();
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001913}
1914
1915template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001916_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001917bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00001918atomic_is_lock_free(const atomic<_Tp>* __o) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001919{
Howard Hinnant138f5922010-12-07 20:46:14 +00001920 return __o->is_lock_free();
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001921}
1922
1923// atomic_init
1924
1925template <class _Tp>
Raul Tambre4e0e88f2021-06-06 19:02:20 +03001926_LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001927void
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07001928atomic_init(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001929{
Davide Italiano011f80a2019-03-05 18:40:49 +00001930 __cxx_atomic_init(&__o->__a_, __d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001931}
1932
1933template <class _Tp>
Raul Tambre4e0e88f2021-06-06 19:02:20 +03001934_LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001935void
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07001936atomic_init(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001937{
Davide Italiano011f80a2019-03-05 18:40:49 +00001938 __cxx_atomic_init(&__o->__a_, __d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001939}
1940
1941// atomic_store
1942
1943template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001944_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001945void
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07001946atomic_store(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001947{
Howard Hinnant138f5922010-12-07 20:46:14 +00001948 __o->store(__d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001949}
1950
1951template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001952_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001953void
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07001954atomic_store(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001955{
Howard Hinnant138f5922010-12-07 20:46:14 +00001956 __o->store(__d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001957}
1958
1959// atomic_store_explicit
1960
1961template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001962_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001963void
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07001964atomic_store_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001965 _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001966{
Howard Hinnant138f5922010-12-07 20:46:14 +00001967 __o->store(__d, __m);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001968}
1969
1970template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001971_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001972void
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07001973atomic_store_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001974 _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001975{
Howard Hinnant138f5922010-12-07 20:46:14 +00001976 __o->store(__d, __m);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001977}
1978
1979// atomic_load
1980
1981template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001982_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001983_Tp
Howard Hinnanteee2c142012-04-11 20:14:21 +00001984atomic_load(const volatile atomic<_Tp>* __o) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001985{
Howard Hinnant138f5922010-12-07 20:46:14 +00001986 return __o->load();
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001987}
1988
1989template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001990_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001991_Tp
Howard Hinnanteee2c142012-04-11 20:14:21 +00001992atomic_load(const atomic<_Tp>* __o) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001993{
Howard Hinnant138f5922010-12-07 20:46:14 +00001994 return __o->load();
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001995}
1996
1997// atomic_load_explicit
1998
1999template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002000_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002001_Tp
Howard Hinnanteee2c142012-04-11 20:14:21 +00002002atomic_load_explicit(const volatile atomic<_Tp>* __o, memory_order __m) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00002003 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002004{
Howard Hinnant138f5922010-12-07 20:46:14 +00002005 return __o->load(__m);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002006}
2007
2008template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002009_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002010_Tp
Howard Hinnanteee2c142012-04-11 20:14:21 +00002011atomic_load_explicit(const atomic<_Tp>* __o, memory_order __m) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00002012 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002013{
Howard Hinnant138f5922010-12-07 20:46:14 +00002014 return __o->load(__m);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002015}
2016
2017// atomic_exchange
2018
2019template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002020_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002021_Tp
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002022atomic_exchange(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002023{
Howard Hinnant138f5922010-12-07 20:46:14 +00002024 return __o->exchange(__d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002025}
2026
2027template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002028_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002029_Tp
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002030atomic_exchange(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002031{
Howard Hinnant138f5922010-12-07 20:46:14 +00002032 return __o->exchange(__d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002033}
2034
2035// atomic_exchange_explicit
2036
2037template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002038_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002039_Tp
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002040atomic_exchange_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002041{
Howard Hinnant138f5922010-12-07 20:46:14 +00002042 return __o->exchange(__d, __m);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002043}
2044
2045template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002046_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002047_Tp
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002048atomic_exchange_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002049{
Howard Hinnant138f5922010-12-07 20:46:14 +00002050 return __o->exchange(__d, __m);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002051}
2052
2053// atomic_compare_exchange_weak
2054
2055template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002056_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002057bool
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002058atomic_compare_exchange_weak(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002059{
Howard Hinnant138f5922010-12-07 20:46:14 +00002060 return __o->compare_exchange_weak(*__e, __d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002061}
2062
2063template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002064_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002065bool
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002066atomic_compare_exchange_weak(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002067{
Howard Hinnant138f5922010-12-07 20:46:14 +00002068 return __o->compare_exchange_weak(*__e, __d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002069}
2070
2071// atomic_compare_exchange_strong
2072
2073template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002074_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002075bool
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002076atomic_compare_exchange_strong(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002077{
Howard Hinnant138f5922010-12-07 20:46:14 +00002078 return __o->compare_exchange_strong(*__e, __d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002079}
2080
2081template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002082_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002083bool
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002084atomic_compare_exchange_strong(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002085{
Howard Hinnant138f5922010-12-07 20:46:14 +00002086 return __o->compare_exchange_strong(*__e, __d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002087}
2088
2089// atomic_compare_exchange_weak_explicit
2090
2091template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002092_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002093bool
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002094atomic_compare_exchange_weak_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e,
2095 typename atomic<_Tp>::value_type __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00002096 memory_order __s, memory_order __f) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00002097 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002098{
Howard Hinnant138f5922010-12-07 20:46:14 +00002099 return __o->compare_exchange_weak(*__e, __d, __s, __f);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002100}
2101
2102template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002103_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002104bool
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002105atomic_compare_exchange_weak_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00002106 memory_order __s, memory_order __f) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00002107 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002108{
Howard Hinnant138f5922010-12-07 20:46:14 +00002109 return __o->compare_exchange_weak(*__e, __d, __s, __f);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002110}
2111
2112// atomic_compare_exchange_strong_explicit
2113
2114template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002115_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002116bool
2117atomic_compare_exchange_strong_explicit(volatile atomic<_Tp>* __o,
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002118 typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00002119 memory_order __s, memory_order __f) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00002120 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002121{
Howard Hinnant138f5922010-12-07 20:46:14 +00002122 return __o->compare_exchange_strong(*__e, __d, __s, __f);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002123}
2124
2125template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002126_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002127bool
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002128atomic_compare_exchange_strong_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e,
2129 typename atomic<_Tp>::value_type __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00002130 memory_order __s, memory_order __f) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00002131 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002132{
Howard Hinnant138f5922010-12-07 20:46:14 +00002133 return __o->compare_exchange_strong(*__e, __d, __s, __f);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002134}
2135
Olivier Giroux161e6e82020-02-18 09:58:34 -05002136// atomic_wait
2137
2138template <class _Tp>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002139_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002140void atomic_wait(const volatile atomic<_Tp>* __o,
2141 typename atomic<_Tp>::value_type __v) _NOEXCEPT
2142{
2143 return __o->wait(__v);
2144}
2145
2146template <class _Tp>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002147_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002148void atomic_wait(const atomic<_Tp>* __o,
2149 typename atomic<_Tp>::value_type __v) _NOEXCEPT
2150{
2151 return __o->wait(__v);
2152}
2153
2154// atomic_wait_explicit
2155
2156template <class _Tp>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002157_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002158void atomic_wait_explicit(const volatile atomic<_Tp>* __o,
2159 typename atomic<_Tp>::value_type __v,
2160 memory_order __m) _NOEXCEPT
2161 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
2162{
2163 return __o->wait(__v, __m);
2164}
2165
2166template <class _Tp>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002167_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002168void atomic_wait_explicit(const atomic<_Tp>* __o,
2169 typename atomic<_Tp>::value_type __v,
2170 memory_order __m) _NOEXCEPT
2171 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
2172{
2173 return __o->wait(__v, __m);
2174}
2175
2176// atomic_notify_one
2177
2178template <class _Tp>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002179_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002180void atomic_notify_one(volatile atomic<_Tp>* __o) _NOEXCEPT
2181{
2182 __o->notify_one();
2183}
2184template <class _Tp>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002185_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002186void atomic_notify_one(atomic<_Tp>* __o) _NOEXCEPT
2187{
2188 __o->notify_one();
2189}
2190
2191// atomic_notify_one
2192
2193template <class _Tp>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002194_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002195void atomic_notify_all(volatile atomic<_Tp>* __o) _NOEXCEPT
2196{
2197 __o->notify_all();
2198}
2199template <class _Tp>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002200_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002201void atomic_notify_all(atomic<_Tp>* __o) _NOEXCEPT
2202{
2203 __o->notify_all();
2204}
2205
Howard Hinnant138f5922010-12-07 20:46:14 +00002206// atomic_fetch_add
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002207
2208template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002209_LIBCPP_INLINE_VISIBILITY
Mark de Wever494905b2021-06-09 20:26:34 +02002210_Tp
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002211atomic_fetch_add(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002212{
Howard Hinnant138f5922010-12-07 20:46:14 +00002213 return __o->fetch_add(__op);
2214}
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002215
Howard Hinnant138f5922010-12-07 20:46:14 +00002216template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002217_LIBCPP_INLINE_VISIBILITY
Mark de Wever494905b2021-06-09 20:26:34 +02002218_Tp
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002219atomic_fetch_add(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002220{
2221 return __o->fetch_add(__op);
2222}
2223
2224// atomic_fetch_add_explicit
2225
2226template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002227_LIBCPP_INLINE_VISIBILITY
Mark de Wever494905b2021-06-09 20:26:34 +02002228_Tp atomic_fetch_add_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002229{
2230 return __o->fetch_add(__op, __m);
2231}
2232
2233template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002234_LIBCPP_INLINE_VISIBILITY
Mark de Wever494905b2021-06-09 20:26:34 +02002235_Tp atomic_fetch_add_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT
Olivier Girouxdf485172020-09-11 12:13:35 -07002236{
2237 return __o->fetch_add(__op, __m);
2238}
2239
Howard Hinnant138f5922010-12-07 20:46:14 +00002240// atomic_fetch_sub
2241
2242template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002243_LIBCPP_INLINE_VISIBILITY
Mark de Wever494905b2021-06-09 20:26:34 +02002244_Tp atomic_fetch_sub(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002245{
2246 return __o->fetch_sub(__op);
2247}
2248
2249template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002250_LIBCPP_INLINE_VISIBILITY
Mark de Wever494905b2021-06-09 20:26:34 +02002251_Tp atomic_fetch_sub(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT
Olivier Girouxdf485172020-09-11 12:13:35 -07002252{
2253 return __o->fetch_sub(__op);
2254}
2255
Howard Hinnant138f5922010-12-07 20:46:14 +00002256// atomic_fetch_sub_explicit
2257
2258template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002259_LIBCPP_INLINE_VISIBILITY
Mark de Wever494905b2021-06-09 20:26:34 +02002260_Tp atomic_fetch_sub_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002261{
2262 return __o->fetch_sub(__op, __m);
2263}
2264
2265template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002266_LIBCPP_INLINE_VISIBILITY
Mark de Wever494905b2021-06-09 20:26:34 +02002267_Tp atomic_fetch_sub_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT
Olivier Girouxdf485172020-09-11 12:13:35 -07002268{
2269 return __o->fetch_sub(__op, __m);
2270}
2271
Howard Hinnant138f5922010-12-07 20:46:14 +00002272// atomic_fetch_and
2273
2274template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002275_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002276typename enable_if
2277<
2278 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2279 _Tp
2280>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002281atomic_fetch_and(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002282{
2283 return __o->fetch_and(__op);
2284}
2285
2286template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002287_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002288typename enable_if
2289<
2290 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2291 _Tp
2292>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002293atomic_fetch_and(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002294{
2295 return __o->fetch_and(__op);
2296}
2297
2298// atomic_fetch_and_explicit
2299
2300template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002301_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002302typename enable_if
2303<
2304 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2305 _Tp
2306>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002307atomic_fetch_and_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002308{
2309 return __o->fetch_and(__op, __m);
2310}
2311
2312template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002313_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002314typename enable_if
2315<
2316 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2317 _Tp
2318>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002319atomic_fetch_and_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002320{
2321 return __o->fetch_and(__op, __m);
2322}
2323
2324// atomic_fetch_or
2325
2326template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002327_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002328typename enable_if
2329<
2330 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2331 _Tp
2332>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002333atomic_fetch_or(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002334{
2335 return __o->fetch_or(__op);
2336}
2337
2338template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002339_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002340typename enable_if
2341<
2342 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2343 _Tp
2344>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002345atomic_fetch_or(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002346{
2347 return __o->fetch_or(__op);
2348}
2349
2350// atomic_fetch_or_explicit
2351
2352template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002353_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002354typename enable_if
2355<
2356 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2357 _Tp
2358>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002359atomic_fetch_or_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002360{
2361 return __o->fetch_or(__op, __m);
2362}
2363
2364template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002365_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002366typename enable_if
2367<
2368 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2369 _Tp
2370>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002371atomic_fetch_or_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002372{
2373 return __o->fetch_or(__op, __m);
2374}
2375
2376// atomic_fetch_xor
2377
2378template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002379_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002380typename enable_if
2381<
2382 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2383 _Tp
2384>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002385atomic_fetch_xor(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002386{
2387 return __o->fetch_xor(__op);
2388}
2389
2390template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002391_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002392typename enable_if
2393<
2394 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2395 _Tp
2396>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002397atomic_fetch_xor(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002398{
2399 return __o->fetch_xor(__op);
2400}
2401
2402// atomic_fetch_xor_explicit
2403
2404template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002405_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002406typename enable_if
2407<
2408 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2409 _Tp
2410>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002411atomic_fetch_xor_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002412{
2413 return __o->fetch_xor(__op, __m);
2414}
2415
2416template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002417_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002418typename enable_if
2419<
2420 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2421 _Tp
2422>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002423atomic_fetch_xor_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002424{
2425 return __o->fetch_xor(__op, __m);
2426}
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002427
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002428// flag type and operations
2429
2430typedef struct atomic_flag
2431{
Davide Italiano011f80a2019-03-05 18:40:49 +00002432 __cxx_atomic_impl<_LIBCPP_ATOMIC_FLAG_TYPE> __a_;
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002433
2434 _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002435 bool test(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
2436 {return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m);}
2437 _LIBCPP_INLINE_VISIBILITY
2438 bool test(memory_order __m = memory_order_seq_cst) const _NOEXCEPT
2439 {return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m);}
2440
2441 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00002442 bool test_and_set(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00002443 {return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);}
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002444 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00002445 bool test_and_set(memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00002446 {return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);}
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002447 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00002448 void clear(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00002449 {__cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);}
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002450 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00002451 void clear(memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00002452 {__cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);}
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002453
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002454 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002455 void wait(bool __v, memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
2456 {__cxx_atomic_wait(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002457 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002458 void wait(bool __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT
2459 {__cxx_atomic_wait(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002460 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002461 void notify_one() volatile _NOEXCEPT
2462 {__cxx_atomic_notify_one(&__a_);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002463 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002464 void notify_one() _NOEXCEPT
2465 {__cxx_atomic_notify_one(&__a_);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002466 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002467 void notify_all() volatile _NOEXCEPT
2468 {__cxx_atomic_notify_all(&__a_);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002469 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002470 void notify_all() _NOEXCEPT
2471 {__cxx_atomic_notify_all(&__a_);}
2472
Raul Tambre4e0e88f2021-06-06 19:02:20 +03002473#if _LIBCPP_STD_VER > 17
2474 _LIBCPP_INLINE_VISIBILITY constexpr
2475 atomic_flag() _NOEXCEPT : __a_(false) {}
2476#else
Olivier Giroux161e6e82020-02-18 09:58:34 -05002477 _LIBCPP_INLINE_VISIBILITY
Davide Italiano011f80a2019-03-05 18:40:49 +00002478 atomic_flag() _NOEXCEPT _LIBCPP_DEFAULT
Raul Tambre4e0e88f2021-06-06 19:02:20 +03002479#endif
Howard Hinnant3d284222013-05-02 20:18:43 +00002480
Marshall Clowcf990752018-04-25 14:27:29 +00002481 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
Eric Fiselierfec26a92016-05-03 02:12:26 +00002482 atomic_flag(bool __b) _NOEXCEPT : __a_(__b) {} // EXTENSION
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002483
Eric Fiselier2d8515f2017-01-06 20:58:25 +00002484#ifndef _LIBCPP_CXX03_LANG
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002485 atomic_flag(const atomic_flag&) = delete;
2486 atomic_flag& operator=(const atomic_flag&) = delete;
2487 atomic_flag& operator=(const atomic_flag&) volatile = delete;
Eric Fiselier2d8515f2017-01-06 20:58:25 +00002488#else
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002489private:
Olivier Giroux161e6e82020-02-18 09:58:34 -05002490 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002491 atomic_flag(const atomic_flag&);
Olivier Giroux161e6e82020-02-18 09:58:34 -05002492 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002493 atomic_flag& operator=(const atomic_flag&);
Olivier Giroux161e6e82020-02-18 09:58:34 -05002494 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002495 atomic_flag& operator=(const atomic_flag&) volatile;
Eric Fiselier2d8515f2017-01-06 20:58:25 +00002496#endif
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002497} atomic_flag;
2498
Olivier Giroux161e6e82020-02-18 09:58:34 -05002499
2500inline _LIBCPP_INLINE_VISIBILITY
2501bool
2502atomic_flag_test(const volatile atomic_flag* __o) _NOEXCEPT
2503{
2504 return __o->test();
2505}
2506
2507inline _LIBCPP_INLINE_VISIBILITY
2508bool
2509atomic_flag_test(const atomic_flag* __o) _NOEXCEPT
2510{
2511 return __o->test();
2512}
2513
2514inline _LIBCPP_INLINE_VISIBILITY
2515bool
2516atomic_flag_test_explicit(const volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
2517{
2518 return __o->test(__m);
2519}
2520
2521inline _LIBCPP_INLINE_VISIBILITY
2522bool
2523atomic_flag_test_explicit(const atomic_flag* __o, memory_order __m) _NOEXCEPT
2524{
2525 return __o->test(__m);
2526}
2527
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002528inline _LIBCPP_INLINE_VISIBILITY
2529bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00002530atomic_flag_test_and_set(volatile atomic_flag* __o) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002531{
2532 return __o->test_and_set();
2533}
2534
2535inline _LIBCPP_INLINE_VISIBILITY
2536bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00002537atomic_flag_test_and_set(atomic_flag* __o) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002538{
2539 return __o->test_and_set();
2540}
2541
2542inline _LIBCPP_INLINE_VISIBILITY
2543bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00002544atomic_flag_test_and_set_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002545{
2546 return __o->test_and_set(__m);
2547}
2548
2549inline _LIBCPP_INLINE_VISIBILITY
2550bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00002551atomic_flag_test_and_set_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002552{
2553 return __o->test_and_set(__m);
2554}
2555
2556inline _LIBCPP_INLINE_VISIBILITY
2557void
Howard Hinnanteee2c142012-04-11 20:14:21 +00002558atomic_flag_clear(volatile atomic_flag* __o) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002559{
2560 __o->clear();
2561}
2562
2563inline _LIBCPP_INLINE_VISIBILITY
2564void
Howard Hinnanteee2c142012-04-11 20:14:21 +00002565atomic_flag_clear(atomic_flag* __o) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002566{
2567 __o->clear();
2568}
2569
2570inline _LIBCPP_INLINE_VISIBILITY
2571void
Howard Hinnanteee2c142012-04-11 20:14:21 +00002572atomic_flag_clear_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002573{
2574 __o->clear(__m);
2575}
2576
2577inline _LIBCPP_INLINE_VISIBILITY
2578void
Howard Hinnanteee2c142012-04-11 20:14:21 +00002579atomic_flag_clear_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002580{
2581 __o->clear(__m);
2582}
2583
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002584inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
Olivier Giroux161e6e82020-02-18 09:58:34 -05002585void
2586atomic_flag_wait(const volatile atomic_flag* __o, bool __v) _NOEXCEPT
2587{
2588 __o->wait(__v);
2589}
2590
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002591inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
Olivier Giroux161e6e82020-02-18 09:58:34 -05002592void
2593atomic_flag_wait(const atomic_flag* __o, bool __v) _NOEXCEPT
2594{
2595 __o->wait(__v);
2596}
2597
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002598inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
Olivier Giroux161e6e82020-02-18 09:58:34 -05002599void
2600atomic_flag_wait_explicit(const volatile atomic_flag* __o,
2601 bool __v, memory_order __m) _NOEXCEPT
2602{
2603 __o->wait(__v, __m);
2604}
2605
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002606inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
Olivier Giroux161e6e82020-02-18 09:58:34 -05002607void
2608atomic_flag_wait_explicit(const atomic_flag* __o,
2609 bool __v, memory_order __m) _NOEXCEPT
2610{
2611 __o->wait(__v, __m);
2612}
2613
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002614inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
Olivier Giroux161e6e82020-02-18 09:58:34 -05002615void
2616atomic_flag_notify_one(volatile atomic_flag* __o) _NOEXCEPT
2617{
2618 __o->notify_one();
2619}
2620
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002621inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
Olivier Giroux161e6e82020-02-18 09:58:34 -05002622void
2623atomic_flag_notify_one(atomic_flag* __o) _NOEXCEPT
2624{
2625 __o->notify_one();
2626}
2627
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002628inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
Olivier Giroux161e6e82020-02-18 09:58:34 -05002629void
2630atomic_flag_notify_all(volatile atomic_flag* __o) _NOEXCEPT
2631{
2632 __o->notify_all();
2633}
2634
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002635inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
Olivier Giroux161e6e82020-02-18 09:58:34 -05002636void
2637atomic_flag_notify_all(atomic_flag* __o) _NOEXCEPT
2638{
2639 __o->notify_all();
2640}
2641
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002642// fences
2643
2644inline _LIBCPP_INLINE_VISIBILITY
2645void
Howard Hinnanteee2c142012-04-11 20:14:21 +00002646atomic_thread_fence(memory_order __m) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002647{
Davide Italiano011f80a2019-03-05 18:40:49 +00002648 __cxx_atomic_thread_fence(__m);
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002649}
2650
2651inline _LIBCPP_INLINE_VISIBILITY
2652void
Howard Hinnanteee2c142012-04-11 20:14:21 +00002653atomic_signal_fence(memory_order __m) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002654{
Davide Italiano011f80a2019-03-05 18:40:49 +00002655 __cxx_atomic_signal_fence(__m);
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002656}
2657
Howard Hinnant96e4cd62010-12-07 23:24:41 +00002658// Atomics for standard typedef types
2659
Howard Hinnantf0af8d92013-01-04 18:58:50 +00002660typedef atomic<bool> atomic_bool;
Howard Hinnant96e4cd62010-12-07 23:24:41 +00002661typedef atomic<char> atomic_char;
2662typedef atomic<signed char> atomic_schar;
2663typedef atomic<unsigned char> atomic_uchar;
2664typedef atomic<short> atomic_short;
2665typedef atomic<unsigned short> atomic_ushort;
2666typedef atomic<int> atomic_int;
2667typedef atomic<unsigned int> atomic_uint;
2668typedef atomic<long> atomic_long;
2669typedef atomic<unsigned long> atomic_ulong;
2670typedef atomic<long long> atomic_llong;
2671typedef atomic<unsigned long long> atomic_ullong;
Arthur O'Dwyerafa5d5f2021-04-18 21:47:08 -04002672#ifndef _LIBCPP_HAS_NO_CHAR8_T
Marek Kurdej91bebaa2020-11-24 21:07:06 +01002673typedef atomic<char8_t> atomic_char8_t;
2674#endif
Howard Hinnant96e4cd62010-12-07 23:24:41 +00002675typedef atomic<char16_t> atomic_char16_t;
2676typedef atomic<char32_t> atomic_char32_t;
Louis Dionne89258142021-08-23 15:32:36 -04002677#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
Howard Hinnant96e4cd62010-12-07 23:24:41 +00002678typedef atomic<wchar_t> atomic_wchar_t;
Louis Dionne89258142021-08-23 15:32:36 -04002679#endif
Howard Hinnant96e4cd62010-12-07 23:24:41 +00002680
2681typedef atomic<int_least8_t> atomic_int_least8_t;
2682typedef atomic<uint_least8_t> atomic_uint_least8_t;
2683typedef atomic<int_least16_t> atomic_int_least16_t;
2684typedef atomic<uint_least16_t> atomic_uint_least16_t;
2685typedef atomic<int_least32_t> atomic_int_least32_t;
2686typedef atomic<uint_least32_t> atomic_uint_least32_t;
2687typedef atomic<int_least64_t> atomic_int_least64_t;
2688typedef atomic<uint_least64_t> atomic_uint_least64_t;
2689
2690typedef atomic<int_fast8_t> atomic_int_fast8_t;
2691typedef atomic<uint_fast8_t> atomic_uint_fast8_t;
2692typedef atomic<int_fast16_t> atomic_int_fast16_t;
2693typedef atomic<uint_fast16_t> atomic_uint_fast16_t;
2694typedef atomic<int_fast32_t> atomic_int_fast32_t;
2695typedef atomic<uint_fast32_t> atomic_uint_fast32_t;
2696typedef atomic<int_fast64_t> atomic_int_fast64_t;
2697typedef atomic<uint_fast64_t> atomic_uint_fast64_t;
2698
Marshall Clowf710afc2016-06-30 15:28:38 +00002699typedef atomic< int8_t> atomic_int8_t;
2700typedef atomic<uint8_t> atomic_uint8_t;
2701typedef atomic< int16_t> atomic_int16_t;
2702typedef atomic<uint16_t> atomic_uint16_t;
2703typedef atomic< int32_t> atomic_int32_t;
2704typedef atomic<uint32_t> atomic_uint32_t;
2705typedef atomic< int64_t> atomic_int64_t;
2706typedef atomic<uint64_t> atomic_uint64_t;
2707
Howard Hinnant96e4cd62010-12-07 23:24:41 +00002708typedef atomic<intptr_t> atomic_intptr_t;
2709typedef atomic<uintptr_t> atomic_uintptr_t;
2710typedef atomic<size_t> atomic_size_t;
2711typedef atomic<ptrdiff_t> atomic_ptrdiff_t;
2712typedef atomic<intmax_t> atomic_intmax_t;
2713typedef atomic<uintmax_t> atomic_uintmax_t;
2714
Olivier Giroux161e6e82020-02-18 09:58:34 -05002715// atomic_*_lock_free : prefer the contention type most highly, then the largest lock-free type
2716
2717#ifdef __cpp_lib_atomic_is_always_lock_free
2718# define _LIBCPP_CONTENTION_LOCK_FREE __atomic_always_lock_free(sizeof(__cxx_contention_t), 0)
2719#else
2720# define _LIBCPP_CONTENTION_LOCK_FREE false
2721#endif
2722
2723#if ATOMIC_LLONG_LOCK_FREE == 2
2724typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, long long>::type __libcpp_signed_lock_free;
2725typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned long long>::type __libcpp_unsigned_lock_free;
2726#elif ATOMIC_INT_LOCK_FREE == 2
2727typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, int>::type __libcpp_signed_lock_free;
2728typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned int>::type __libcpp_unsigned_lock_free;
2729#elif ATOMIC_SHORT_LOCK_FREE == 2
2730typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, short>::type __libcpp_signed_lock_free;
2731typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned short>::type __libcpp_unsigned_lock_free;
2732#elif ATOMIC_CHAR_LOCK_FREE == 2
2733typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, char>::type __libcpp_signed_lock_free;
2734typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned char>::type __libcpp_unsigned_lock_free;
2735#else
2736 // No signed/unsigned lock-free types
2737#endif
2738
2739typedef atomic<__libcpp_signed_lock_free> atomic_signed_lock_free;
2740typedef atomic<__libcpp_unsigned_lock_free> atomic_unsigned_lock_free;
2741
Howard Hinnantf1f066a2010-09-29 21:20:03 +00002742#define ATOMIC_FLAG_INIT {false}
Howard Hinnant953c31d2010-10-04 18:52:54 +00002743#define ATOMIC_VAR_INIT(__v) {__v}
2744
Howard Hinnant71be7292010-09-27 21:17:38 +00002745_LIBCPP_END_NAMESPACE_STD
2746
Louis Dionne2b1ceaa2021-04-20 12:03:32 -04002747#endif // _LIBCPP_ATOMIC