blob: 0f6aee83ce824df5aa26c0f2ad145c1863014a98 [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 }; };
1476template<> struct __cxx_is_always_lock_free<wchar_t> { enum { __value = 2 == ATOMIC_WCHAR_T_LOCK_FREE }; };
1477template<> struct __cxx_is_always_lock_free<short> { enum { __value = 2 == ATOMIC_SHORT_LOCK_FREE }; };
1478template<> struct __cxx_is_always_lock_free<unsigned short> { enum { __value = 2 == ATOMIC_SHORT_LOCK_FREE }; };
1479template<> struct __cxx_is_always_lock_free<int> { enum { __value = 2 == ATOMIC_INT_LOCK_FREE }; };
1480template<> struct __cxx_is_always_lock_free<unsigned int> { enum { __value = 2 == ATOMIC_INT_LOCK_FREE }; };
1481template<> struct __cxx_is_always_lock_free<long> { enum { __value = 2 == ATOMIC_LONG_LOCK_FREE }; };
1482template<> struct __cxx_is_always_lock_free<unsigned long> { enum { __value = 2 == ATOMIC_LONG_LOCK_FREE }; };
1483template<> struct __cxx_is_always_lock_free<long long> { enum { __value = 2 == ATOMIC_LLONG_LOCK_FREE }; };
1484template<> struct __cxx_is_always_lock_free<unsigned long long> { enum { __value = 2 == ATOMIC_LLONG_LOCK_FREE }; };
1485template<typename _Tp> struct __cxx_is_always_lock_free<_Tp*> { enum { __value = 2 == ATOMIC_POINTER_LOCK_FREE }; };
1486template<> struct __cxx_is_always_lock_free<std::nullptr_t> { enum { __value = 2 == ATOMIC_POINTER_LOCK_FREE }; };
1487
1488#endif //__cpp_lib_atomic_is_always_lock_free
1489
1490template <typename _Tp,
1491 typename _Base = typename conditional<__cxx_is_always_lock_free<_Tp>::__value,
1492 __cxx_atomic_base_impl<_Tp>,
1493 __cxx_atomic_lock_impl<_Tp> >::type>
1494#else
1495template <typename _Tp,
1496 typename _Base = __cxx_atomic_base_impl<_Tp> >
1497#endif //_LIBCPP_ATOMIC_ONLY_USE_BUILTINS
1498struct __cxx_atomic_impl : public _Base {
1499
1500#if _GNUC_VER >= 501
1501 static_assert(is_trivially_copyable<_Tp>::value,
1502 "std::atomic<Tp> requires that 'Tp' be a trivially copyable type");
1503#endif
1504
1505 _LIBCPP_INLINE_VISIBILITY __cxx_atomic_impl() _NOEXCEPT _LIBCPP_DEFAULT
1506 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR explicit __cxx_atomic_impl(_Tp value) _NOEXCEPT
1507 : _Base(value) {}
1508};
1509
Olivier Giroux161e6e82020-02-18 09:58:34 -05001510#ifdef __linux__
1511 using __cxx_contention_t = int32_t;
1512#else
1513 using __cxx_contention_t = int64_t;
1514#endif //__linux__
1515
Olivier Giroux161e6e82020-02-18 09:58:34 -05001516using __cxx_atomic_contention_t = __cxx_atomic_impl<__cxx_contention_t>;
1517
1518#ifndef _LIBCPP_HAS_NO_PLATFORM_WAIT
1519
Louis Dionne48a828b2020-02-24 10:08:41 -05001520_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_one(void const volatile*);
1521_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_all(void const volatile*);
1522_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t __libcpp_atomic_monitor(void const volatile*);
1523_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __libcpp_atomic_wait(void const volatile*, __cxx_contention_t);
Olivier Giroux161e6e82020-02-18 09:58:34 -05001524
Louis Dionne48a828b2020-02-24 10:08:41 -05001525_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_one(__cxx_atomic_contention_t const volatile*);
1526_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_all(__cxx_atomic_contention_t const volatile*);
1527_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t __libcpp_atomic_monitor(__cxx_atomic_contention_t const volatile*);
1528_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 -05001529
1530template <class _Atp, class _Fn>
Louis Dionne08cd5cb2020-02-24 11:39:48 -05001531struct __libcpp_atomic_wait_backoff_impl {
1532 _Atp* __a;
1533 _Fn __test_fn;
Louis Dionne3dde4ab2020-02-24 10:09:29 -05001534 _LIBCPP_AVAILABILITY_SYNC
Louis Dionne08cd5cb2020-02-24 11:39:48 -05001535 _LIBCPP_INLINE_VISIBILITY bool operator()(chrono::nanoseconds __elapsed) const
1536 {
Olivier Giroux161e6e82020-02-18 09:58:34 -05001537 if(__elapsed > chrono::microseconds(64))
1538 {
1539 auto const __monitor = __libcpp_atomic_monitor(__a);
1540 if(__test_fn())
1541 return true;
1542 __libcpp_atomic_wait(__a, __monitor);
1543 }
1544 else if(__elapsed > chrono::microseconds(4))
1545 __libcpp_thread_yield();
1546 else
Marek Kurdejc79652f2020-11-15 16:17:52 +01001547 {} // poll
Olivier Giroux161e6e82020-02-18 09:58:34 -05001548 return false;
Louis Dionne08cd5cb2020-02-24 11:39:48 -05001549 }
1550};
1551
1552template <class _Atp, class _Fn>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05001553_LIBCPP_AVAILABILITY_SYNC
Louis Dionne08cd5cb2020-02-24 11:39:48 -05001554_LIBCPP_INLINE_VISIBILITY bool __cxx_atomic_wait(_Atp* __a, _Fn && __test_fn)
1555{
1556 __libcpp_atomic_wait_backoff_impl<_Atp, typename decay<_Fn>::type> __backoff_fn = {__a, __test_fn};
1557 return __libcpp_thread_poll_with_backoff(__test_fn, __backoff_fn);
Olivier Giroux161e6e82020-02-18 09:58:34 -05001558}
1559
1560#else // _LIBCPP_HAS_NO_PLATFORM_WAIT
1561
1562template <class _Tp>
1563_LIBCPP_INLINE_VISIBILITY void __cxx_atomic_notify_all(__cxx_atomic_impl<_Tp> const volatile*) { }
1564template <class _Tp>
1565_LIBCPP_INLINE_VISIBILITY void __cxx_atomic_notify_one(__cxx_atomic_impl<_Tp> const volatile*) { }
1566template <class _Atp, class _Fn>
1567_LIBCPP_INLINE_VISIBILITY bool __cxx_atomic_wait(_Atp*, _Fn && __test_fn)
1568{
1569 return __libcpp_thread_poll_with_backoff(__test_fn, __libcpp_timed_backoff_policy());
1570}
1571
1572#endif // _LIBCPP_HAS_NO_PLATFORM_WAIT
1573
1574template <class _Atp, class _Tp>
Louis Dionne08cd5cb2020-02-24 11:39:48 -05001575struct __cxx_atomic_wait_test_fn_impl {
1576 _Atp* __a;
1577 _Tp __val;
1578 memory_order __order;
1579 _LIBCPP_INLINE_VISIBILITY bool operator()() const
1580 {
1581 return !__cxx_nonatomic_compare_equal(__cxx_atomic_load(__a, __order), __val);
1582 }
1583};
1584
1585template <class _Atp, class _Tp>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05001586_LIBCPP_AVAILABILITY_SYNC
Olivier Giroux161e6e82020-02-18 09:58:34 -05001587_LIBCPP_INLINE_VISIBILITY bool __cxx_atomic_wait(_Atp* __a, _Tp const __val, memory_order __order)
1588{
Louis Dionne08cd5cb2020-02-24 11:39:48 -05001589 __cxx_atomic_wait_test_fn_impl<_Atp, _Tp> __test_fn = {__a, __val, __order};
Olivier Giroux161e6e82020-02-18 09:58:34 -05001590 return __cxx_atomic_wait(__a, __test_fn);
1591}
1592
Howard Hinnant138f5922010-12-07 20:46:14 +00001593// general atomic<T>
1594
1595template <class _Tp, bool = is_integral<_Tp>::value && !is_same<_Tp, bool>::value>
1596struct __atomic_base // false
1597{
Davide Italiano011f80a2019-03-05 18:40:49 +00001598 mutable __cxx_atomic_impl<_Tp> __a_;
Howard Hinnant138f5922010-12-07 20:46:14 +00001599
JF Bastienfdb42c22016-03-25 15:48:21 +00001600#if defined(__cpp_lib_atomic_is_always_lock_free)
1601 static _LIBCPP_CONSTEXPR bool is_always_lock_free = __atomic_always_lock_free(sizeof(__a_), 0);
1602#endif
1603
Howard Hinnant138f5922010-12-07 20:46:14 +00001604 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001605 bool is_lock_free() const volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001606 {return __cxx_atomic_is_lock_free(sizeof(_Tp));}
Howard Hinnant138f5922010-12-07 20:46:14 +00001607 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001608 bool is_lock_free() const _NOEXCEPT
Eric Fiselier3fd22c22015-06-13 00:23:07 +00001609 {return static_cast<__atomic_base const volatile*>(this)->is_lock_free();}
Howard Hinnant138f5922010-12-07 20:46:14 +00001610 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001611 void store(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001612 _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
Davide Italiano011f80a2019-03-05 18:40:49 +00001613 {__cxx_atomic_store(&__a_, __d, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001614 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001615 void store(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001616 _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
Davide Italiano011f80a2019-03-05 18:40:49 +00001617 {__cxx_atomic_store(&__a_, __d, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001618 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001619 _Tp load(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001620 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
Davide Italiano011f80a2019-03-05 18:40:49 +00001621 {return __cxx_atomic_load(&__a_, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001622 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001623 _Tp load(memory_order __m = memory_order_seq_cst) const _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001624 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
Davide Italiano011f80a2019-03-05 18:40:49 +00001625 {return __cxx_atomic_load(&__a_, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001626 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001627 operator _Tp() const volatile _NOEXCEPT {return load();}
Howard Hinnant138f5922010-12-07 20:46:14 +00001628 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001629 operator _Tp() const _NOEXCEPT {return load();}
Howard Hinnant138f5922010-12-07 20:46:14 +00001630 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001631 _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001632 {return __cxx_atomic_exchange(&__a_, __d, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001633 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001634 _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001635 {return __cxx_atomic_exchange(&__a_, __d, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001636 _LIBCPP_INLINE_VISIBILITY
1637 bool compare_exchange_weak(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001638 memory_order __s, memory_order __f) volatile _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001639 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Davide Italiano011f80a2019-03-05 18:40:49 +00001640 {return __cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001641 _LIBCPP_INLINE_VISIBILITY
1642 bool compare_exchange_weak(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001643 memory_order __s, memory_order __f) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001644 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Davide Italiano011f80a2019-03-05 18:40:49 +00001645 {return __cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001646 _LIBCPP_INLINE_VISIBILITY
1647 bool compare_exchange_strong(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001648 memory_order __s, memory_order __f) volatile _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001649 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Davide Italiano011f80a2019-03-05 18:40:49 +00001650 {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001651 _LIBCPP_INLINE_VISIBILITY
1652 bool compare_exchange_strong(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001653 memory_order __s, memory_order __f) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001654 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Davide Italiano011f80a2019-03-05 18:40:49 +00001655 {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001656 _LIBCPP_INLINE_VISIBILITY
1657 bool compare_exchange_weak(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001658 memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001659 {return __cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001660 _LIBCPP_INLINE_VISIBILITY
1661 bool compare_exchange_weak(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001662 memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001663 {return __cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001664 _LIBCPP_INLINE_VISIBILITY
1665 bool compare_exchange_strong(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001666 memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001667 {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001668 _LIBCPP_INLINE_VISIBILITY
1669 bool compare_exchange_strong(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001670 memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001671 {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001672
Louis Dionne3dde4ab2020-02-24 10:09:29 -05001673 _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 -05001674 {__cxx_atomic_wait(&__a_, __v, __m);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05001675 _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 -05001676 {__cxx_atomic_wait(&__a_, __v, __m);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05001677 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_one() volatile _NOEXCEPT
Olivier Giroux161e6e82020-02-18 09:58:34 -05001678 {__cxx_atomic_notify_one(&__a_);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05001679 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_one() _NOEXCEPT
Olivier Giroux161e6e82020-02-18 09:58:34 -05001680 {__cxx_atomic_notify_one(&__a_);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05001681 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_all() volatile _NOEXCEPT
Olivier Giroux161e6e82020-02-18 09:58:34 -05001682 {__cxx_atomic_notify_all(&__a_);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05001683 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_all() _NOEXCEPT
Olivier Giroux161e6e82020-02-18 09:58:34 -05001684 {__cxx_atomic_notify_all(&__a_);}
1685
Raul Tambre4e0e88f2021-06-06 19:02:20 +03001686#if _LIBCPP_STD_VER > 17
1687 _LIBCPP_INLINE_VISIBILITY constexpr
1688 __atomic_base() noexcept(is_nothrow_default_constructible_v<_Tp>) : __a_(_Tp()) {}
1689#else
Howard Hinnant138f5922010-12-07 20:46:14 +00001690 _LIBCPP_INLINE_VISIBILITY
Davide Italiano011f80a2019-03-05 18:40:49 +00001691 __atomic_base() _NOEXCEPT _LIBCPP_DEFAULT
Raul Tambre4e0e88f2021-06-06 19:02:20 +03001692#endif
Howard Hinnant3d284222013-05-02 20:18:43 +00001693
Davide Italiano011f80a2019-03-05 18:40:49 +00001694 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
1695 __atomic_base(_Tp __d) _NOEXCEPT : __a_(__d) {}
1696
Eric Fiselier2d8515f2017-01-06 20:58:25 +00001697#ifndef _LIBCPP_CXX03_LANG
Howard Hinnant138f5922010-12-07 20:46:14 +00001698 __atomic_base(const __atomic_base&) = delete;
Eric Fiselier2d8515f2017-01-06 20:58:25 +00001699#else
Howard Hinnant6ac60f82010-12-08 17:20:28 +00001700private:
Olivier Giroux161e6e82020-02-18 09:58:34 -05001701 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant6ac60f82010-12-08 17:20:28 +00001702 __atomic_base(const __atomic_base&);
Eric Fiselier2d8515f2017-01-06 20:58:25 +00001703#endif
Howard Hinnant138f5922010-12-07 20:46:14 +00001704};
1705
JF Bastienfdb42c22016-03-25 15:48:21 +00001706#if defined(__cpp_lib_atomic_is_always_lock_free)
1707template <class _Tp, bool __b>
1708_LIBCPP_CONSTEXPR bool __atomic_base<_Tp, __b>::is_always_lock_free;
1709#endif
1710
Howard Hinnant138f5922010-12-07 20:46:14 +00001711// atomic<Integral>
1712
1713template <class _Tp>
1714struct __atomic_base<_Tp, true>
1715 : public __atomic_base<_Tp, false>
1716{
1717 typedef __atomic_base<_Tp, false> __base;
Raul Tambre4e0e88f2021-06-06 19:02:20 +03001718
1719 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
Howard Hinnant3d284222013-05-02 20:18:43 +00001720 __atomic_base() _NOEXCEPT _LIBCPP_DEFAULT
Raul Tambre4e0e88f2021-06-06 19:02:20 +03001721
Howard Hinnant138f5922010-12-07 20:46:14 +00001722 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001723 _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __base(__d) {}
Howard Hinnant138f5922010-12-07 20:46:14 +00001724
1725 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001726 _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001727 {return __cxx_atomic_fetch_add(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001728 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001729 _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001730 {return __cxx_atomic_fetch_add(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001731 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001732 _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001733 {return __cxx_atomic_fetch_sub(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001734 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001735 _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001736 {return __cxx_atomic_fetch_sub(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001737 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001738 _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001739 {return __cxx_atomic_fetch_and(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001740 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001741 _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001742 {return __cxx_atomic_fetch_and(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001743 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001744 _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001745 {return __cxx_atomic_fetch_or(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001746 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001747 _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001748 {return __cxx_atomic_fetch_or(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001749 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001750 _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001751 {return __cxx_atomic_fetch_xor(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001752 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001753 _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001754 {return __cxx_atomic_fetch_xor(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001755
1756 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001757 _Tp operator++(int) volatile _NOEXCEPT {return fetch_add(_Tp(1));}
Howard Hinnant138f5922010-12-07 20:46:14 +00001758 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001759 _Tp operator++(int) _NOEXCEPT {return fetch_add(_Tp(1));}
Howard Hinnant138f5922010-12-07 20:46:14 +00001760 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001761 _Tp operator--(int) volatile _NOEXCEPT {return fetch_sub(_Tp(1));}
Howard Hinnant138f5922010-12-07 20:46:14 +00001762 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001763 _Tp operator--(int) _NOEXCEPT {return fetch_sub(_Tp(1));}
Howard Hinnant138f5922010-12-07 20:46:14 +00001764 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001765 _Tp operator++() volatile _NOEXCEPT {return fetch_add(_Tp(1)) + _Tp(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001766 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001767 _Tp operator++() _NOEXCEPT {return fetch_add(_Tp(1)) + _Tp(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001768 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001769 _Tp operator--() volatile _NOEXCEPT {return fetch_sub(_Tp(1)) - _Tp(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001770 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001771 _Tp operator--() _NOEXCEPT {return fetch_sub(_Tp(1)) - _Tp(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001772 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001773 _Tp operator+=(_Tp __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001774 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001775 _Tp operator+=(_Tp __op) _NOEXCEPT {return fetch_add(__op) + __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001776 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001777 _Tp operator-=(_Tp __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001778 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001779 _Tp operator-=(_Tp __op) _NOEXCEPT {return fetch_sub(__op) - __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001780 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001781 _Tp operator&=(_Tp __op) volatile _NOEXCEPT {return fetch_and(__op) & __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001782 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001783 _Tp operator&=(_Tp __op) _NOEXCEPT {return fetch_and(__op) & __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001784 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001785 _Tp operator|=(_Tp __op) volatile _NOEXCEPT {return fetch_or(__op) | __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001786 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001787 _Tp operator|=(_Tp __op) _NOEXCEPT {return fetch_or(__op) | __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001788 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001789 _Tp operator^=(_Tp __op) volatile _NOEXCEPT {return fetch_xor(__op) ^ __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001790 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001791 _Tp operator^=(_Tp __op) _NOEXCEPT {return fetch_xor(__op) ^ __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001792};
1793
1794// atomic<T>
1795
1796template <class _Tp>
1797struct atomic
1798 : public __atomic_base<_Tp>
1799{
1800 typedef __atomic_base<_Tp> __base;
Olivier Giroux161e6e82020-02-18 09:58:34 -05001801 typedef _Tp value_type;
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07001802 typedef value_type difference_type;
Raul Tambre4e0e88f2021-06-06 19:02:20 +03001803
1804#if _LIBCPP_STD_VER > 17
1805 _LIBCPP_INLINE_VISIBILITY
1806 atomic() = default;
1807#else
Howard Hinnant138f5922010-12-07 20:46:14 +00001808 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3d284222013-05-02 20:18:43 +00001809 atomic() _NOEXCEPT _LIBCPP_DEFAULT
Raul Tambre4e0e88f2021-06-06 19:02:20 +03001810#endif
1811
Howard Hinnant138f5922010-12-07 20:46:14 +00001812 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001813 _LIBCPP_CONSTEXPR atomic(_Tp __d) _NOEXCEPT : __base(__d) {}
Howard Hinnant96e4cd62010-12-07 23:24:41 +00001814
1815 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001816 _Tp operator=(_Tp __d) volatile _NOEXCEPT
Howard Hinnant96e4cd62010-12-07 23:24:41 +00001817 {__base::store(__d); return __d;}
1818 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001819 _Tp operator=(_Tp __d) _NOEXCEPT
Howard Hinnant96e4cd62010-12-07 23:24:41 +00001820 {__base::store(__d); return __d;}
Ruslan Arutyunyan033093f2021-02-01 10:12:09 -05001821
1822 atomic& operator=(const atomic&) = delete;
1823 atomic& operator=(const atomic&) volatile = delete;
Howard Hinnant138f5922010-12-07 20:46:14 +00001824};
1825
1826// atomic<T*>
1827
1828template <class _Tp>
1829struct atomic<_Tp*>
1830 : public __atomic_base<_Tp*>
1831{
Howard Hinnant96e4cd62010-12-07 23:24:41 +00001832 typedef __atomic_base<_Tp*> __base;
Olivier Giroux161e6e82020-02-18 09:58:34 -05001833 typedef _Tp* value_type;
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07001834 typedef ptrdiff_t difference_type;
Raul Tambre4e0e88f2021-06-06 19:02:20 +03001835
Howard Hinnant138f5922010-12-07 20:46:14 +00001836 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3d284222013-05-02 20:18:43 +00001837 atomic() _NOEXCEPT _LIBCPP_DEFAULT
Raul Tambre4e0e88f2021-06-06 19:02:20 +03001838
Howard Hinnant138f5922010-12-07 20:46:14 +00001839 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001840 _LIBCPP_CONSTEXPR atomic(_Tp* __d) _NOEXCEPT : __base(__d) {}
Howard Hinnant138f5922010-12-07 20:46:14 +00001841
1842 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001843 _Tp* operator=(_Tp* __d) volatile _NOEXCEPT
Howard Hinnant96e4cd62010-12-07 23:24:41 +00001844 {__base::store(__d); return __d;}
1845 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001846 _Tp* operator=(_Tp* __d) _NOEXCEPT
Howard Hinnant96e4cd62010-12-07 23:24:41 +00001847 {__base::store(__d); return __d;}
1848
1849 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00001850 _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst)
Howard Hinnanteee2c142012-04-11 20:14:21 +00001851 volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001852 {return __cxx_atomic_fetch_add(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001853 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001854 _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001855 {return __cxx_atomic_fetch_add(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001856 _LIBCPP_INLINE_VISIBILITY
1857 _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst)
Howard Hinnanteee2c142012-04-11 20:14:21 +00001858 volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001859 {return __cxx_atomic_fetch_sub(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001860 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001861 _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001862 {return __cxx_atomic_fetch_sub(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001863
1864 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001865 _Tp* operator++(int) volatile _NOEXCEPT {return fetch_add(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001866 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001867 _Tp* operator++(int) _NOEXCEPT {return fetch_add(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001868 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001869 _Tp* operator--(int) volatile _NOEXCEPT {return fetch_sub(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001870 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001871 _Tp* operator--(int) _NOEXCEPT {return fetch_sub(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001872 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001873 _Tp* operator++() volatile _NOEXCEPT {return fetch_add(1) + 1;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001874 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001875 _Tp* operator++() _NOEXCEPT {return fetch_add(1) + 1;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001876 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001877 _Tp* operator--() volatile _NOEXCEPT {return fetch_sub(1) - 1;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001878 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001879 _Tp* operator--() _NOEXCEPT {return fetch_sub(1) - 1;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001880 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001881 _Tp* operator+=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001882 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001883 _Tp* operator+=(ptrdiff_t __op) _NOEXCEPT {return fetch_add(__op) + __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001884 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001885 _Tp* operator-=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001886 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001887 _Tp* operator-=(ptrdiff_t __op) _NOEXCEPT {return fetch_sub(__op) - __op;}
Ruslan Arutyunyan033093f2021-02-01 10:12:09 -05001888
1889 atomic& operator=(const atomic&) = delete;
1890 atomic& operator=(const atomic&) volatile = delete;
Howard Hinnant138f5922010-12-07 20:46:14 +00001891};
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001892
1893// atomic_is_lock_free
1894
1895template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001896_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001897bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00001898atomic_is_lock_free(const volatile atomic<_Tp>* __o) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001899{
Howard Hinnant138f5922010-12-07 20:46:14 +00001900 return __o->is_lock_free();
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001901}
1902
1903template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001904_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001905bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00001906atomic_is_lock_free(const atomic<_Tp>* __o) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001907{
Howard Hinnant138f5922010-12-07 20:46:14 +00001908 return __o->is_lock_free();
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001909}
1910
1911// atomic_init
1912
1913template <class _Tp>
Raul Tambre4e0e88f2021-06-06 19:02:20 +03001914_LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001915void
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07001916atomic_init(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001917{
Davide Italiano011f80a2019-03-05 18:40:49 +00001918 __cxx_atomic_init(&__o->__a_, __d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001919}
1920
1921template <class _Tp>
Raul Tambre4e0e88f2021-06-06 19:02:20 +03001922_LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001923void
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07001924atomic_init(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001925{
Davide Italiano011f80a2019-03-05 18:40:49 +00001926 __cxx_atomic_init(&__o->__a_, __d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001927}
1928
1929// atomic_store
1930
1931template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001932_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001933void
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07001934atomic_store(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001935{
Howard Hinnant138f5922010-12-07 20:46:14 +00001936 __o->store(__d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001937}
1938
1939template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001940_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001941void
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07001942atomic_store(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001943{
Howard Hinnant138f5922010-12-07 20:46:14 +00001944 __o->store(__d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001945}
1946
1947// atomic_store_explicit
1948
1949template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001950_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001951void
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07001952atomic_store_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001953 _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001954{
Howard Hinnant138f5922010-12-07 20:46:14 +00001955 __o->store(__d, __m);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001956}
1957
1958template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001959_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001960void
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07001961atomic_store_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001962 _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001963{
Howard Hinnant138f5922010-12-07 20:46:14 +00001964 __o->store(__d, __m);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001965}
1966
1967// atomic_load
1968
1969template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001970_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001971_Tp
Howard Hinnanteee2c142012-04-11 20:14:21 +00001972atomic_load(const volatile atomic<_Tp>* __o) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001973{
Howard Hinnant138f5922010-12-07 20:46:14 +00001974 return __o->load();
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001975}
1976
1977template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001978_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001979_Tp
Howard Hinnanteee2c142012-04-11 20:14:21 +00001980atomic_load(const atomic<_Tp>* __o) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001981{
Howard Hinnant138f5922010-12-07 20:46:14 +00001982 return __o->load();
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001983}
1984
1985// atomic_load_explicit
1986
1987template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001988_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001989_Tp
Howard Hinnanteee2c142012-04-11 20:14:21 +00001990atomic_load_explicit(const volatile atomic<_Tp>* __o, memory_order __m) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001991 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001992{
Howard Hinnant138f5922010-12-07 20:46:14 +00001993 return __o->load(__m);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001994}
1995
1996template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001997_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001998_Tp
Howard Hinnanteee2c142012-04-11 20:14:21 +00001999atomic_load_explicit(const atomic<_Tp>* __o, memory_order __m) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00002000 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002001{
Howard Hinnant138f5922010-12-07 20:46:14 +00002002 return __o->load(__m);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002003}
2004
2005// atomic_exchange
2006
2007template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002008_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002009_Tp
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002010atomic_exchange(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002011{
Howard Hinnant138f5922010-12-07 20:46:14 +00002012 return __o->exchange(__d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002013}
2014
2015template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002016_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002017_Tp
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002018atomic_exchange(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002019{
Howard Hinnant138f5922010-12-07 20:46:14 +00002020 return __o->exchange(__d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002021}
2022
2023// atomic_exchange_explicit
2024
2025template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002026_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002027_Tp
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002028atomic_exchange_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002029{
Howard Hinnant138f5922010-12-07 20:46:14 +00002030 return __o->exchange(__d, __m);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002031}
2032
2033template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002034_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002035_Tp
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002036atomic_exchange_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002037{
Howard Hinnant138f5922010-12-07 20:46:14 +00002038 return __o->exchange(__d, __m);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002039}
2040
2041// atomic_compare_exchange_weak
2042
2043template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002044_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002045bool
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002046atomic_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 +00002047{
Howard Hinnant138f5922010-12-07 20:46:14 +00002048 return __o->compare_exchange_weak(*__e, __d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002049}
2050
2051template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002052_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002053bool
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002054atomic_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 +00002055{
Howard Hinnant138f5922010-12-07 20:46:14 +00002056 return __o->compare_exchange_weak(*__e, __d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002057}
2058
2059// atomic_compare_exchange_strong
2060
2061template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002062_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002063bool
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002064atomic_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 +00002065{
Howard Hinnant138f5922010-12-07 20:46:14 +00002066 return __o->compare_exchange_strong(*__e, __d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002067}
2068
2069template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002070_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002071bool
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002072atomic_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 +00002073{
Howard Hinnant138f5922010-12-07 20:46:14 +00002074 return __o->compare_exchange_strong(*__e, __d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002075}
2076
2077// atomic_compare_exchange_weak_explicit
2078
2079template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002080_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002081bool
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002082atomic_compare_exchange_weak_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e,
2083 typename atomic<_Tp>::value_type __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00002084 memory_order __s, memory_order __f) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00002085 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002086{
Howard Hinnant138f5922010-12-07 20:46:14 +00002087 return __o->compare_exchange_weak(*__e, __d, __s, __f);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002088}
2089
2090template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002091_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002092bool
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002093atomic_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 +00002094 memory_order __s, memory_order __f) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00002095 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002096{
Howard Hinnant138f5922010-12-07 20:46:14 +00002097 return __o->compare_exchange_weak(*__e, __d, __s, __f);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002098}
2099
2100// atomic_compare_exchange_strong_explicit
2101
2102template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002103_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002104bool
2105atomic_compare_exchange_strong_explicit(volatile atomic<_Tp>* __o,
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002106 typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00002107 memory_order __s, memory_order __f) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00002108 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002109{
Howard Hinnant138f5922010-12-07 20:46:14 +00002110 return __o->compare_exchange_strong(*__e, __d, __s, __f);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002111}
2112
2113template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002114_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002115bool
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002116atomic_compare_exchange_strong_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e,
2117 typename atomic<_Tp>::value_type __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00002118 memory_order __s, memory_order __f) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00002119 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002120{
Howard Hinnant138f5922010-12-07 20:46:14 +00002121 return __o->compare_exchange_strong(*__e, __d, __s, __f);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002122}
2123
Olivier Giroux161e6e82020-02-18 09:58:34 -05002124// atomic_wait
2125
2126template <class _Tp>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002127_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002128void atomic_wait(const volatile atomic<_Tp>* __o,
2129 typename atomic<_Tp>::value_type __v) _NOEXCEPT
2130{
2131 return __o->wait(__v);
2132}
2133
2134template <class _Tp>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002135_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002136void atomic_wait(const atomic<_Tp>* __o,
2137 typename atomic<_Tp>::value_type __v) _NOEXCEPT
2138{
2139 return __o->wait(__v);
2140}
2141
2142// atomic_wait_explicit
2143
2144template <class _Tp>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002145_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002146void atomic_wait_explicit(const volatile atomic<_Tp>* __o,
2147 typename atomic<_Tp>::value_type __v,
2148 memory_order __m) _NOEXCEPT
2149 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
2150{
2151 return __o->wait(__v, __m);
2152}
2153
2154template <class _Tp>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002155_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002156void atomic_wait_explicit(const atomic<_Tp>* __o,
2157 typename atomic<_Tp>::value_type __v,
2158 memory_order __m) _NOEXCEPT
2159 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
2160{
2161 return __o->wait(__v, __m);
2162}
2163
2164// atomic_notify_one
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_notify_one(volatile atomic<_Tp>* __o) _NOEXCEPT
2169{
2170 __o->notify_one();
2171}
2172template <class _Tp>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002173_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002174void atomic_notify_one(atomic<_Tp>* __o) _NOEXCEPT
2175{
2176 __o->notify_one();
2177}
2178
2179// atomic_notify_one
2180
2181template <class _Tp>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002182_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002183void atomic_notify_all(volatile atomic<_Tp>* __o) _NOEXCEPT
2184{
2185 __o->notify_all();
2186}
2187template <class _Tp>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002188_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002189void atomic_notify_all(atomic<_Tp>* __o) _NOEXCEPT
2190{
2191 __o->notify_all();
2192}
2193
Howard Hinnant138f5922010-12-07 20:46:14 +00002194// atomic_fetch_add
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002195
2196template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002197_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002198typename enable_if
2199<
Olivier Girouxdf485172020-09-11 12:13:35 -07002200 is_integral<_Tp>::value && !is_same<_Tp, bool>::value && !is_const<_Tp>::value,
Howard Hinnant138f5922010-12-07 20:46:14 +00002201 _Tp
2202>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002203atomic_fetch_add(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002204{
Howard Hinnant138f5922010-12-07 20:46:14 +00002205 return __o->fetch_add(__op);
2206}
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002207
Howard Hinnant138f5922010-12-07 20:46:14 +00002208template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002209_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002210typename enable_if
2211<
Olivier Girouxdf485172020-09-11 12:13:35 -07002212 is_integral<_Tp>::value && !is_same<_Tp, bool>::value && !is_const<_Tp>::value,
Howard Hinnant138f5922010-12-07 20:46:14 +00002213 _Tp
2214>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002215atomic_fetch_add(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002216{
2217 return __o->fetch_add(__op);
2218}
2219
Olivier Girouxdf485172020-09-11 12:13:35 -07002220template <class _Tp>
2221_LIBCPP_INLINE_VISIBILITY
Louis Dionneb39adc52020-11-04 14:07:59 -05002222_Tp*
Olivier Girouxdf485172020-09-11 12:13:35 -07002223atomic_fetch_add(volatile atomic<_Tp*>* __o, typename atomic<_Tp*>::difference_type __op) _NOEXCEPT
2224{
2225 return __o->fetch_add(__op);
2226}
2227
2228template <class _Tp>
2229_LIBCPP_INLINE_VISIBILITY
Louis Dionneb39adc52020-11-04 14:07:59 -05002230_Tp*
Olivier Girouxdf485172020-09-11 12:13:35 -07002231atomic_fetch_add(atomic<_Tp*>* __o, typename atomic<_Tp*>::difference_type __op) _NOEXCEPT
2232{
2233 return __o->fetch_add(__op);
2234}
2235
Howard Hinnant138f5922010-12-07 20:46:14 +00002236// atomic_fetch_add_explicit
2237
2238template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002239_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002240typename enable_if
2241<
Olivier Girouxdf485172020-09-11 12:13:35 -07002242 is_integral<_Tp>::value && !is_same<_Tp, bool>::value && !is_const<_Tp>::value,
Howard Hinnant138f5922010-12-07 20:46:14 +00002243 _Tp
2244>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002245atomic_fetch_add_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002246{
2247 return __o->fetch_add(__op, __m);
2248}
2249
2250template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002251_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002252typename enable_if
2253<
Olivier Girouxdf485172020-09-11 12:13:35 -07002254 is_integral<_Tp>::value && !is_same<_Tp, bool>::value && !is_const<_Tp>::value,
Howard Hinnant138f5922010-12-07 20:46:14 +00002255 _Tp
2256>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002257atomic_fetch_add_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002258{
2259 return __o->fetch_add(__op, __m);
2260}
2261
Olivier Girouxdf485172020-09-11 12:13:35 -07002262template <class _Tp>
2263_LIBCPP_INLINE_VISIBILITY
2264_Tp*
2265atomic_fetch_add_explicit(volatile atomic<_Tp*>* __o, typename atomic<_Tp*>::difference_type __op, memory_order __m) _NOEXCEPT
2266{
2267 return __o->fetch_add(__op, __m);
2268}
2269
2270template <class _Tp>
2271_LIBCPP_INLINE_VISIBILITY
2272_Tp*
2273atomic_fetch_add_explicit(atomic<_Tp*>* __o, typename atomic<_Tp*>::difference_type __op, memory_order __m) _NOEXCEPT
2274{
2275 return __o->fetch_add(__op, __m);
2276}
2277
Howard Hinnant138f5922010-12-07 20:46:14 +00002278// atomic_fetch_sub
2279
2280template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002281_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002282typename enable_if
2283<
Olivier Girouxdf485172020-09-11 12:13:35 -07002284 is_integral<_Tp>::value && !is_same<_Tp, bool>::value && !is_const<_Tp>::value,
Howard Hinnant138f5922010-12-07 20:46:14 +00002285 _Tp
2286>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002287atomic_fetch_sub(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002288{
2289 return __o->fetch_sub(__op);
2290}
2291
2292template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002293_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002294typename enable_if
2295<
Olivier Girouxdf485172020-09-11 12:13:35 -07002296 is_integral<_Tp>::value && !is_same<_Tp, bool>::value && !is_const<_Tp>::value,
Howard Hinnant138f5922010-12-07 20:46:14 +00002297 _Tp
2298>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002299atomic_fetch_sub(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002300{
2301 return __o->fetch_sub(__op);
2302}
2303
Olivier Girouxdf485172020-09-11 12:13:35 -07002304template <class _Tp>
2305_LIBCPP_INLINE_VISIBILITY
2306_Tp*
2307atomic_fetch_sub(volatile atomic<_Tp*>* __o, typename atomic<_Tp*>::difference_type __op) _NOEXCEPT
2308{
2309 return __o->fetch_sub(__op);
2310}
2311
2312template <class _Tp>
2313_LIBCPP_INLINE_VISIBILITY
2314_Tp*
2315atomic_fetch_sub(atomic<_Tp*>* __o, typename atomic<_Tp*>::difference_type __op) _NOEXCEPT
2316{
2317 return __o->fetch_sub(__op);
2318}
2319
Howard Hinnant138f5922010-12-07 20:46:14 +00002320// atomic_fetch_sub_explicit
2321
2322template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002323_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002324typename enable_if
2325<
Olivier Girouxdf485172020-09-11 12:13:35 -07002326 is_integral<_Tp>::value && !is_same<_Tp, bool>::value && !is_const<_Tp>::value,
Howard Hinnant138f5922010-12-07 20:46:14 +00002327 _Tp
2328>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002329atomic_fetch_sub_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002330{
2331 return __o->fetch_sub(__op, __m);
2332}
2333
2334template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002335_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002336typename enable_if
2337<
Olivier Girouxdf485172020-09-11 12:13:35 -07002338 is_integral<_Tp>::value && !is_same<_Tp, bool>::value && !is_const<_Tp>::value,
Howard Hinnant138f5922010-12-07 20:46:14 +00002339 _Tp
2340>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002341atomic_fetch_sub_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002342{
2343 return __o->fetch_sub(__op, __m);
2344}
2345
Olivier Girouxdf485172020-09-11 12:13:35 -07002346template <class _Tp>
2347_LIBCPP_INLINE_VISIBILITY
2348_Tp*
2349atomic_fetch_sub_explicit(volatile atomic<_Tp*>* __o, typename atomic<_Tp*>::difference_type __op, memory_order __m) _NOEXCEPT
2350{
2351 return __o->fetch_sub(__op, __m);
2352}
2353
2354template <class _Tp>
2355_LIBCPP_INLINE_VISIBILITY
2356_Tp*
2357atomic_fetch_sub_explicit(atomic<_Tp*>* __o, typename atomic<_Tp*>::difference_type __op, memory_order __m) _NOEXCEPT
2358{
2359 return __o->fetch_sub(__op, __m);
2360}
2361
Howard Hinnant138f5922010-12-07 20:46:14 +00002362// atomic_fetch_and
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_and(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002372{
2373 return __o->fetch_and(__op);
2374}
2375
2376template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002377_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002378typename enable_if
2379<
2380 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2381 _Tp
2382>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002383atomic_fetch_and(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002384{
2385 return __o->fetch_and(__op);
2386}
2387
2388// atomic_fetch_and_explicit
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_and_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002398{
2399 return __o->fetch_and(__op, __m);
2400}
2401
2402template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002403_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002404typename enable_if
2405<
2406 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2407 _Tp
2408>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002409atomic_fetch_and_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002410{
2411 return __o->fetch_and(__op, __m);
2412}
2413
2414// atomic_fetch_or
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_or(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002424{
2425 return __o->fetch_or(__op);
2426}
2427
2428template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002429_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002430typename enable_if
2431<
2432 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2433 _Tp
2434>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002435atomic_fetch_or(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002436{
2437 return __o->fetch_or(__op);
2438}
2439
2440// atomic_fetch_or_explicit
2441
2442template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002443_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002444typename enable_if
2445<
2446 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2447 _Tp
2448>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002449atomic_fetch_or_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002450{
2451 return __o->fetch_or(__op, __m);
2452}
2453
2454template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002455_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002456typename enable_if
2457<
2458 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2459 _Tp
2460>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002461atomic_fetch_or_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002462{
2463 return __o->fetch_or(__op, __m);
2464}
2465
2466// atomic_fetch_xor
2467
2468template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002469_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002470typename enable_if
2471<
2472 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2473 _Tp
2474>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002475atomic_fetch_xor(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002476{
2477 return __o->fetch_xor(__op);
2478}
2479
2480template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002481_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002482typename enable_if
2483<
2484 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2485 _Tp
2486>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002487atomic_fetch_xor(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002488{
2489 return __o->fetch_xor(__op);
2490}
2491
2492// atomic_fetch_xor_explicit
2493
2494template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002495_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002496typename enable_if
2497<
2498 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2499 _Tp
2500>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002501atomic_fetch_xor_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002502{
2503 return __o->fetch_xor(__op, __m);
2504}
2505
2506template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002507_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002508typename enable_if
2509<
2510 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2511 _Tp
2512>::type
Olivier Girouxdf5bfa32020-09-09 10:00:09 -07002513atomic_fetch_xor_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002514{
2515 return __o->fetch_xor(__op, __m);
2516}
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002517
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002518// flag type and operations
2519
2520typedef struct atomic_flag
2521{
Davide Italiano011f80a2019-03-05 18:40:49 +00002522 __cxx_atomic_impl<_LIBCPP_ATOMIC_FLAG_TYPE> __a_;
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002523
2524 _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002525 bool test(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
2526 {return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m);}
2527 _LIBCPP_INLINE_VISIBILITY
2528 bool test(memory_order __m = memory_order_seq_cst) const _NOEXCEPT
2529 {return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m);}
2530
2531 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00002532 bool test_and_set(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00002533 {return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);}
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002534 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00002535 bool test_and_set(memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00002536 {return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);}
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002537 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00002538 void clear(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00002539 {__cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);}
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002540 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00002541 void clear(memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00002542 {__cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);}
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002543
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002544 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002545 void wait(bool __v, memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
2546 {__cxx_atomic_wait(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002547 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002548 void wait(bool __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT
2549 {__cxx_atomic_wait(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002550 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002551 void notify_one() volatile _NOEXCEPT
2552 {__cxx_atomic_notify_one(&__a_);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002553 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002554 void notify_one() _NOEXCEPT
2555 {__cxx_atomic_notify_one(&__a_);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002556 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002557 void notify_all() volatile _NOEXCEPT
2558 {__cxx_atomic_notify_all(&__a_);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002559 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002560 void notify_all() _NOEXCEPT
2561 {__cxx_atomic_notify_all(&__a_);}
2562
Raul Tambre4e0e88f2021-06-06 19:02:20 +03002563#if _LIBCPP_STD_VER > 17
2564 _LIBCPP_INLINE_VISIBILITY constexpr
2565 atomic_flag() _NOEXCEPT : __a_(false) {}
2566#else
Olivier Giroux161e6e82020-02-18 09:58:34 -05002567 _LIBCPP_INLINE_VISIBILITY
Davide Italiano011f80a2019-03-05 18:40:49 +00002568 atomic_flag() _NOEXCEPT _LIBCPP_DEFAULT
Raul Tambre4e0e88f2021-06-06 19:02:20 +03002569#endif
Howard Hinnant3d284222013-05-02 20:18:43 +00002570
Marshall Clowcf990752018-04-25 14:27:29 +00002571 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
Eric Fiselierfec26a92016-05-03 02:12:26 +00002572 atomic_flag(bool __b) _NOEXCEPT : __a_(__b) {} // EXTENSION
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002573
Eric Fiselier2d8515f2017-01-06 20:58:25 +00002574#ifndef _LIBCPP_CXX03_LANG
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002575 atomic_flag(const atomic_flag&) = delete;
2576 atomic_flag& operator=(const atomic_flag&) = delete;
2577 atomic_flag& operator=(const atomic_flag&) volatile = delete;
Eric Fiselier2d8515f2017-01-06 20:58:25 +00002578#else
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002579private:
Olivier Giroux161e6e82020-02-18 09:58:34 -05002580 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002581 atomic_flag(const atomic_flag&);
Olivier Giroux161e6e82020-02-18 09:58:34 -05002582 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002583 atomic_flag& operator=(const atomic_flag&);
Olivier Giroux161e6e82020-02-18 09:58:34 -05002584 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002585 atomic_flag& operator=(const atomic_flag&) volatile;
Eric Fiselier2d8515f2017-01-06 20:58:25 +00002586#endif
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002587} atomic_flag;
2588
Olivier Giroux161e6e82020-02-18 09:58:34 -05002589
2590inline _LIBCPP_INLINE_VISIBILITY
2591bool
2592atomic_flag_test(const volatile atomic_flag* __o) _NOEXCEPT
2593{
2594 return __o->test();
2595}
2596
2597inline _LIBCPP_INLINE_VISIBILITY
2598bool
2599atomic_flag_test(const atomic_flag* __o) _NOEXCEPT
2600{
2601 return __o->test();
2602}
2603
2604inline _LIBCPP_INLINE_VISIBILITY
2605bool
2606atomic_flag_test_explicit(const volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
2607{
2608 return __o->test(__m);
2609}
2610
2611inline _LIBCPP_INLINE_VISIBILITY
2612bool
2613atomic_flag_test_explicit(const atomic_flag* __o, memory_order __m) _NOEXCEPT
2614{
2615 return __o->test(__m);
2616}
2617
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002618inline _LIBCPP_INLINE_VISIBILITY
2619bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00002620atomic_flag_test_and_set(volatile atomic_flag* __o) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002621{
2622 return __o->test_and_set();
2623}
2624
2625inline _LIBCPP_INLINE_VISIBILITY
2626bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00002627atomic_flag_test_and_set(atomic_flag* __o) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002628{
2629 return __o->test_and_set();
2630}
2631
2632inline _LIBCPP_INLINE_VISIBILITY
2633bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00002634atomic_flag_test_and_set_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002635{
2636 return __o->test_and_set(__m);
2637}
2638
2639inline _LIBCPP_INLINE_VISIBILITY
2640bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00002641atomic_flag_test_and_set_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002642{
2643 return __o->test_and_set(__m);
2644}
2645
2646inline _LIBCPP_INLINE_VISIBILITY
2647void
Howard Hinnanteee2c142012-04-11 20:14:21 +00002648atomic_flag_clear(volatile atomic_flag* __o) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002649{
2650 __o->clear();
2651}
2652
2653inline _LIBCPP_INLINE_VISIBILITY
2654void
Howard Hinnanteee2c142012-04-11 20:14:21 +00002655atomic_flag_clear(atomic_flag* __o) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002656{
2657 __o->clear();
2658}
2659
2660inline _LIBCPP_INLINE_VISIBILITY
2661void
Howard Hinnanteee2c142012-04-11 20:14:21 +00002662atomic_flag_clear_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002663{
2664 __o->clear(__m);
2665}
2666
2667inline _LIBCPP_INLINE_VISIBILITY
2668void
Howard Hinnanteee2c142012-04-11 20:14:21 +00002669atomic_flag_clear_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002670{
2671 __o->clear(__m);
2672}
2673
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002674inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
Olivier Giroux161e6e82020-02-18 09:58:34 -05002675void
2676atomic_flag_wait(const volatile atomic_flag* __o, bool __v) _NOEXCEPT
2677{
2678 __o->wait(__v);
2679}
2680
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002681inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
Olivier Giroux161e6e82020-02-18 09:58:34 -05002682void
2683atomic_flag_wait(const atomic_flag* __o, bool __v) _NOEXCEPT
2684{
2685 __o->wait(__v);
2686}
2687
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002688inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
Olivier Giroux161e6e82020-02-18 09:58:34 -05002689void
2690atomic_flag_wait_explicit(const volatile atomic_flag* __o,
2691 bool __v, memory_order __m) _NOEXCEPT
2692{
2693 __o->wait(__v, __m);
2694}
2695
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002696inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
Olivier Giroux161e6e82020-02-18 09:58:34 -05002697void
2698atomic_flag_wait_explicit(const atomic_flag* __o,
2699 bool __v, memory_order __m) _NOEXCEPT
2700{
2701 __o->wait(__v, __m);
2702}
2703
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002704inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
Olivier Giroux161e6e82020-02-18 09:58:34 -05002705void
2706atomic_flag_notify_one(volatile atomic_flag* __o) _NOEXCEPT
2707{
2708 __o->notify_one();
2709}
2710
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002711inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
Olivier Giroux161e6e82020-02-18 09:58:34 -05002712void
2713atomic_flag_notify_one(atomic_flag* __o) _NOEXCEPT
2714{
2715 __o->notify_one();
2716}
2717
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002718inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
Olivier Giroux161e6e82020-02-18 09:58:34 -05002719void
2720atomic_flag_notify_all(volatile atomic_flag* __o) _NOEXCEPT
2721{
2722 __o->notify_all();
2723}
2724
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002725inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
Olivier Giroux161e6e82020-02-18 09:58:34 -05002726void
2727atomic_flag_notify_all(atomic_flag* __o) _NOEXCEPT
2728{
2729 __o->notify_all();
2730}
2731
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002732// fences
2733
2734inline _LIBCPP_INLINE_VISIBILITY
2735void
Howard Hinnanteee2c142012-04-11 20:14:21 +00002736atomic_thread_fence(memory_order __m) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002737{
Davide Italiano011f80a2019-03-05 18:40:49 +00002738 __cxx_atomic_thread_fence(__m);
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002739}
2740
2741inline _LIBCPP_INLINE_VISIBILITY
2742void
Howard Hinnanteee2c142012-04-11 20:14:21 +00002743atomic_signal_fence(memory_order __m) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002744{
Davide Italiano011f80a2019-03-05 18:40:49 +00002745 __cxx_atomic_signal_fence(__m);
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002746}
2747
Howard Hinnant96e4cd62010-12-07 23:24:41 +00002748// Atomics for standard typedef types
2749
Howard Hinnantf0af8d92013-01-04 18:58:50 +00002750typedef atomic<bool> atomic_bool;
Howard Hinnant96e4cd62010-12-07 23:24:41 +00002751typedef atomic<char> atomic_char;
2752typedef atomic<signed char> atomic_schar;
2753typedef atomic<unsigned char> atomic_uchar;
2754typedef atomic<short> atomic_short;
2755typedef atomic<unsigned short> atomic_ushort;
2756typedef atomic<int> atomic_int;
2757typedef atomic<unsigned int> atomic_uint;
2758typedef atomic<long> atomic_long;
2759typedef atomic<unsigned long> atomic_ulong;
2760typedef atomic<long long> atomic_llong;
2761typedef atomic<unsigned long long> atomic_ullong;
Arthur O'Dwyerafa5d5f2021-04-18 21:47:08 -04002762#ifndef _LIBCPP_HAS_NO_CHAR8_T
Marek Kurdej91bebaa2020-11-24 21:07:06 +01002763typedef atomic<char8_t> atomic_char8_t;
2764#endif
Howard Hinnant96e4cd62010-12-07 23:24:41 +00002765typedef atomic<char16_t> atomic_char16_t;
2766typedef atomic<char32_t> atomic_char32_t;
2767typedef atomic<wchar_t> atomic_wchar_t;
2768
2769typedef atomic<int_least8_t> atomic_int_least8_t;
2770typedef atomic<uint_least8_t> atomic_uint_least8_t;
2771typedef atomic<int_least16_t> atomic_int_least16_t;
2772typedef atomic<uint_least16_t> atomic_uint_least16_t;
2773typedef atomic<int_least32_t> atomic_int_least32_t;
2774typedef atomic<uint_least32_t> atomic_uint_least32_t;
2775typedef atomic<int_least64_t> atomic_int_least64_t;
2776typedef atomic<uint_least64_t> atomic_uint_least64_t;
2777
2778typedef atomic<int_fast8_t> atomic_int_fast8_t;
2779typedef atomic<uint_fast8_t> atomic_uint_fast8_t;
2780typedef atomic<int_fast16_t> atomic_int_fast16_t;
2781typedef atomic<uint_fast16_t> atomic_uint_fast16_t;
2782typedef atomic<int_fast32_t> atomic_int_fast32_t;
2783typedef atomic<uint_fast32_t> atomic_uint_fast32_t;
2784typedef atomic<int_fast64_t> atomic_int_fast64_t;
2785typedef atomic<uint_fast64_t> atomic_uint_fast64_t;
2786
Marshall Clowf710afc2016-06-30 15:28:38 +00002787typedef atomic< int8_t> atomic_int8_t;
2788typedef atomic<uint8_t> atomic_uint8_t;
2789typedef atomic< int16_t> atomic_int16_t;
2790typedef atomic<uint16_t> atomic_uint16_t;
2791typedef atomic< int32_t> atomic_int32_t;
2792typedef atomic<uint32_t> atomic_uint32_t;
2793typedef atomic< int64_t> atomic_int64_t;
2794typedef atomic<uint64_t> atomic_uint64_t;
2795
Howard Hinnant96e4cd62010-12-07 23:24:41 +00002796typedef atomic<intptr_t> atomic_intptr_t;
2797typedef atomic<uintptr_t> atomic_uintptr_t;
2798typedef atomic<size_t> atomic_size_t;
2799typedef atomic<ptrdiff_t> atomic_ptrdiff_t;
2800typedef atomic<intmax_t> atomic_intmax_t;
2801typedef atomic<uintmax_t> atomic_uintmax_t;
2802
Olivier Giroux161e6e82020-02-18 09:58:34 -05002803// atomic_*_lock_free : prefer the contention type most highly, then the largest lock-free type
2804
2805#ifdef __cpp_lib_atomic_is_always_lock_free
2806# define _LIBCPP_CONTENTION_LOCK_FREE __atomic_always_lock_free(sizeof(__cxx_contention_t), 0)
2807#else
2808# define _LIBCPP_CONTENTION_LOCK_FREE false
2809#endif
2810
2811#if ATOMIC_LLONG_LOCK_FREE == 2
2812typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, long long>::type __libcpp_signed_lock_free;
2813typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned long long>::type __libcpp_unsigned_lock_free;
2814#elif ATOMIC_INT_LOCK_FREE == 2
2815typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, int>::type __libcpp_signed_lock_free;
2816typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned int>::type __libcpp_unsigned_lock_free;
2817#elif ATOMIC_SHORT_LOCK_FREE == 2
2818typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, short>::type __libcpp_signed_lock_free;
2819typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned short>::type __libcpp_unsigned_lock_free;
2820#elif ATOMIC_CHAR_LOCK_FREE == 2
2821typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, char>::type __libcpp_signed_lock_free;
2822typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned char>::type __libcpp_unsigned_lock_free;
2823#else
2824 // No signed/unsigned lock-free types
2825#endif
2826
2827typedef atomic<__libcpp_signed_lock_free> atomic_signed_lock_free;
2828typedef atomic<__libcpp_unsigned_lock_free> atomic_unsigned_lock_free;
2829
Howard Hinnantf1f066a2010-09-29 21:20:03 +00002830#define ATOMIC_FLAG_INIT {false}
Howard Hinnant953c31d2010-10-04 18:52:54 +00002831#define ATOMIC_VAR_INIT(__v) {__v}
2832
Howard Hinnant71be7292010-09-27 21:17:38 +00002833_LIBCPP_END_NAMESPACE_STD
2834
Louis Dionne2b1ceaa2021-04-20 12:03:32 -04002835#endif // _LIBCPP_ATOMIC