blob: 9c289865378827b2fa1f1c56bdd228627ed3a038 [file] [log] [blame]
Howard Hinnant71be7292010-09-27 21:17:38 +00001// -*- C++ -*-
2//===--------------------------- atomic -----------------------------------===//
3//
Chandler Carruth7642bb12019-01-19 08:50:56 +00004// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Howard Hinnant71be7292010-09-27 21:17:38 +00007//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP_ATOMIC
11#define _LIBCPP_ATOMIC
12
13/*
14 atomic synopsis
15
16namespace std
17{
18
JF Bastienfdb42c22016-03-25 15:48:21 +000019// feature test macro
20
21#define __cpp_lib_atomic_is_always_lock_free // as specified by SG10
22
Davide Italiano011f80a2019-03-05 18:40:49 +000023 // order and consistency
Howard Hinnant71be7292010-09-27 21:17:38 +000024
Davide Italiano011f80a2019-03-05 18:40:49 +000025 enum memory_order: unspecified // enum class in C++20
26 {
27 relaxed,
28 consume, // load-consume
29 acquire, // load-acquire
30 release, // store-release
31 acq_rel, // store-release load-acquire
32 seq_cst // store-release load-acquire
33 };
34
35 inline constexpr auto memory_order_relaxed = memory_order::relaxed;
36 inline constexpr auto memory_order_consume = memory_order::consume;
37 inline constexpr auto memory_order_acquire = memory_order::acquire;
38 inline constexpr auto memory_order_release = memory_order::release;
39 inline constexpr auto memory_order_acq_rel = memory_order::acq_rel;
40 inline constexpr auto memory_order_seq_cst = memory_order::seq_cst;
Howard Hinnant71be7292010-09-27 21:17:38 +000041
Howard Hinnanteee2c142012-04-11 20:14:21 +000042template <class T> T kill_dependency(T y) noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +000043
44// lock-free property
45
Howard Hinnant931e3402013-01-21 20:39:41 +000046#define ATOMIC_BOOL_LOCK_FREE unspecified
Howard Hinnant71be7292010-09-27 21:17:38 +000047#define ATOMIC_CHAR_LOCK_FREE unspecified
48#define ATOMIC_CHAR16_T_LOCK_FREE unspecified
49#define ATOMIC_CHAR32_T_LOCK_FREE unspecified
50#define ATOMIC_WCHAR_T_LOCK_FREE unspecified
51#define ATOMIC_SHORT_LOCK_FREE unspecified
52#define ATOMIC_INT_LOCK_FREE unspecified
53#define ATOMIC_LONG_LOCK_FREE unspecified
54#define ATOMIC_LLONG_LOCK_FREE unspecified
Howard Hinnant931e3402013-01-21 20:39:41 +000055#define ATOMIC_POINTER_LOCK_FREE unspecified
Howard Hinnant71be7292010-09-27 21:17:38 +000056
Howard Hinnant71be7292010-09-27 21:17:38 +000057template <class T>
58struct atomic
59{
Olivier Giroux6031a712020-06-01 14:30:13 -070060 using value_type = T;
61
JF Bastienfdb42c22016-03-25 15:48:21 +000062 static constexpr bool is_always_lock_free;
Howard Hinnanteee2c142012-04-11 20:14:21 +000063 bool is_lock_free() const volatile noexcept;
64 bool is_lock_free() const noexcept;
Olivier Giroux6031a712020-06-01 14:30:13 -070065
66 atomic() noexcept = default;
67 constexpr atomic(T desr) noexcept;
68 atomic(const atomic&) = delete;
69 atomic& operator=(const atomic&) = delete;
70 atomic& operator=(const atomic&) volatile = delete;
71
Howard Hinnanteee2c142012-04-11 20:14:21 +000072 T load(memory_order m = memory_order_seq_cst) const volatile noexcept;
73 T load(memory_order m = memory_order_seq_cst) const noexcept;
74 operator T() const volatile noexcept;
75 operator T() const noexcept;
Olivier Giroux6031a712020-06-01 14:30:13 -070076 void store(T desr, memory_order m = memory_order_seq_cst) volatile noexcept;
77 void store(T desr, memory_order m = memory_order_seq_cst) noexcept;
78 T operator=(T) volatile noexcept;
79 T operator=(T) noexcept;
80
Howard Hinnanteee2c142012-04-11 20:14:21 +000081 T exchange(T desr, memory_order m = memory_order_seq_cst) volatile noexcept;
82 T exchange(T desr, memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +000083 bool compare_exchange_weak(T& expc, T desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +000084 memory_order s, memory_order f) volatile noexcept;
85 bool compare_exchange_weak(T& expc, T desr, memory_order s, memory_order f) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +000086 bool compare_exchange_strong(T& expc, T desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +000087 memory_order s, memory_order f) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +000088 bool compare_exchange_strong(T& expc, T desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +000089 memory_order s, memory_order f) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +000090 bool compare_exchange_weak(T& expc, T desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +000091 memory_order m = memory_order_seq_cst) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +000092 bool compare_exchange_weak(T& expc, T desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +000093 memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +000094 bool compare_exchange_strong(T& expc, T desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +000095 memory_order m = memory_order_seq_cst) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +000096 bool compare_exchange_strong(T& expc, T desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +000097 memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +000098
Olivier Giroux6031a712020-06-01 14:30:13 -070099 void wait(T, memory_order = memory_order::seq_cst) const volatile noexcept;
100 void wait(T, memory_order = memory_order::seq_cst) const noexcept;
101 void notify_one() volatile noexcept;
102 void notify_one() noexcept;
103 void notify_all() volatile noexcept;
104 void notify_all() noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +0000105};
106
107template <>
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000108struct atomic<integral>
Howard Hinnant71be7292010-09-27 21:17:38 +0000109{
Olivier Giroux6031a712020-06-01 14:30:13 -0700110 using value_type = integral;
111
JF Bastienfdb42c22016-03-25 15:48:21 +0000112 static constexpr bool is_always_lock_free;
Howard Hinnanteee2c142012-04-11 20:14:21 +0000113 bool is_lock_free() const volatile noexcept;
114 bool is_lock_free() const noexcept;
Olivier Giroux6031a712020-06-01 14:30:13 -0700115
116 atomic() noexcept = default;
117 constexpr atomic(integral desr) noexcept;
118 atomic(const atomic&) = delete;
119 atomic& operator=(const atomic&) = delete;
120 atomic& operator=(const atomic&) volatile = delete;
121
Howard Hinnanteee2c142012-04-11 20:14:21 +0000122 integral load(memory_order m = memory_order_seq_cst) const volatile noexcept;
123 integral load(memory_order m = memory_order_seq_cst) const noexcept;
124 operator integral() const volatile noexcept;
125 operator integral() const noexcept;
Olivier Giroux6031a712020-06-01 14:30:13 -0700126 void store(integral desr, memory_order m = memory_order_seq_cst) volatile noexcept;
127 void store(integral desr, memory_order m = memory_order_seq_cst) noexcept;
128 integral operator=(integral desr) volatile noexcept;
129 integral operator=(integral desr) noexcept;
130
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000131 integral exchange(integral desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000132 memory_order m = memory_order_seq_cst) volatile noexcept;
133 integral exchange(integral desr, memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000134 bool compare_exchange_weak(integral& expc, integral desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000135 memory_order s, memory_order f) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000136 bool compare_exchange_weak(integral& expc, integral desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000137 memory_order s, memory_order f) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000138 bool compare_exchange_strong(integral& expc, integral desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000139 memory_order s, memory_order f) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000140 bool compare_exchange_strong(integral& expc, integral desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000141 memory_order s, memory_order f) 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 m = memory_order_seq_cst) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000144 bool compare_exchange_weak(integral& expc, integral desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000145 memory_order m = memory_order_seq_cst) 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 m = memory_order_seq_cst) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000148 bool compare_exchange_strong(integral& expc, integral desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000149 memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +0000150
Olivier Giroux6031a712020-06-01 14:30:13 -0700151 integral fetch_add(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
Howard Hinnanteee2c142012-04-11 20:14:21 +0000152 integral fetch_add(integral op, memory_order m = memory_order_seq_cst) noexcept;
Olivier Giroux6031a712020-06-01 14:30:13 -0700153 integral fetch_sub(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
Howard Hinnanteee2c142012-04-11 20:14:21 +0000154 integral fetch_sub(integral op, memory_order m = memory_order_seq_cst) noexcept;
Olivier Giroux6031a712020-06-01 14:30:13 -0700155 integral fetch_and(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
Howard Hinnanteee2c142012-04-11 20:14:21 +0000156 integral fetch_and(integral op, memory_order m = memory_order_seq_cst) noexcept;
Olivier Giroux6031a712020-06-01 14:30:13 -0700157 integral fetch_or(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
Howard Hinnanteee2c142012-04-11 20:14:21 +0000158 integral fetch_or(integral op, memory_order m = memory_order_seq_cst) noexcept;
Olivier Giroux6031a712020-06-01 14:30:13 -0700159 integral fetch_xor(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
Howard Hinnanteee2c142012-04-11 20:14:21 +0000160 integral fetch_xor(integral op, memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +0000161
Howard Hinnanteee2c142012-04-11 20:14:21 +0000162 integral operator++(int) volatile noexcept;
163 integral operator++(int) noexcept;
164 integral operator--(int) volatile noexcept;
165 integral operator--(int) noexcept;
166 integral operator++() volatile noexcept;
167 integral operator++() noexcept;
168 integral operator--() volatile noexcept;
169 integral operator--() noexcept;
170 integral operator+=(integral op) volatile noexcept;
171 integral operator+=(integral op) noexcept;
172 integral operator-=(integral op) volatile noexcept;
173 integral operator-=(integral op) noexcept;
174 integral operator&=(integral op) volatile noexcept;
175 integral operator&=(integral op) 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;
Olivier Giroux6031a712020-06-01 14:30:13 -0700180
181 void wait(integral, memory_order = memory_order::seq_cst) const volatile noexcept;
182 void wait(integral, memory_order = memory_order::seq_cst) const noexcept;
183 void notify_one() volatile noexcept;
184 void notify_one() noexcept;
185 void notify_all() volatile noexcept;
186 void notify_all() noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +0000187};
188
189template <class T>
190struct atomic<T*>
Howard Hinnant71be7292010-09-27 21:17:38 +0000191{
Olivier Giroux6031a712020-06-01 14:30:13 -0700192 using value_type = T*;
193
JF Bastienfdb42c22016-03-25 15:48:21 +0000194 static constexpr bool is_always_lock_free;
Howard Hinnanteee2c142012-04-11 20:14:21 +0000195 bool is_lock_free() const volatile noexcept;
196 bool is_lock_free() const noexcept;
Olivier Giroux6031a712020-06-01 14:30:13 -0700197
198 atomic() noexcept = default;
199 constexpr atomic(T* desr) noexcept;
200 atomic(const atomic&) = delete;
201 atomic& operator=(const atomic&) = delete;
202 atomic& operator=(const atomic&) volatile = delete;
203
Howard Hinnanteee2c142012-04-11 20:14:21 +0000204 T* load(memory_order m = memory_order_seq_cst) const volatile noexcept;
205 T* load(memory_order m = memory_order_seq_cst) const noexcept;
206 operator T*() const volatile noexcept;
207 operator T*() const noexcept;
Olivier Giroux6031a712020-06-01 14:30:13 -0700208 void store(T* desr, memory_order m = memory_order_seq_cst) volatile noexcept;
209 void store(T* desr, memory_order m = memory_order_seq_cst) noexcept;
210 T* operator=(T*) volatile noexcept;
211 T* operator=(T*) noexcept;
212
Howard Hinnanteee2c142012-04-11 20:14:21 +0000213 T* exchange(T* desr, memory_order m = memory_order_seq_cst) volatile noexcept;
214 T* exchange(T* desr, memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000215 bool compare_exchange_weak(T*& expc, T* desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000216 memory_order s, memory_order f) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000217 bool compare_exchange_weak(T*& expc, T* desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000218 memory_order s, memory_order f) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000219 bool compare_exchange_strong(T*& expc, T* desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000220 memory_order s, memory_order f) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000221 bool compare_exchange_strong(T*& expc, T* desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000222 memory_order s, memory_order f) 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 m = memory_order_seq_cst) 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 m = memory_order_seq_cst) 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 m = memory_order_seq_cst) 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 m = memory_order_seq_cst) noexcept;
231 T* fetch_add(ptrdiff_t op, memory_order m = memory_order_seq_cst) volatile noexcept;
232 T* fetch_add(ptrdiff_t op, memory_order m = memory_order_seq_cst) noexcept;
233 T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst) volatile noexcept;
234 T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000235
Howard Hinnanteee2c142012-04-11 20:14:21 +0000236 T* operator++(int) volatile noexcept;
237 T* operator++(int) noexcept;
238 T* operator--(int) volatile noexcept;
239 T* operator--(int) noexcept;
240 T* operator++() volatile noexcept;
241 T* operator++() noexcept;
242 T* operator--() volatile noexcept;
243 T* operator--() noexcept;
244 T* operator+=(ptrdiff_t op) volatile noexcept;
245 T* operator+=(ptrdiff_t op) noexcept;
246 T* operator-=(ptrdiff_t op) volatile noexcept;
247 T* operator-=(ptrdiff_t op) noexcept;
Olivier Giroux6031a712020-06-01 14:30:13 -0700248
249 void wait(T*, memory_order = memory_order::seq_cst) const volatile noexcept;
250 void wait(T*, memory_order = memory_order::seq_cst) const noexcept;
251 void notify_one() volatile noexcept;
252 void notify_one() noexcept;
253 void notify_all() volatile noexcept;
254 void notify_all() noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +0000255};
256
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000257
258template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700259 bool atomic_is_lock_free(const volatile atomic<T>* obj) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000260
261template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700262 bool atomic_is_lock_free(const atomic<T>* obj) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000263
264template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700265 void atomic_store(volatile atomic<T>* obj, T desr) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000266
267template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700268 void atomic_store(atomic<T>* obj, T desr) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000269
270template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700271 void atomic_store_explicit(volatile atomic<T>* obj, T desr, memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000272
273template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700274 void atomic_store_explicit(atomic<T>* obj, T desr, memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000275
276template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700277 T atomic_load(const volatile atomic<T>* obj) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000278
279template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700280 T atomic_load(const atomic<T>* obj) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000281
282template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700283 T atomic_load_explicit(const volatile atomic<T>* obj, memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000284
285template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700286 T atomic_load_explicit(const atomic<T>* obj, memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000287
288template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700289 T atomic_exchange(volatile atomic<T>* obj, T desr) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000290
291template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700292 T atomic_exchange(atomic<T>* obj, T desr) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000293
294template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700295 T atomic_exchange_explicit(volatile atomic<T>* obj, T desr, memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000296
297template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700298 T atomic_exchange_explicit(atomic<T>* obj, T desr, memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000299
300template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700301 bool atomic_compare_exchange_weak(volatile atomic<T>* obj, T* expc, T desr) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000302
303template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700304 bool atomic_compare_exchange_weak(atomic<T>* obj, T* expc, T desr) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000305
306template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700307 bool atomic_compare_exchange_strong(volatile atomic<T>* obj, T* expc, T desr) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000308
309template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700310 bool atomic_compare_exchange_strong(atomic<T>* obj, T* expc, T desr) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000311
312template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700313 bool atomic_compare_exchange_weak_explicit(volatile atomic<T>* obj, T* expc,
314 T desr,
315 memory_order s, memory_order f) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000316
317template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700318 bool atomic_compare_exchange_weak_explicit(atomic<T>* obj, T* expc, T desr,
319 memory_order s, memory_order f) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000320
321template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700322 bool atomic_compare_exchange_strong_explicit(volatile atomic<T>* obj,
323 T* expc, T desr,
324 memory_order s, memory_order f) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000325
326template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700327 bool atomic_compare_exchange_strong_explicit(atomic<T>* obj, T* expc,
328 T desr,
329 memory_order s, memory_order f) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000330
331template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700332 void atomic_wait(const volatile atomic<T>* obj, T old) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000333
334template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700335 void atomic_wait(const atomic<T>* obj, T old) noexcept;
336
337template <class T>
338 void atomic_wait_explicit(const volatile atomic<T>* obj, T old, memory_order m) noexcept;
339
340template <class T>
341 void atomic_wait_explicit(const atomic<T>* obj, T old, memory_order m) noexcept;
342
343template <class T>
344 void atomic_one(volatile atomic<T>* obj) noexcept;
345
346template <class T>
347 void atomic_one(atomic<T>* obj) noexcept;
348
349template <class T>
350 void atomic_all(volatile atomic<T>* obj) noexcept;
351
352template <class T>
353 void atomic_all(atomic<T>* obj) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000354
355template <class Integral>
Olivier Giroux6031a712020-06-01 14:30:13 -0700356 Integral atomic_fetch_add(volatile atomic<Integral>* obj, Integral op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000357
358template <class Integral>
Olivier Giroux6031a712020-06-01 14:30:13 -0700359 Integral atomic_fetch_add(atomic<Integral>* obj, Integral op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000360
361template <class Integral>
Olivier Giroux6031a712020-06-01 14:30:13 -0700362 Integral atomic_fetch_add_explicit(volatile atomic<Integral>* obj, Integral op,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000363 memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000364template <class Integral>
Olivier Giroux6031a712020-06-01 14:30:13 -0700365 Integral atomic_fetch_add_explicit(atomic<Integral>* obj, Integral op,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000366 memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000367template <class Integral>
Olivier Giroux6031a712020-06-01 14:30:13 -0700368 Integral atomic_fetch_sub(volatile atomic<Integral>* obj, Integral op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000369
370template <class Integral>
Olivier Giroux6031a712020-06-01 14:30:13 -0700371 Integral atomic_fetch_sub(atomic<Integral>* obj, Integral op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000372
373template <class Integral>
Olivier Giroux6031a712020-06-01 14:30:13 -0700374 Integral atomic_fetch_sub_explicit(volatile atomic<Integral>* obj, Integral op,
375 memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000376
377template <class Integral>
Olivier Giroux6031a712020-06-01 14:30:13 -0700378 Integral atomic_fetch_sub_explicit(atomic<Integral>* obj, Integral op,
379 memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000380
381template <class Integral>
Olivier Giroux6031a712020-06-01 14:30:13 -0700382 Integral atomic_fetch_and(volatile atomic<Integral>* obj, Integral op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000383
384template <class Integral>
Olivier Giroux6031a712020-06-01 14:30:13 -0700385 Integral atomic_fetch_and(atomic<Integral>* obj, Integral op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000386
387template <class Integral>
Olivier Giroux6031a712020-06-01 14:30:13 -0700388 Integral atomic_fetch_and_explicit(volatile atomic<Integral>* obj, Integral op,
389 memory_order m) noexcept;
390
391template <class Integral>
392 Integral atomic_fetch_and_explicit(atomic<Integral>* obj, Integral op,
393 memory_order m) noexcept;
394
395template <class Integral>
396 Integral atomic_fetch_or(volatile atomic<Integral>* obj, Integral op) noexcept;
397
398template <class Integral>
399 Integral atomic_fetch_or(atomic<Integral>* obj, Integral op) noexcept;
400
401template <class Integral>
402 Integral atomic_fetch_or_explicit(volatile atomic<Integral>* obj, Integral op,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000403 memory_order m) noexcept;
Olivier Giroux6031a712020-06-01 14:30:13 -0700404
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000405template <class Integral>
Olivier Giroux6031a712020-06-01 14:30:13 -0700406 Integral atomic_fetch_or_explicit(atomic<Integral>* obj, Integral op,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000407 memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000408
409template <class Integral>
Olivier Giroux6031a712020-06-01 14:30:13 -0700410 Integral atomic_fetch_xor(volatile atomic<Integral>* obj, Integral op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000411
412template <class Integral>
Olivier Giroux6031a712020-06-01 14:30:13 -0700413 Integral atomic_fetch_xor(atomic<Integral>* obj, Integral op) noexcept;
414
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000415template <class Integral>
Olivier Giroux6031a712020-06-01 14:30:13 -0700416 Integral atomic_fetch_xor_explicit(volatile atomic<Integral>* obj, Integral op,
417 memory_order m) noexcept;
418
419template <class Integral>
420 Integral atomic_fetch_xor_explicit(atomic<Integral>* obj, Integral op,
421 memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000422
423template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700424 T* atomic_fetch_add(volatile atomic<T*>* obj, ptrdiff_t op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000425
426template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700427 T* atomic_fetch_add(atomic<T*>* obj, ptrdiff_t op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000428
429template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700430 T* atomic_fetch_add_explicit(volatile atomic<T*>* obj, ptrdiff_t op,
431 memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000432
433template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700434 T* atomic_fetch_add_explicit(atomic<T*>* obj, ptrdiff_t op, memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000435
436template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700437 T* atomic_fetch_sub(volatile atomic<T*>* obj, ptrdiff_t op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000438
439template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700440 T* atomic_fetch_sub(atomic<T*>* obj, ptrdiff_t op) noexcept;
441
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000442template <class T>
Olivier Giroux6031a712020-06-01 14:30:13 -0700443 T* atomic_fetch_sub_explicit(volatile atomic<T*>* obj, ptrdiff_t op,
444 memory_order m) noexcept;
445
446template <class T>
447 T* atomic_fetch_sub_explicit(atomic<T*>* obj, ptrdiff_t op, memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000448
449// Atomics for standard typedef types
450
Howard Hinnantf0af8d92013-01-04 18:58:50 +0000451typedef atomic<bool> atomic_bool;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000452typedef atomic<char> atomic_char;
453typedef atomic<signed char> atomic_schar;
454typedef atomic<unsigned char> atomic_uchar;
455typedef atomic<short> atomic_short;
456typedef atomic<unsigned short> atomic_ushort;
457typedef atomic<int> atomic_int;
458typedef atomic<unsigned int> atomic_uint;
459typedef atomic<long> atomic_long;
460typedef atomic<unsigned long> atomic_ulong;
461typedef atomic<long long> atomic_llong;
462typedef atomic<unsigned long long> atomic_ullong;
463typedef atomic<char16_t> atomic_char16_t;
464typedef atomic<char32_t> atomic_char32_t;
465typedef atomic<wchar_t> atomic_wchar_t;
466
467typedef atomic<int_least8_t> atomic_int_least8_t;
468typedef atomic<uint_least8_t> atomic_uint_least8_t;
469typedef atomic<int_least16_t> atomic_int_least16_t;
470typedef atomic<uint_least16_t> atomic_uint_least16_t;
471typedef atomic<int_least32_t> atomic_int_least32_t;
472typedef atomic<uint_least32_t> atomic_uint_least32_t;
473typedef atomic<int_least64_t> atomic_int_least64_t;
474typedef atomic<uint_least64_t> atomic_uint_least64_t;
475
476typedef atomic<int_fast8_t> atomic_int_fast8_t;
477typedef atomic<uint_fast8_t> atomic_uint_fast8_t;
478typedef atomic<int_fast16_t> atomic_int_fast16_t;
479typedef atomic<uint_fast16_t> atomic_uint_fast16_t;
Olivier Giroux6031a712020-06-01 14:30:13 -0700480typedef atomic<int_fast32_t> atomic_int_fast32_t;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000481typedef atomic<uint_fast32_t> atomic_uint_fast32_t;
482typedef atomic<int_fast64_t> atomic_int_fast64_t;
483typedef atomic<uint_fast64_t> atomic_uint_fast64_t;
484
Marshall Clowf710afc2016-06-30 15:28:38 +0000485typedef atomic<int8_t> atomic_int8_t;
486typedef atomic<uint8_t> atomic_uint8_t;
487typedef atomic<int16_t> atomic_int16_t;
488typedef atomic<uint16_t> atomic_uint16_t;
489typedef atomic<int32_t> atomic_int32_t;
490typedef atomic<uint32_t> atomic_uint32_t;
491typedef atomic<int64_t> atomic_int64_t;
492typedef atomic<uint64_t> atomic_uint64_t;
493
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000494typedef atomic<intptr_t> atomic_intptr_t;
495typedef atomic<uintptr_t> atomic_uintptr_t;
496typedef atomic<size_t> atomic_size_t;
497typedef atomic<ptrdiff_t> atomic_ptrdiff_t;
498typedef atomic<intmax_t> atomic_intmax_t;
499typedef atomic<uintmax_t> atomic_uintmax_t;
500
Olivier Giroux6031a712020-06-01 14:30:13 -0700501// flag type and operations
502
503typedef struct atomic_flag
504{
505 atomic_flag() noexcept = default;
506 atomic_flag(const atomic_flag&) = delete;
507 atomic_flag& operator=(const atomic_flag&) = delete;
508 atomic_flag& operator=(const atomic_flag&) volatile = delete;
509
510 bool test(memory_order m = memory_order_seq_cst) volatile noexcept;
511 bool test(memory_order m = memory_order_seq_cst) noexcept;
512 bool test_and_set(memory_order m = memory_order_seq_cst) volatile noexcept;
513 bool test_and_set(memory_order m = memory_order_seq_cst) noexcept;
514 void clear(memory_order m = memory_order_seq_cst) volatile noexcept;
515 void clear(memory_order m = memory_order_seq_cst) noexcept;
516
517 void wait(bool, memory_order = memory_order::seq_cst) const volatile noexcept;
518 void wait(bool, memory_order = memory_order::seq_cst) const noexcept;
519 void notify_one() volatile noexcept;
520 void notify_one() noexcept;
521 void notify_all() volatile noexcept;
522 void notify_all() noexcept;
523} atomic_flag;
524
525bool atomic_flag_test(volatile atomic_flag* obj) noexcept;
526bool atomic_flag_test(atomic_flag* obj) noexcept;
527bool atomic_flag_test_explicit(volatile atomic_flag* obj,
528 memory_order m) noexcept;
529bool atomic_flag_test_explicit(atomic_flag* obj, memory_order m) noexcept;
530bool atomic_flag_test_and_set(volatile atomic_flag* obj) noexcept;
531bool atomic_flag_test_and_set(atomic_flag* obj) noexcept;
532bool atomic_flag_test_and_set_explicit(volatile atomic_flag* obj,
533 memory_order m) noexcept;
534bool atomic_flag_test_and_set_explicit(atomic_flag* obj, memory_order m) noexcept;
535void atomic_flag_clear(volatile atomic_flag* obj) noexcept;
536void atomic_flag_clear(atomic_flag* obj) noexcept;
537void atomic_flag_clear_explicit(volatile atomic_flag* obj, memory_order m) noexcept;
538void atomic_flag_clear_explicit(atomic_flag* obj, memory_order m) noexcept;
539
540void atomic_wait(const volatile atomic_flag* obj, T old) noexcept;
541void atomic_wait(const atomic_flag* obj, T old) noexcept;
542void atomic_wait_explicit(const volatile atomic_flag* obj, T old, memory_order m) noexcept;
543void atomic_wait_explicit(const atomic_flag* obj, T old, memory_order m) noexcept;
544void atomic_one(volatile atomic_flag* obj) noexcept;
545void atomic_one(atomic_flag* obj) noexcept;
546void atomic_all(volatile atomic_flag* obj) noexcept;
547void atomic_all(atomic_flag* obj) noexcept;
548
Howard Hinnant71be7292010-09-27 21:17:38 +0000549// fences
550
Howard Hinnanteee2c142012-04-11 20:14:21 +0000551void atomic_thread_fence(memory_order m) noexcept;
552void atomic_signal_fence(memory_order m) noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +0000553
Olivier Giroux6031a712020-06-01 14:30:13 -0700554// deprecated
555
556template <class T>
557 void atomic_init(volatile atomic<T>* obj, typename atomic<T>::value_type desr) noexcept;
558
559template <class T>
560 void atomic_init(atomic<T>* obj, typename atomic<T>::value_type desr) noexcept;
561
562#define ATOMIC_VAR_INIT(value) see below
563
564#define ATOMIC_FLAG_INIT see below
565
Howard Hinnant71be7292010-09-27 21:17:38 +0000566} // std
567
568*/
569
570#include <__config>
Olivier Giroux161e6e82020-02-18 09:58:34 -0500571#include <__threading_support>
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000572#include <cstddef>
573#include <cstdint>
Olivier Giroux161e6e82020-02-18 09:58:34 -0500574#include <cstring>
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000575#include <type_traits>
Marshall Clow0a1e7502018-09-12 19:41:40 +0000576#include <version>
Howard Hinnant71be7292010-09-27 21:17:38 +0000577
Howard Hinnantaaaa52b2011-10-17 20:05:10 +0000578#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
Howard Hinnant71be7292010-09-27 21:17:38 +0000579#pragma GCC system_header
Howard Hinnantaaaa52b2011-10-17 20:05:10 +0000580#endif
Howard Hinnant71be7292010-09-27 21:17:38 +0000581
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000582#ifdef _LIBCPP_HAS_NO_THREADS
Davide Italiano011f80a2019-03-05 18:40:49 +0000583# error <atomic> is not supported on this single threaded system
Eric Fiselier8020b6c2015-08-19 17:21:46 +0000584#endif
Davide Italiano011f80a2019-03-05 18:40:49 +0000585#ifdef _LIBCPP_HAS_NO_ATOMIC_HEADER
586# error <atomic> is not implemented
Eric Fiselier8020b6c2015-08-19 17:21:46 +0000587#endif
Volodymyr Sapsaif3ed1fd2018-05-15 22:38:31 +0000588#ifdef kill_dependency
Davide Italiano011f80a2019-03-05 18:40:49 +0000589# error C++ standard library is incompatible with <stdatomic.h>
Volodymyr Sapsaif3ed1fd2018-05-15 22:38:31 +0000590#endif
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000591
Eric Fiselierb5ab51d2017-01-13 23:45:39 +0000592#define _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) \
593 _LIBCPP_DIAGNOSE_WARNING(__m == memory_order_consume || \
594 __m == memory_order_acquire || \
595 __m == memory_order_acq_rel, \
596 "memory order argument to atomic operation is invalid")
597
598#define _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) \
599 _LIBCPP_DIAGNOSE_WARNING(__m == memory_order_release || \
600 __m == memory_order_acq_rel, \
601 "memory order argument to atomic operation is invalid")
602
603#define _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__m, __f) \
604 _LIBCPP_DIAGNOSE_WARNING(__f == memory_order_release || \
605 __f == memory_order_acq_rel, \
606 "memory order argument to atomic operation is invalid")
607
Howard Hinnant71be7292010-09-27 21:17:38 +0000608_LIBCPP_BEGIN_NAMESPACE_STD
609
Eric Fiselierd4e3e5b2019-03-08 23:15:54 +0000610// Figure out what the underlying type for `memory_order` would be if it were
611// declared as an unscoped enum (accounting for -fshort-enums). Use this result
612// to pin the underlying type in C++20.
613enum __legacy_memory_order {
614 __mo_relaxed,
615 __mo_consume,
616 __mo_acquire,
617 __mo_release,
618 __mo_acq_rel,
619 __mo_seq_cst
620};
621
622typedef underlying_type<__legacy_memory_order>::type __memory_order_underlying_t;
623
Davide Italiano011f80a2019-03-05 18:40:49 +0000624#if _LIBCPP_STD_VER > 17
625
Eric Fiselierd4e3e5b2019-03-08 23:15:54 +0000626enum class memory_order : __memory_order_underlying_t {
627 relaxed = __mo_relaxed,
628 consume = __mo_consume,
629 acquire = __mo_acquire,
630 release = __mo_release,
631 acq_rel = __mo_acq_rel,
632 seq_cst = __mo_seq_cst
Davide Italiano011f80a2019-03-05 18:40:49 +0000633};
634
635inline constexpr auto memory_order_relaxed = memory_order::relaxed;
636inline constexpr auto memory_order_consume = memory_order::consume;
637inline constexpr auto memory_order_acquire = memory_order::acquire;
638inline constexpr auto memory_order_release = memory_order::release;
639inline constexpr auto memory_order_acq_rel = memory_order::acq_rel;
640inline constexpr auto memory_order_seq_cst = memory_order::seq_cst;
641
Davide Italiano011f80a2019-03-05 18:40:49 +0000642#else
643
644typedef enum memory_order {
Eric Fiselierd4e3e5b2019-03-08 23:15:54 +0000645 memory_order_relaxed = __mo_relaxed,
646 memory_order_consume = __mo_consume,
647 memory_order_acquire = __mo_acquire,
648 memory_order_release = __mo_release,
649 memory_order_acq_rel = __mo_acq_rel,
650 memory_order_seq_cst = __mo_seq_cst,
Howard Hinnantdca6e712010-09-28 17:13:38 +0000651} memory_order;
652
Davide Italiano011f80a2019-03-05 18:40:49 +0000653#endif // _LIBCPP_STD_VER > 17
654
Olivier Giroux161e6e82020-02-18 09:58:34 -0500655template <typename _Tp> _LIBCPP_INLINE_VISIBILITY
656bool __cxx_nonatomic_compare_equal(_Tp const& __lhs, _Tp const& __rhs) {
657 return memcmp(&__lhs, &__rhs, sizeof(_Tp)) == 0;
658}
659
Eric Fiselier51525172019-03-08 23:30:26 +0000660static_assert((is_same<underlying_type<memory_order>::type, __memory_order_underlying_t>::value),
Eric Fiselierd4e3e5b2019-03-08 23:15:54 +0000661 "unexpected underlying type for std::memory_order");
Davide Italiano011f80a2019-03-05 18:40:49 +0000662
663#if defined(_LIBCPP_HAS_GCC_ATOMIC_IMP) || \
664 defined(_LIBCPP_ATOMIC_ONLY_USE_BUILTINS)
665
666// [atomics.types.generic]p1 guarantees _Tp is trivially copyable. Because
667// the default operator= in an object is not volatile, a byte-by-byte copy
668// is required.
669template <typename _Tp, typename _Tv> _LIBCPP_INLINE_VISIBILITY
670typename enable_if<is_assignable<_Tp&, _Tv>::value>::type
671__cxx_atomic_assign_volatile(_Tp& __a_value, _Tv const& __val) {
672 __a_value = __val;
673}
674template <typename _Tp, typename _Tv> _LIBCPP_INLINE_VISIBILITY
675typename enable_if<is_assignable<_Tp&, _Tv>::value>::type
676__cxx_atomic_assign_volatile(_Tp volatile& __a_value, _Tv volatile const& __val) {
677 volatile char* __to = reinterpret_cast<volatile char*>(&__a_value);
678 volatile char* __end = __to + sizeof(_Tp);
679 volatile const char* __from = reinterpret_cast<volatile const char*>(&__val);
680 while (__to != __end)
681 *__to++ = *__from++;
682}
683
Davide Italiano31f218a2019-03-05 17:38:33 +0000684#endif
Louis Dionnea1ae0032019-03-04 15:26:27 +0000685
Davide Italiano011f80a2019-03-05 18:40:49 +0000686#if defined(_LIBCPP_HAS_GCC_ATOMIC_IMP)
687
688template <typename _Tp>
689struct __cxx_atomic_base_impl {
690
Eric Fiselier684aaca2015-10-14 08:36:22 +0000691 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier07b2b552016-11-18 06:42:17 +0000692#ifndef _LIBCPP_CXX03_LANG
Davide Italiano011f80a2019-03-05 18:40:49 +0000693 __cxx_atomic_base_impl() _NOEXCEPT = default;
Eric Fiselier684aaca2015-10-14 08:36:22 +0000694#else
Davide Italiano011f80a2019-03-05 18:40:49 +0000695 __cxx_atomic_base_impl() _NOEXCEPT : __a_value() {}
Eric Fiselier07b2b552016-11-18 06:42:17 +0000696#endif // _LIBCPP_CXX03_LANG
Davide Italiano011f80a2019-03-05 18:40:49 +0000697 _LIBCPP_CONSTEXPR explicit __cxx_atomic_base_impl(_Tp value) _NOEXCEPT
Eric Fiselier719e0442015-07-14 17:50:27 +0000698 : __a_value(value) {}
Marshall Clow290eb3f2015-01-11 06:15:59 +0000699 _Tp __a_value;
Dan Albert7b65ace2014-08-09 23:51:51 +0000700};
Dan Albert7b65ace2014-08-09 23:51:51 +0000701
Davide Italiano011f80a2019-03-05 18:40:49 +0000702_LIBCPP_INLINE_VISIBILITY inline _LIBCPP_CONSTEXPR int __to_gcc_order(memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000703 // Avoid switch statement to make this a constexpr.
704 return __order == memory_order_relaxed ? __ATOMIC_RELAXED:
705 (__order == memory_order_acquire ? __ATOMIC_ACQUIRE:
706 (__order == memory_order_release ? __ATOMIC_RELEASE:
707 (__order == memory_order_seq_cst ? __ATOMIC_SEQ_CST:
708 (__order == memory_order_acq_rel ? __ATOMIC_ACQ_REL:
709 __ATOMIC_CONSUME))));
710}
711
Davide Italiano011f80a2019-03-05 18:40:49 +0000712_LIBCPP_INLINE_VISIBILITY inline _LIBCPP_CONSTEXPR int __to_gcc_failure_order(memory_order __order) {
Dan Albert48815f22015-01-06 18:39:37 +0000713 // Avoid switch statement to make this a constexpr.
714 return __order == memory_order_relaxed ? __ATOMIC_RELAXED:
715 (__order == memory_order_acquire ? __ATOMIC_ACQUIRE:
716 (__order == memory_order_release ? __ATOMIC_RELAXED:
717 (__order == memory_order_seq_cst ? __ATOMIC_SEQ_CST:
718 (__order == memory_order_acq_rel ? __ATOMIC_ACQUIRE:
719 __ATOMIC_CONSUME))));
720}
721
Davide Italiano011f80a2019-03-05 18:40:49 +0000722template <typename _Tp>
723_LIBCPP_INLINE_VISIBILITY
724void __cxx_atomic_init(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __val) {
725 __cxx_atomic_assign_volatile(__a->__a_value, __val);
726}
Dan Albert7b65ace2014-08-09 23:51:51 +0000727
728template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000729_LIBCPP_INLINE_VISIBILITY
730void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp>* __a, _Tp __val) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000731 __a->__a_value = __val;
732}
733
Davide Italiano011f80a2019-03-05 18:40:49 +0000734_LIBCPP_INLINE_VISIBILITY inline
735void __cxx_atomic_thread_fence(memory_order __order) {
736 __atomic_thread_fence(__to_gcc_order(__order));
737}
738
739_LIBCPP_INLINE_VISIBILITY inline
740void __cxx_atomic_signal_fence(memory_order __order) {
741 __atomic_signal_fence(__to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000742}
743
744template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000745_LIBCPP_INLINE_VISIBILITY
746void __cxx_atomic_store(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __val,
747 memory_order __order) {
Dan Albert48815f22015-01-06 18:39:37 +0000748 __atomic_store(&__a->__a_value, &__val,
Davide Italiano011f80a2019-03-05 18:40:49 +0000749 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000750}
751
752template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000753_LIBCPP_INLINE_VISIBILITY
754void __cxx_atomic_store(__cxx_atomic_base_impl<_Tp>* __a, _Tp __val,
755 memory_order __order) {
756 __atomic_store(&__a->__a_value, &__val,
757 __to_gcc_order(__order));
758}
759
760template <typename _Tp>
761_LIBCPP_INLINE_VISIBILITY
762_Tp __cxx_atomic_load(const volatile __cxx_atomic_base_impl<_Tp>* __a,
763 memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000764 _Tp __ret;
765 __atomic_load(&__a->__a_value, &__ret,
Davide Italiano011f80a2019-03-05 18:40:49 +0000766 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000767 return __ret;
768}
769
770template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000771_LIBCPP_INLINE_VISIBILITY
772_Tp __cxx_atomic_load(const __cxx_atomic_base_impl<_Tp>* __a, memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000773 _Tp __ret;
774 __atomic_load(&__a->__a_value, &__ret,
Davide Italiano011f80a2019-03-05 18:40:49 +0000775 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000776 return __ret;
777}
778
779template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000780_LIBCPP_INLINE_VISIBILITY
781_Tp __cxx_atomic_exchange(volatile __cxx_atomic_base_impl<_Tp>* __a,
782 _Tp __value, memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000783 _Tp __ret;
784 __atomic_exchange(&__a->__a_value, &__value, &__ret,
Davide Italiano011f80a2019-03-05 18:40:49 +0000785 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000786 return __ret;
787}
788
789template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000790_LIBCPP_INLINE_VISIBILITY
791_Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp>* __a, _Tp __value,
792 memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000793 _Tp __ret;
794 __atomic_exchange(&__a->__a_value, &__value, &__ret,
Davide Italiano011f80a2019-03-05 18:40:49 +0000795 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000796 return __ret;
797}
798
799template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000800_LIBCPP_INLINE_VISIBILITY
801bool __cxx_atomic_compare_exchange_strong(
802 volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value,
JF Bastien6e412d92018-05-26 19:44:45 +0000803 memory_order __success, memory_order __failure) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000804 return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
805 false,
Davide Italiano011f80a2019-03-05 18:40:49 +0000806 __to_gcc_order(__success),
807 __to_gcc_failure_order(__failure));
Dan Albert7b65ace2014-08-09 23:51:51 +0000808}
809
810template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000811_LIBCPP_INLINE_VISIBILITY
812bool __cxx_atomic_compare_exchange_strong(
813 __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success,
JF Bastien6e412d92018-05-26 19:44:45 +0000814 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_weak(
824 volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value,
JF Bastien6e412d92018-05-26 19:44:45 +0000825 memory_order __success, memory_order __failure) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000826 return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
827 true,
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 __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success,
JF Bastien6e412d92018-05-26 19:44:45 +0000836 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>
844struct __skip_amt { enum {value = 1}; };
845
846template <typename _Tp>
847struct __skip_amt<_Tp*> { enum {value = sizeof(_Tp)}; };
848
849// FIXME: Haven't figured out what the spec says about using arrays with
850// atomic_fetch_add. Force a failure rather than creating bad behavior.
851template <typename _Tp>
852struct __skip_amt<_Tp[]> { };
853template <typename _Tp, int n>
854struct __skip_amt<_Tp[n]> { };
855
856template <typename _Tp, typename _Td>
Davide Italiano011f80a2019-03-05 18:40:49 +0000857_LIBCPP_INLINE_VISIBILITY
858_Tp __cxx_atomic_fetch_add(volatile __cxx_atomic_base_impl<_Tp>* __a,
859 _Td __delta, memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000860 return __atomic_fetch_add(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
Davide Italiano011f80a2019-03-05 18:40:49 +0000861 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000862}
863
864template <typename _Tp, typename _Td>
Davide Italiano011f80a2019-03-05 18:40:49 +0000865_LIBCPP_INLINE_VISIBILITY
866_Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp>* __a, _Td __delta,
867 memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000868 return __atomic_fetch_add(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
Davide Italiano011f80a2019-03-05 18:40:49 +0000869 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000870}
871
872template <typename _Tp, typename _Td>
Davide Italiano011f80a2019-03-05 18:40:49 +0000873_LIBCPP_INLINE_VISIBILITY
874_Tp __cxx_atomic_fetch_sub(volatile __cxx_atomic_base_impl<_Tp>* __a,
875 _Td __delta, memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000876 return __atomic_fetch_sub(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
Davide Italiano011f80a2019-03-05 18:40:49 +0000877 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000878}
879
880template <typename _Tp, typename _Td>
Davide Italiano011f80a2019-03-05 18:40:49 +0000881_LIBCPP_INLINE_VISIBILITY
882_Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp>* __a, _Td __delta,
883 memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000884 return __atomic_fetch_sub(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
Davide Italiano011f80a2019-03-05 18:40:49 +0000885 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000886}
887
888template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000889_LIBCPP_INLINE_VISIBILITY
890_Tp __cxx_atomic_fetch_and(volatile __cxx_atomic_base_impl<_Tp>* __a,
891 _Tp __pattern, memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000892 return __atomic_fetch_and(&__a->__a_value, __pattern,
Davide Italiano011f80a2019-03-05 18:40:49 +0000893 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000894}
895
896template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000897_LIBCPP_INLINE_VISIBILITY
898_Tp __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp>* __a,
899 _Tp __pattern, memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000900 return __atomic_fetch_and(&__a->__a_value, __pattern,
Davide Italiano011f80a2019-03-05 18:40:49 +0000901 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000902}
903
904template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000905_LIBCPP_INLINE_VISIBILITY
906_Tp __cxx_atomic_fetch_or(volatile __cxx_atomic_base_impl<_Tp>* __a,
907 _Tp __pattern, memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000908 return __atomic_fetch_or(&__a->__a_value, __pattern,
Davide Italiano011f80a2019-03-05 18:40:49 +0000909 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000910}
911
912template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000913_LIBCPP_INLINE_VISIBILITY
914_Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern,
915 memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000916 return __atomic_fetch_or(&__a->__a_value, __pattern,
Davide Italiano011f80a2019-03-05 18:40:49 +0000917 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000918}
919
920template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000921_LIBCPP_INLINE_VISIBILITY
922_Tp __cxx_atomic_fetch_xor(volatile __cxx_atomic_base_impl<_Tp>* __a,
923 _Tp __pattern, memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000924 return __atomic_fetch_xor(&__a->__a_value, __pattern,
Davide Italiano011f80a2019-03-05 18:40:49 +0000925 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000926}
927
928template <typename _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +0000929_LIBCPP_INLINE_VISIBILITY
930_Tp __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern,
931 memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000932 return __atomic_fetch_xor(&__a->__a_value, __pattern,
Davide Italiano011f80a2019-03-05 18:40:49 +0000933 __to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000934}
Davide Italiano011f80a2019-03-05 18:40:49 +0000935
936#define __cxx_atomic_is_lock_free(__s) __atomic_is_lock_free(__s, 0)
937
938#elif defined(_LIBCPP_HAS_C_ATOMIC_IMP)
939
940template <typename _Tp>
941struct __cxx_atomic_base_impl {
942
943 _LIBCPP_INLINE_VISIBILITY
944#ifndef _LIBCPP_CXX03_LANG
945 __cxx_atomic_base_impl() _NOEXCEPT = default;
946#else
947 __cxx_atomic_base_impl() _NOEXCEPT : __a_value() {}
948#endif // _LIBCPP_CXX03_LANG
949 _LIBCPP_CONSTEXPR explicit __cxx_atomic_base_impl(_Tp value) _NOEXCEPT
950 : __a_value(value) {}
Louis Dionnefaa17452019-09-04 12:44:19 +0000951 _LIBCPP_DISABLE_EXTENSION_WARNING _Atomic(_Tp) __a_value;
Davide Italiano011f80a2019-03-05 18:40:49 +0000952};
953
954#define __cxx_atomic_is_lock_free(__s) __c11_atomic_is_lock_free(__s)
955
956_LIBCPP_INLINE_VISIBILITY inline
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000957void __cxx_atomic_thread_fence(memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +0000958 __c11_atomic_thread_fence(static_cast<__memory_order_underlying_t>(__order));
959}
960
961_LIBCPP_INLINE_VISIBILITY inline
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000962void __cxx_atomic_signal_fence(memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +0000963 __c11_atomic_signal_fence(static_cast<__memory_order_underlying_t>(__order));
964}
965
966template<class _Tp>
967_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000968void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __val) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +0000969 __c11_atomic_init(&__a->__a_value, __val);
970}
971template<class _Tp>
972_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000973void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp> * __a, _Tp __val) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +0000974 __c11_atomic_init(&__a->__a_value, __val);
975}
976
977template<class _Tp>
978_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000979void __cxx_atomic_store(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __val, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +0000980 __c11_atomic_store(&__a->__a_value, __val, static_cast<__memory_order_underlying_t>(__order));
981}
982template<class _Tp>
983_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000984void __cxx_atomic_store(__cxx_atomic_base_impl<_Tp> * __a, _Tp __val, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +0000985 __c11_atomic_store(&__a->__a_value, __val, static_cast<__memory_order_underlying_t>(__order));
986}
987
988template<class _Tp>
989_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000990_Tp __cxx_atomic_load(__cxx_atomic_base_impl<_Tp> const volatile* __a, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +0000991 using __ptr_type = typename remove_const<decltype(__a->__a_value)>::type*;
992 return __c11_atomic_load(const_cast<__ptr_type>(&__a->__a_value), static_cast<__memory_order_underlying_t>(__order));
993}
994template<class _Tp>
995_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +0000996_Tp __cxx_atomic_load(__cxx_atomic_base_impl<_Tp> const* __a, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +0000997 using __ptr_type = typename remove_const<decltype(__a->__a_value)>::type*;
998 return __c11_atomic_load(const_cast<__ptr_type>(&__a->__a_value), static_cast<__memory_order_underlying_t>(__order));
999}
1000
1001template<class _Tp>
1002_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001003_Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __value, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +00001004 return __c11_atomic_exchange(&__a->__a_value, __value, static_cast<__memory_order_underlying_t>(__order));
1005}
1006template<class _Tp>
1007_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001008_Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp> * __a, _Tp __value, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +00001009 return __c11_atomic_exchange(&__a->__a_value, __value, static_cast<__memory_order_underlying_t>(__order));
1010}
1011
1012template<class _Tp>
1013_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001014bool __cxx_atomic_compare_exchange_strong(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +00001015 return __c11_atomic_compare_exchange_strong(&__a->__a_value, __expected, __value, static_cast<__memory_order_underlying_t>(__success), static_cast<__memory_order_underlying_t>(__failure));
1016}
1017template<class _Tp>
1018_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001019bool __cxx_atomic_compare_exchange_strong(__cxx_atomic_base_impl<_Tp> * __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +00001020 return __c11_atomic_compare_exchange_strong(&__a->__a_value, __expected, __value, static_cast<__memory_order_underlying_t>(__success), static_cast<__memory_order_underlying_t>(__failure));
1021}
1022
1023template<class _Tp>
1024_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001025bool __cxx_atomic_compare_exchange_weak(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +00001026 return __c11_atomic_compare_exchange_weak(&__a->__a_value, __expected, __value, static_cast<__memory_order_underlying_t>(__success), static_cast<__memory_order_underlying_t>(__failure));
1027}
1028template<class _Tp>
1029_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001030bool __cxx_atomic_compare_exchange_weak(__cxx_atomic_base_impl<_Tp> * __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +00001031 return __c11_atomic_compare_exchange_weak(&__a->__a_value, __expected, __value, static_cast<__memory_order_underlying_t>(__success), static_cast<__memory_order_underlying_t>(__failure));
1032}
1033
1034template<class _Tp>
1035_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001036_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 +00001037 return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
1038}
1039template<class _Tp>
1040_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001041_Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp> * __a, _Tp __delta, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +00001042 return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
1043}
1044
1045template<class _Tp>
1046_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001047_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 +00001048 return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
1049}
1050template<class _Tp>
1051_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001052_Tp* __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp*> * __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +00001053 return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
1054}
1055
1056template<class _Tp>
1057_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001058_Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __delta, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +00001059 return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
1060}
1061template<class _Tp>
1062_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001063_Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp> * __a, _Tp __delta, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +00001064 return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
1065}
1066template<class _Tp>
1067_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001068_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 +00001069 return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
1070}
1071template<class _Tp>
1072_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001073_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 +00001074 return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
1075}
1076
1077template<class _Tp>
1078_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001079_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 +00001080 return __c11_atomic_fetch_and(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
1081}
1082template<class _Tp>
1083_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001084_Tp __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +00001085 return __c11_atomic_fetch_and(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
1086}
1087
1088template<class _Tp>
1089_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001090_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 +00001091 return __c11_atomic_fetch_or(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
1092}
1093template<class _Tp>
1094_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001095_Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +00001096 return __c11_atomic_fetch_or(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
1097}
1098
1099template<class _Tp>
1100_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001101_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 +00001102 return __c11_atomic_fetch_xor(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
1103}
1104template<class _Tp>
1105_LIBCPP_INLINE_VISIBILITY
Eric Fiselier8fa9b6f2019-06-23 02:49:12 +00001106_Tp __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
Davide Italiano011f80a2019-03-05 18:40:49 +00001107 return __c11_atomic_fetch_xor(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
1108}
1109
1110#endif // _LIBCPP_HAS_GCC_ATOMIC_IMP, _LIBCPP_HAS_C_ATOMIC_IMP
Dan Albert7b65ace2014-08-09 23:51:51 +00001111
Howard Hinnantdca6e712010-09-28 17:13:38 +00001112template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001113_LIBCPP_INLINE_VISIBILITY
1114_Tp kill_dependency(_Tp __y) _NOEXCEPT
Howard Hinnantdca6e712010-09-28 17:13:38 +00001115{
1116 return __y;
1117}
Howard Hinnant71be7292010-09-27 21:17:38 +00001118
Eric Fiselierbed42df2017-04-20 23:22:46 +00001119#if defined(__CLANG_ATOMIC_BOOL_LOCK_FREE)
1120# define ATOMIC_BOOL_LOCK_FREE __CLANG_ATOMIC_BOOL_LOCK_FREE
1121# define ATOMIC_CHAR_LOCK_FREE __CLANG_ATOMIC_CHAR_LOCK_FREE
1122# define ATOMIC_CHAR16_T_LOCK_FREE __CLANG_ATOMIC_CHAR16_T_LOCK_FREE
1123# define ATOMIC_CHAR32_T_LOCK_FREE __CLANG_ATOMIC_CHAR32_T_LOCK_FREE
1124# define ATOMIC_WCHAR_T_LOCK_FREE __CLANG_ATOMIC_WCHAR_T_LOCK_FREE
1125# define ATOMIC_SHORT_LOCK_FREE __CLANG_ATOMIC_SHORT_LOCK_FREE
1126# define ATOMIC_INT_LOCK_FREE __CLANG_ATOMIC_INT_LOCK_FREE
1127# define ATOMIC_LONG_LOCK_FREE __CLANG_ATOMIC_LONG_LOCK_FREE
1128# define ATOMIC_LLONG_LOCK_FREE __CLANG_ATOMIC_LLONG_LOCK_FREE
1129# define ATOMIC_POINTER_LOCK_FREE __CLANG_ATOMIC_POINTER_LOCK_FREE
Davide Italiano011f80a2019-03-05 18:40:49 +00001130#elif defined(__GCC_ATOMIC_BOOL_LOCK_FREE)
Eric Fiselierbed42df2017-04-20 23:22:46 +00001131# define ATOMIC_BOOL_LOCK_FREE __GCC_ATOMIC_BOOL_LOCK_FREE
1132# define ATOMIC_CHAR_LOCK_FREE __GCC_ATOMIC_CHAR_LOCK_FREE
1133# define ATOMIC_CHAR16_T_LOCK_FREE __GCC_ATOMIC_CHAR16_T_LOCK_FREE
1134# define ATOMIC_CHAR32_T_LOCK_FREE __GCC_ATOMIC_CHAR32_T_LOCK_FREE
1135# define ATOMIC_WCHAR_T_LOCK_FREE __GCC_ATOMIC_WCHAR_T_LOCK_FREE
1136# define ATOMIC_SHORT_LOCK_FREE __GCC_ATOMIC_SHORT_LOCK_FREE
1137# define ATOMIC_INT_LOCK_FREE __GCC_ATOMIC_INT_LOCK_FREE
1138# define ATOMIC_LONG_LOCK_FREE __GCC_ATOMIC_LONG_LOCK_FREE
1139# define ATOMIC_LLONG_LOCK_FREE __GCC_ATOMIC_LLONG_LOCK_FREE
1140# define ATOMIC_POINTER_LOCK_FREE __GCC_ATOMIC_POINTER_LOCK_FREE
1141#endif
JF Bastienfdb42c22016-03-25 15:48:21 +00001142
Davide Italiano011f80a2019-03-05 18:40:49 +00001143#ifdef _LIBCPP_ATOMIC_ONLY_USE_BUILTINS
1144
1145template<typename _Tp>
1146struct __cxx_atomic_lock_impl {
1147
1148 _LIBCPP_INLINE_VISIBILITY
1149 __cxx_atomic_lock_impl() _NOEXCEPT
1150 : __a_value(), __a_lock(0) {}
1151 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR explicit
1152 __cxx_atomic_lock_impl(_Tp value) _NOEXCEPT
1153 : __a_value(value), __a_lock(0) {}
1154
1155 _Tp __a_value;
1156 mutable __cxx_atomic_base_impl<_LIBCPP_ATOMIC_FLAG_TYPE> __a_lock;
1157
1158 _LIBCPP_INLINE_VISIBILITY void __lock() const volatile {
1159 while(1 == __cxx_atomic_exchange(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(true), memory_order_acquire))
1160 /*spin*/;
1161 }
1162 _LIBCPP_INLINE_VISIBILITY void __lock() const {
1163 while(1 == __cxx_atomic_exchange(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(true), memory_order_acquire))
1164 /*spin*/;
1165 }
1166 _LIBCPP_INLINE_VISIBILITY void __unlock() const volatile {
1167 __cxx_atomic_store(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(false), memory_order_release);
1168 }
1169 _LIBCPP_INLINE_VISIBILITY void __unlock() const {
1170 __cxx_atomic_store(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(false), memory_order_release);
1171 }
1172 _LIBCPP_INLINE_VISIBILITY _Tp __read() const volatile {
1173 __lock();
1174 _Tp __old;
1175 __cxx_atomic_assign_volatile(__old, __a_value);
1176 __unlock();
1177 return __old;
1178 }
1179 _LIBCPP_INLINE_VISIBILITY _Tp __read() const {
1180 __lock();
1181 _Tp __old = __a_value;
1182 __unlock();
1183 return __old;
1184 }
1185};
1186
1187template <typename _Tp>
1188_LIBCPP_INLINE_VISIBILITY
1189void __cxx_atomic_init(volatile __cxx_atomic_lock_impl<_Tp>* __a, _Tp __val) {
1190 __cxx_atomic_assign_volatile(__a->__a_value, __val);
1191}
1192template <typename _Tp>
1193_LIBCPP_INLINE_VISIBILITY
1194void __cxx_atomic_init(__cxx_atomic_lock_impl<_Tp>* __a, _Tp __val) {
1195 __a->__a_value = __val;
1196}
1197
1198template <typename _Tp>
1199_LIBCPP_INLINE_VISIBILITY
1200void __cxx_atomic_store(volatile __cxx_atomic_lock_impl<_Tp>* __a, _Tp __val, memory_order) {
1201 __a->__lock();
1202 __cxx_atomic_assign_volatile(__a->__a_value, __val);
1203 __a->__unlock();
1204}
1205template <typename _Tp>
1206_LIBCPP_INLINE_VISIBILITY
1207void __cxx_atomic_store(__cxx_atomic_lock_impl<_Tp>* __a, _Tp __val, memory_order) {
1208 __a->__lock();
1209 __a->__a_value = __val;
1210 __a->__unlock();
1211}
1212
1213template <typename _Tp>
1214_LIBCPP_INLINE_VISIBILITY
1215_Tp __cxx_atomic_load(const volatile __cxx_atomic_lock_impl<_Tp>* __a, memory_order) {
1216 return __a->__read();
1217}
1218template <typename _Tp>
1219_LIBCPP_INLINE_VISIBILITY
1220_Tp __cxx_atomic_load(const __cxx_atomic_lock_impl<_Tp>* __a, memory_order) {
1221 return __a->__read();
1222}
1223
1224template <typename _Tp>
1225_LIBCPP_INLINE_VISIBILITY
1226_Tp __cxx_atomic_exchange(volatile __cxx_atomic_lock_impl<_Tp>* __a, _Tp __value, memory_order) {
1227 __a->__lock();
1228 _Tp __old;
1229 __cxx_atomic_assign_volatile(__old, __a->__a_value);
1230 __cxx_atomic_assign_volatile(__a->__a_value, __value);
1231 __a->__unlock();
1232 return __old;
1233}
1234template <typename _Tp>
1235_LIBCPP_INLINE_VISIBILITY
1236_Tp __cxx_atomic_exchange(__cxx_atomic_lock_impl<_Tp>* __a, _Tp __value, memory_order) {
1237 __a->__lock();
1238 _Tp __old = __a->__a_value;
1239 __a->__a_value = __value;
1240 __a->__unlock();
1241 return __old;
1242}
1243
1244template <typename _Tp>
1245_LIBCPP_INLINE_VISIBILITY
1246bool __cxx_atomic_compare_exchange_strong(volatile __cxx_atomic_lock_impl<_Tp>* __a,
1247 _Tp* __expected, _Tp __value, memory_order, memory_order) {
1248 __a->__lock();
Olivier Giroux161e6e82020-02-18 09:58:34 -05001249 _Tp __temp;
1250 __cxx_atomic_assign_volatile(__temp, __a->__a_value);
1251 bool __ret = __temp == *__expected;
Davide Italiano011f80a2019-03-05 18:40:49 +00001252 if(__ret)
1253 __cxx_atomic_assign_volatile(__a->__a_value, __value);
1254 else
1255 __cxx_atomic_assign_volatile(*__expected, __a->__a_value);
1256 __a->__unlock();
1257 return __ret;
1258}
1259template <typename _Tp>
1260_LIBCPP_INLINE_VISIBILITY
1261bool __cxx_atomic_compare_exchange_strong(__cxx_atomic_lock_impl<_Tp>* __a,
1262 _Tp* __expected, _Tp __value, memory_order, memory_order) {
1263 __a->__lock();
1264 bool __ret = __a->__a_value == *__expected;
1265 if(__ret)
1266 __a->__a_value = __value;
1267 else
1268 *__expected = __a->__a_value;
1269 __a->__unlock();
1270 return __ret;
1271}
1272
1273template <typename _Tp>
1274_LIBCPP_INLINE_VISIBILITY
1275bool __cxx_atomic_compare_exchange_weak(volatile __cxx_atomic_lock_impl<_Tp>* __a,
1276 _Tp* __expected, _Tp __value, memory_order, memory_order) {
1277 __a->__lock();
Olivier Giroux161e6e82020-02-18 09:58:34 -05001278 _Tp __temp;
1279 __cxx_atomic_assign_volatile(__temp, __a->__a_value);
1280 bool __ret = __temp == *__expected;
Davide Italiano011f80a2019-03-05 18:40:49 +00001281 if(__ret)
1282 __cxx_atomic_assign_volatile(__a->__a_value, __value);
1283 else
1284 __cxx_atomic_assign_volatile(*__expected, __a->__a_value);
1285 __a->__unlock();
1286 return __ret;
1287}
1288template <typename _Tp>
1289_LIBCPP_INLINE_VISIBILITY
1290bool __cxx_atomic_compare_exchange_weak(__cxx_atomic_lock_impl<_Tp>* __a,
1291 _Tp* __expected, _Tp __value, memory_order, memory_order) {
1292 __a->__lock();
1293 bool __ret = __a->__a_value == *__expected;
1294 if(__ret)
1295 __a->__a_value = __value;
1296 else
1297 *__expected = __a->__a_value;
1298 __a->__unlock();
1299 return __ret;
1300}
1301
1302template <typename _Tp, typename _Td>
1303_LIBCPP_INLINE_VISIBILITY
1304_Tp __cxx_atomic_fetch_add(volatile __cxx_atomic_lock_impl<_Tp>* __a,
1305 _Td __delta, memory_order) {
1306 __a->__lock();
1307 _Tp __old;
1308 __cxx_atomic_assign_volatile(__old, __a->__a_value);
1309 __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old + __delta));
1310 __a->__unlock();
1311 return __old;
1312}
1313template <typename _Tp, typename _Td>
1314_LIBCPP_INLINE_VISIBILITY
1315_Tp __cxx_atomic_fetch_add(__cxx_atomic_lock_impl<_Tp>* __a,
1316 _Td __delta, memory_order) {
1317 __a->__lock();
1318 _Tp __old = __a->__a_value;
1319 __a->__a_value += __delta;
1320 __a->__unlock();
1321 return __old;
1322}
1323
1324template <typename _Tp, typename _Td>
1325_LIBCPP_INLINE_VISIBILITY
1326_Tp* __cxx_atomic_fetch_add(volatile __cxx_atomic_lock_impl<_Tp*>* __a,
1327 ptrdiff_t __delta, memory_order) {
1328 __a->__lock();
1329 _Tp* __old;
1330 __cxx_atomic_assign_volatile(__old, __a->__a_value);
1331 __cxx_atomic_assign_volatile(__a->__a_value, __old + __delta);
1332 __a->__unlock();
1333 return __old;
1334}
1335template <typename _Tp, typename _Td>
1336_LIBCPP_INLINE_VISIBILITY
1337_Tp* __cxx_atomic_fetch_add(__cxx_atomic_lock_impl<_Tp*>* __a,
1338 ptrdiff_t __delta, memory_order) {
1339 __a->__lock();
1340 _Tp* __old = __a->__a_value;
1341 __a->__a_value += __delta;
1342 __a->__unlock();
1343 return __old;
1344}
1345
1346template <typename _Tp, typename _Td>
1347_LIBCPP_INLINE_VISIBILITY
1348_Tp __cxx_atomic_fetch_sub(volatile __cxx_atomic_lock_impl<_Tp>* __a,
1349 _Td __delta, memory_order) {
1350 __a->__lock();
1351 _Tp __old;
1352 __cxx_atomic_assign_volatile(__old, __a->__a_value);
1353 __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old - __delta));
1354 __a->__unlock();
1355 return __old;
1356}
1357template <typename _Tp, typename _Td>
1358_LIBCPP_INLINE_VISIBILITY
1359_Tp __cxx_atomic_fetch_sub(__cxx_atomic_lock_impl<_Tp>* __a,
1360 _Td __delta, memory_order) {
1361 __a->__lock();
1362 _Tp __old = __a->__a_value;
1363 __a->__a_value -= __delta;
1364 __a->__unlock();
1365 return __old;
1366}
1367
1368template <typename _Tp>
1369_LIBCPP_INLINE_VISIBILITY
1370_Tp __cxx_atomic_fetch_and(volatile __cxx_atomic_lock_impl<_Tp>* __a,
1371 _Tp __pattern, memory_order) {
1372 __a->__lock();
1373 _Tp __old;
1374 __cxx_atomic_assign_volatile(__old, __a->__a_value);
1375 __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old & __pattern));
1376 __a->__unlock();
1377 return __old;
1378}
1379template <typename _Tp>
1380_LIBCPP_INLINE_VISIBILITY
1381_Tp __cxx_atomic_fetch_and(__cxx_atomic_lock_impl<_Tp>* __a,
1382 _Tp __pattern, memory_order) {
1383 __a->__lock();
1384 _Tp __old = __a->__a_value;
1385 __a->__a_value &= __pattern;
1386 __a->__unlock();
1387 return __old;
1388}
1389
1390template <typename _Tp>
1391_LIBCPP_INLINE_VISIBILITY
1392_Tp __cxx_atomic_fetch_or(volatile __cxx_atomic_lock_impl<_Tp>* __a,
1393 _Tp __pattern, memory_order) {
1394 __a->__lock();
1395 _Tp __old;
1396 __cxx_atomic_assign_volatile(__old, __a->__a_value);
1397 __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old | __pattern));
1398 __a->__unlock();
1399 return __old;
1400}
1401template <typename _Tp>
1402_LIBCPP_INLINE_VISIBILITY
1403_Tp __cxx_atomic_fetch_or(__cxx_atomic_lock_impl<_Tp>* __a,
1404 _Tp __pattern, memory_order) {
1405 __a->__lock();
1406 _Tp __old = __a->__a_value;
1407 __a->__a_value |= __pattern;
1408 __a->__unlock();
1409 return __old;
1410}
1411
1412template <typename _Tp>
1413_LIBCPP_INLINE_VISIBILITY
1414_Tp __cxx_atomic_fetch_xor(volatile __cxx_atomic_lock_impl<_Tp>* __a,
1415 _Tp __pattern, memory_order) {
1416 __a->__lock();
1417 _Tp __old;
1418 __cxx_atomic_assign_volatile(__old, __a->__a_value);
1419 __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old ^ __pattern));
1420 __a->__unlock();
1421 return __old;
1422}
1423template <typename _Tp>
1424_LIBCPP_INLINE_VISIBILITY
1425_Tp __cxx_atomic_fetch_xor(__cxx_atomic_lock_impl<_Tp>* __a,
1426 _Tp __pattern, memory_order) {
1427 __a->__lock();
1428 _Tp __old = __a->__a_value;
1429 __a->__a_value ^= __pattern;
1430 __a->__unlock();
1431 return __old;
1432}
1433
1434#ifdef __cpp_lib_atomic_is_always_lock_free
1435
1436template<typename _Tp> struct __cxx_is_always_lock_free {
1437 enum { __value = __atomic_always_lock_free(sizeof(_Tp), 0) }; };
1438
1439#else
1440
1441template<typename _Tp> struct __cxx_is_always_lock_free { enum { __value = false }; };
1442// Implementations must match the C ATOMIC_*_LOCK_FREE macro values.
1443template<> struct __cxx_is_always_lock_free<bool> { enum { __value = 2 == ATOMIC_BOOL_LOCK_FREE }; };
1444template<> struct __cxx_is_always_lock_free<char> { enum { __value = 2 == ATOMIC_CHAR_LOCK_FREE }; };
1445template<> struct __cxx_is_always_lock_free<signed char> { enum { __value = 2 == ATOMIC_CHAR_LOCK_FREE }; };
1446template<> struct __cxx_is_always_lock_free<unsigned char> { enum { __value = 2 == ATOMIC_CHAR_LOCK_FREE }; };
1447template<> struct __cxx_is_always_lock_free<char16_t> { enum { __value = 2 == ATOMIC_CHAR16_T_LOCK_FREE }; };
1448template<> struct __cxx_is_always_lock_free<char32_t> { enum { __value = 2 == ATOMIC_CHAR32_T_LOCK_FREE }; };
1449template<> struct __cxx_is_always_lock_free<wchar_t> { enum { __value = 2 == ATOMIC_WCHAR_T_LOCK_FREE }; };
1450template<> struct __cxx_is_always_lock_free<short> { enum { __value = 2 == ATOMIC_SHORT_LOCK_FREE }; };
1451template<> struct __cxx_is_always_lock_free<unsigned short> { enum { __value = 2 == ATOMIC_SHORT_LOCK_FREE }; };
1452template<> struct __cxx_is_always_lock_free<int> { enum { __value = 2 == ATOMIC_INT_LOCK_FREE }; };
1453template<> struct __cxx_is_always_lock_free<unsigned int> { enum { __value = 2 == ATOMIC_INT_LOCK_FREE }; };
1454template<> struct __cxx_is_always_lock_free<long> { enum { __value = 2 == ATOMIC_LONG_LOCK_FREE }; };
1455template<> struct __cxx_is_always_lock_free<unsigned long> { enum { __value = 2 == ATOMIC_LONG_LOCK_FREE }; };
1456template<> struct __cxx_is_always_lock_free<long long> { enum { __value = 2 == ATOMIC_LLONG_LOCK_FREE }; };
1457template<> struct __cxx_is_always_lock_free<unsigned long long> { enum { __value = 2 == ATOMIC_LLONG_LOCK_FREE }; };
1458template<typename _Tp> struct __cxx_is_always_lock_free<_Tp*> { enum { __value = 2 == ATOMIC_POINTER_LOCK_FREE }; };
1459template<> struct __cxx_is_always_lock_free<std::nullptr_t> { enum { __value = 2 == ATOMIC_POINTER_LOCK_FREE }; };
1460
1461#endif //__cpp_lib_atomic_is_always_lock_free
1462
1463template <typename _Tp,
1464 typename _Base = typename conditional<__cxx_is_always_lock_free<_Tp>::__value,
1465 __cxx_atomic_base_impl<_Tp>,
1466 __cxx_atomic_lock_impl<_Tp> >::type>
1467#else
1468template <typename _Tp,
1469 typename _Base = __cxx_atomic_base_impl<_Tp> >
1470#endif //_LIBCPP_ATOMIC_ONLY_USE_BUILTINS
1471struct __cxx_atomic_impl : public _Base {
1472
1473#if _GNUC_VER >= 501
1474 static_assert(is_trivially_copyable<_Tp>::value,
1475 "std::atomic<Tp> requires that 'Tp' be a trivially copyable type");
1476#endif
1477
1478 _LIBCPP_INLINE_VISIBILITY __cxx_atomic_impl() _NOEXCEPT _LIBCPP_DEFAULT
1479 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR explicit __cxx_atomic_impl(_Tp value) _NOEXCEPT
1480 : _Base(value) {}
1481};
1482
Olivier Giroux161e6e82020-02-18 09:58:34 -05001483#ifdef __linux__
1484 using __cxx_contention_t = int32_t;
1485#else
1486 using __cxx_contention_t = int64_t;
1487#endif //__linux__
1488
1489#if _LIBCPP_STD_VER >= 11
1490
1491using __cxx_atomic_contention_t = __cxx_atomic_impl<__cxx_contention_t>;
1492
1493#ifndef _LIBCPP_HAS_NO_PLATFORM_WAIT
1494
Louis Dionne48a828b2020-02-24 10:08:41 -05001495_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_one(void const volatile*);
1496_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_all(void const volatile*);
1497_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t __libcpp_atomic_monitor(void const volatile*);
1498_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __libcpp_atomic_wait(void const volatile*, __cxx_contention_t);
Olivier Giroux161e6e82020-02-18 09:58:34 -05001499
Louis Dionne48a828b2020-02-24 10:08:41 -05001500_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_one(__cxx_atomic_contention_t const volatile*);
1501_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_all(__cxx_atomic_contention_t const volatile*);
1502_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t __libcpp_atomic_monitor(__cxx_atomic_contention_t const volatile*);
1503_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 -05001504
1505template <class _Atp, class _Fn>
Louis Dionne08cd5cb2020-02-24 11:39:48 -05001506struct __libcpp_atomic_wait_backoff_impl {
1507 _Atp* __a;
1508 _Fn __test_fn;
Louis Dionne3dde4ab2020-02-24 10:09:29 -05001509 _LIBCPP_AVAILABILITY_SYNC
Louis Dionne08cd5cb2020-02-24 11:39:48 -05001510 _LIBCPP_INLINE_VISIBILITY bool operator()(chrono::nanoseconds __elapsed) const
1511 {
Olivier Giroux161e6e82020-02-18 09:58:34 -05001512 if(__elapsed > chrono::microseconds(64))
1513 {
1514 auto const __monitor = __libcpp_atomic_monitor(__a);
1515 if(__test_fn())
1516 return true;
1517 __libcpp_atomic_wait(__a, __monitor);
1518 }
1519 else if(__elapsed > chrono::microseconds(4))
1520 __libcpp_thread_yield();
1521 else
1522 ; // poll
1523 return false;
Louis Dionne08cd5cb2020-02-24 11:39:48 -05001524 }
1525};
1526
1527template <class _Atp, class _Fn>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05001528_LIBCPP_AVAILABILITY_SYNC
Louis Dionne08cd5cb2020-02-24 11:39:48 -05001529_LIBCPP_INLINE_VISIBILITY bool __cxx_atomic_wait(_Atp* __a, _Fn && __test_fn)
1530{
1531 __libcpp_atomic_wait_backoff_impl<_Atp, typename decay<_Fn>::type> __backoff_fn = {__a, __test_fn};
1532 return __libcpp_thread_poll_with_backoff(__test_fn, __backoff_fn);
Olivier Giroux161e6e82020-02-18 09:58:34 -05001533}
1534
1535#else // _LIBCPP_HAS_NO_PLATFORM_WAIT
1536
1537template <class _Tp>
1538_LIBCPP_INLINE_VISIBILITY void __cxx_atomic_notify_all(__cxx_atomic_impl<_Tp> const volatile*) { }
1539template <class _Tp>
1540_LIBCPP_INLINE_VISIBILITY void __cxx_atomic_notify_one(__cxx_atomic_impl<_Tp> const volatile*) { }
1541template <class _Atp, class _Fn>
1542_LIBCPP_INLINE_VISIBILITY bool __cxx_atomic_wait(_Atp*, _Fn && __test_fn)
1543{
1544 return __libcpp_thread_poll_with_backoff(__test_fn, __libcpp_timed_backoff_policy());
1545}
1546
1547#endif // _LIBCPP_HAS_NO_PLATFORM_WAIT
1548
1549template <class _Atp, class _Tp>
Louis Dionne08cd5cb2020-02-24 11:39:48 -05001550struct __cxx_atomic_wait_test_fn_impl {
1551 _Atp* __a;
1552 _Tp __val;
1553 memory_order __order;
1554 _LIBCPP_INLINE_VISIBILITY bool operator()() const
1555 {
1556 return !__cxx_nonatomic_compare_equal(__cxx_atomic_load(__a, __order), __val);
1557 }
1558};
1559
1560template <class _Atp, class _Tp>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05001561_LIBCPP_AVAILABILITY_SYNC
Olivier Giroux161e6e82020-02-18 09:58:34 -05001562_LIBCPP_INLINE_VISIBILITY bool __cxx_atomic_wait(_Atp* __a, _Tp const __val, memory_order __order)
1563{
Louis Dionne08cd5cb2020-02-24 11:39:48 -05001564 __cxx_atomic_wait_test_fn_impl<_Atp, _Tp> __test_fn = {__a, __val, __order};
Olivier Giroux161e6e82020-02-18 09:58:34 -05001565 return __cxx_atomic_wait(__a, __test_fn);
1566}
1567
1568#endif //_LIBCPP_STD_VER >= 11
1569
Howard Hinnant138f5922010-12-07 20:46:14 +00001570// general atomic<T>
1571
1572template <class _Tp, bool = is_integral<_Tp>::value && !is_same<_Tp, bool>::value>
1573struct __atomic_base // false
1574{
Davide Italiano011f80a2019-03-05 18:40:49 +00001575 mutable __cxx_atomic_impl<_Tp> __a_;
Howard Hinnant138f5922010-12-07 20:46:14 +00001576
JF Bastienfdb42c22016-03-25 15:48:21 +00001577#if defined(__cpp_lib_atomic_is_always_lock_free)
1578 static _LIBCPP_CONSTEXPR bool is_always_lock_free = __atomic_always_lock_free(sizeof(__a_), 0);
1579#endif
1580
Howard Hinnant138f5922010-12-07 20:46:14 +00001581 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001582 bool is_lock_free() const volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001583 {return __cxx_atomic_is_lock_free(sizeof(_Tp));}
Howard Hinnant138f5922010-12-07 20:46:14 +00001584 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001585 bool is_lock_free() const _NOEXCEPT
Eric Fiselier3fd22c22015-06-13 00:23:07 +00001586 {return static_cast<__atomic_base const volatile*>(this)->is_lock_free();}
Howard Hinnant138f5922010-12-07 20:46:14 +00001587 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001588 void store(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001589 _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
Davide Italiano011f80a2019-03-05 18:40:49 +00001590 {__cxx_atomic_store(&__a_, __d, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001591 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001592 void store(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001593 _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
Davide Italiano011f80a2019-03-05 18:40:49 +00001594 {__cxx_atomic_store(&__a_, __d, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001595 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001596 _Tp load(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001597 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
Davide Italiano011f80a2019-03-05 18:40:49 +00001598 {return __cxx_atomic_load(&__a_, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001599 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001600 _Tp load(memory_order __m = memory_order_seq_cst) const _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001601 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
Davide Italiano011f80a2019-03-05 18:40:49 +00001602 {return __cxx_atomic_load(&__a_, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001603 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001604 operator _Tp() const volatile _NOEXCEPT {return load();}
Howard Hinnant138f5922010-12-07 20:46:14 +00001605 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001606 operator _Tp() const _NOEXCEPT {return load();}
Howard Hinnant138f5922010-12-07 20:46:14 +00001607 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001608 _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001609 {return __cxx_atomic_exchange(&__a_, __d, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001610 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001611 _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001612 {return __cxx_atomic_exchange(&__a_, __d, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001613 _LIBCPP_INLINE_VISIBILITY
1614 bool compare_exchange_weak(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001615 memory_order __s, memory_order __f) volatile _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001616 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Davide Italiano011f80a2019-03-05 18:40:49 +00001617 {return __cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001618 _LIBCPP_INLINE_VISIBILITY
1619 bool compare_exchange_weak(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001620 memory_order __s, memory_order __f) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001621 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Davide Italiano011f80a2019-03-05 18:40:49 +00001622 {return __cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001623 _LIBCPP_INLINE_VISIBILITY
1624 bool compare_exchange_strong(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001625 memory_order __s, memory_order __f) volatile _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001626 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Davide Italiano011f80a2019-03-05 18:40:49 +00001627 {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001628 _LIBCPP_INLINE_VISIBILITY
1629 bool compare_exchange_strong(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001630 memory_order __s, memory_order __f) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001631 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Davide Italiano011f80a2019-03-05 18:40:49 +00001632 {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001633 _LIBCPP_INLINE_VISIBILITY
1634 bool compare_exchange_weak(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001635 memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001636 {return __cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001637 _LIBCPP_INLINE_VISIBILITY
1638 bool compare_exchange_weak(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001639 memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001640 {return __cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001641 _LIBCPP_INLINE_VISIBILITY
1642 bool compare_exchange_strong(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001643 memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001644 {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001645 _LIBCPP_INLINE_VISIBILITY
1646 bool compare_exchange_strong(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001647 memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001648 {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001649
Louis Dionne3dde4ab2020-02-24 10:09:29 -05001650 _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 -05001651 {__cxx_atomic_wait(&__a_, __v, __m);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05001652 _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 -05001653 {__cxx_atomic_wait(&__a_, __v, __m);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05001654 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_one() volatile _NOEXCEPT
Olivier Giroux161e6e82020-02-18 09:58:34 -05001655 {__cxx_atomic_notify_one(&__a_);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05001656 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_one() _NOEXCEPT
Olivier Giroux161e6e82020-02-18 09:58:34 -05001657 {__cxx_atomic_notify_one(&__a_);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05001658 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_all() volatile _NOEXCEPT
Olivier Giroux161e6e82020-02-18 09:58:34 -05001659 {__cxx_atomic_notify_all(&__a_);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05001660 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_all() _NOEXCEPT
Olivier Giroux161e6e82020-02-18 09:58:34 -05001661 {__cxx_atomic_notify_all(&__a_);}
1662
Howard Hinnant138f5922010-12-07 20:46:14 +00001663 _LIBCPP_INLINE_VISIBILITY
Davide Italiano011f80a2019-03-05 18:40:49 +00001664 __atomic_base() _NOEXCEPT _LIBCPP_DEFAULT
Howard Hinnant3d284222013-05-02 20:18:43 +00001665
Davide Italiano011f80a2019-03-05 18:40:49 +00001666 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
1667 __atomic_base(_Tp __d) _NOEXCEPT : __a_(__d) {}
1668
Eric Fiselier2d8515f2017-01-06 20:58:25 +00001669#ifndef _LIBCPP_CXX03_LANG
Howard Hinnant138f5922010-12-07 20:46:14 +00001670 __atomic_base(const __atomic_base&) = delete;
1671 __atomic_base& operator=(const __atomic_base&) = delete;
1672 __atomic_base& operator=(const __atomic_base&) volatile = delete;
Eric Fiselier2d8515f2017-01-06 20:58:25 +00001673#else
Howard Hinnant6ac60f82010-12-08 17:20:28 +00001674private:
Olivier Giroux161e6e82020-02-18 09:58:34 -05001675 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant6ac60f82010-12-08 17:20:28 +00001676 __atomic_base(const __atomic_base&);
Olivier Giroux161e6e82020-02-18 09:58:34 -05001677 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant6ac60f82010-12-08 17:20:28 +00001678 __atomic_base& operator=(const __atomic_base&);
Olivier Giroux161e6e82020-02-18 09:58:34 -05001679 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant6ac60f82010-12-08 17:20:28 +00001680 __atomic_base& operator=(const __atomic_base&) volatile;
Eric Fiselier2d8515f2017-01-06 20:58:25 +00001681#endif
Howard Hinnant138f5922010-12-07 20:46:14 +00001682};
1683
JF Bastienfdb42c22016-03-25 15:48:21 +00001684#if defined(__cpp_lib_atomic_is_always_lock_free)
1685template <class _Tp, bool __b>
1686_LIBCPP_CONSTEXPR bool __atomic_base<_Tp, __b>::is_always_lock_free;
1687#endif
1688
Howard Hinnant138f5922010-12-07 20:46:14 +00001689// atomic<Integral>
1690
1691template <class _Tp>
1692struct __atomic_base<_Tp, true>
1693 : public __atomic_base<_Tp, false>
1694{
1695 typedef __atomic_base<_Tp, false> __base;
1696 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3d284222013-05-02 20:18:43 +00001697 __atomic_base() _NOEXCEPT _LIBCPP_DEFAULT
Howard Hinnant138f5922010-12-07 20:46:14 +00001698 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001699 _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __base(__d) {}
Howard Hinnant138f5922010-12-07 20:46:14 +00001700
1701 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001702 _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001703 {return __cxx_atomic_fetch_add(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001704 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001705 _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001706 {return __cxx_atomic_fetch_add(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001707 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001708 _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001709 {return __cxx_atomic_fetch_sub(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001710 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001711 _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001712 {return __cxx_atomic_fetch_sub(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001713 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001714 _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001715 {return __cxx_atomic_fetch_and(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001716 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001717 _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001718 {return __cxx_atomic_fetch_and(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001719 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001720 _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001721 {return __cxx_atomic_fetch_or(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001722 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001723 _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001724 {return __cxx_atomic_fetch_or(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001725 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001726 _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001727 {return __cxx_atomic_fetch_xor(&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_xor(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001730 {return __cxx_atomic_fetch_xor(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001731
1732 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001733 _Tp operator++(int) volatile _NOEXCEPT {return fetch_add(_Tp(1));}
Howard Hinnant138f5922010-12-07 20:46:14 +00001734 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001735 _Tp operator++(int) _NOEXCEPT {return fetch_add(_Tp(1));}
Howard Hinnant138f5922010-12-07 20:46:14 +00001736 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001737 _Tp operator--(int) volatile _NOEXCEPT {return fetch_sub(_Tp(1));}
Howard Hinnant138f5922010-12-07 20:46:14 +00001738 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001739 _Tp operator--(int) _NOEXCEPT {return fetch_sub(_Tp(1));}
Howard Hinnant138f5922010-12-07 20:46:14 +00001740 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001741 _Tp operator++() volatile _NOEXCEPT {return fetch_add(_Tp(1)) + _Tp(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001742 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001743 _Tp operator++() _NOEXCEPT {return fetch_add(_Tp(1)) + _Tp(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001744 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001745 _Tp operator--() volatile _NOEXCEPT {return fetch_sub(_Tp(1)) - _Tp(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001746 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001747 _Tp operator--() _NOEXCEPT {return fetch_sub(_Tp(1)) - _Tp(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001748 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001749 _Tp operator+=(_Tp __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001750 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001751 _Tp operator+=(_Tp __op) _NOEXCEPT {return fetch_add(__op) + __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001752 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001753 _Tp operator-=(_Tp __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001754 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001755 _Tp operator-=(_Tp __op) _NOEXCEPT {return fetch_sub(__op) - __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001756 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001757 _Tp operator&=(_Tp __op) volatile _NOEXCEPT {return fetch_and(__op) & __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001758 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001759 _Tp operator&=(_Tp __op) _NOEXCEPT {return fetch_and(__op) & __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001760 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001761 _Tp operator|=(_Tp __op) volatile _NOEXCEPT {return fetch_or(__op) | __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001762 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001763 _Tp operator|=(_Tp __op) _NOEXCEPT {return fetch_or(__op) | __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001764 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001765 _Tp operator^=(_Tp __op) volatile _NOEXCEPT {return fetch_xor(__op) ^ __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001766 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001767 _Tp operator^=(_Tp __op) _NOEXCEPT {return fetch_xor(__op) ^ __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001768};
1769
1770// atomic<T>
1771
1772template <class _Tp>
1773struct atomic
1774 : public __atomic_base<_Tp>
1775{
1776 typedef __atomic_base<_Tp> __base;
Olivier Giroux161e6e82020-02-18 09:58:34 -05001777 typedef _Tp value_type;
Howard Hinnant138f5922010-12-07 20:46:14 +00001778 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3d284222013-05-02 20:18:43 +00001779 atomic() _NOEXCEPT _LIBCPP_DEFAULT
Howard Hinnant138f5922010-12-07 20:46:14 +00001780 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001781 _LIBCPP_CONSTEXPR atomic(_Tp __d) _NOEXCEPT : __base(__d) {}
Howard Hinnant96e4cd62010-12-07 23:24:41 +00001782
1783 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001784 _Tp operator=(_Tp __d) volatile _NOEXCEPT
Howard Hinnant96e4cd62010-12-07 23:24:41 +00001785 {__base::store(__d); return __d;}
1786 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001787 _Tp operator=(_Tp __d) _NOEXCEPT
Howard Hinnant96e4cd62010-12-07 23:24:41 +00001788 {__base::store(__d); return __d;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001789};
1790
1791// atomic<T*>
1792
1793template <class _Tp>
1794struct atomic<_Tp*>
1795 : public __atomic_base<_Tp*>
1796{
Howard Hinnant96e4cd62010-12-07 23:24:41 +00001797 typedef __atomic_base<_Tp*> __base;
Olivier Giroux161e6e82020-02-18 09:58:34 -05001798 typedef _Tp* value_type;
Howard Hinnant138f5922010-12-07 20:46:14 +00001799 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3d284222013-05-02 20:18:43 +00001800 atomic() _NOEXCEPT _LIBCPP_DEFAULT
Howard Hinnant138f5922010-12-07 20:46:14 +00001801 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001802 _LIBCPP_CONSTEXPR atomic(_Tp* __d) _NOEXCEPT : __base(__d) {}
Howard Hinnant138f5922010-12-07 20:46:14 +00001803
1804 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001805 _Tp* operator=(_Tp* __d) volatile _NOEXCEPT
Howard Hinnant96e4cd62010-12-07 23:24:41 +00001806 {__base::store(__d); return __d;}
1807 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001808 _Tp* operator=(_Tp* __d) _NOEXCEPT
Howard Hinnant96e4cd62010-12-07 23:24:41 +00001809 {__base::store(__d); return __d;}
1810
1811 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00001812 _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst)
Howard Hinnanteee2c142012-04-11 20:14:21 +00001813 volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001814 {return __cxx_atomic_fetch_add(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001815 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001816 _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001817 {return __cxx_atomic_fetch_add(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001818 _LIBCPP_INLINE_VISIBILITY
1819 _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst)
Howard Hinnanteee2c142012-04-11 20:14:21 +00001820 volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001821 {return __cxx_atomic_fetch_sub(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001822 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001823 _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00001824 {return __cxx_atomic_fetch_sub(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001825
1826 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001827 _Tp* operator++(int) volatile _NOEXCEPT {return fetch_add(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001828 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001829 _Tp* operator++(int) _NOEXCEPT {return fetch_add(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001830 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001831 _Tp* operator--(int) volatile _NOEXCEPT {return fetch_sub(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001832 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001833 _Tp* operator--(int) _NOEXCEPT {return fetch_sub(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001834 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001835 _Tp* operator++() volatile _NOEXCEPT {return fetch_add(1) + 1;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001836 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001837 _Tp* operator++() _NOEXCEPT {return fetch_add(1) + 1;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001838 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001839 _Tp* operator--() volatile _NOEXCEPT {return fetch_sub(1) - 1;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001840 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001841 _Tp* operator--() _NOEXCEPT {return fetch_sub(1) - 1;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001842 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001843 _Tp* operator+=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001844 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001845 _Tp* operator+=(ptrdiff_t __op) _NOEXCEPT {return fetch_add(__op) + __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001846 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001847 _Tp* operator-=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001848 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001849 _Tp* operator-=(ptrdiff_t __op) _NOEXCEPT {return fetch_sub(__op) - __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001850};
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001851
1852// atomic_is_lock_free
1853
1854template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001855_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001856bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00001857atomic_is_lock_free(const volatile atomic<_Tp>* __o) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001858{
Howard Hinnant138f5922010-12-07 20:46:14 +00001859 return __o->is_lock_free();
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001860}
1861
1862template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001863_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001864bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00001865atomic_is_lock_free(const atomic<_Tp>* __o) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001866{
Howard Hinnant138f5922010-12-07 20:46:14 +00001867 return __o->is_lock_free();
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001868}
1869
1870// atomic_init
1871
1872template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001873_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001874void
Howard Hinnanteee2c142012-04-11 20:14:21 +00001875atomic_init(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001876{
Davide Italiano011f80a2019-03-05 18:40:49 +00001877 __cxx_atomic_init(&__o->__a_, __d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001878}
1879
1880template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001881_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001882void
Howard Hinnanteee2c142012-04-11 20:14:21 +00001883atomic_init(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001884{
Davide Italiano011f80a2019-03-05 18:40:49 +00001885 __cxx_atomic_init(&__o->__a_, __d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001886}
1887
1888// atomic_store
1889
1890template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001891_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001892void
Howard Hinnanteee2c142012-04-11 20:14:21 +00001893atomic_store(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001894{
Howard Hinnant138f5922010-12-07 20:46:14 +00001895 __o->store(__d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001896}
1897
1898template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001899_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001900void
Howard Hinnanteee2c142012-04-11 20:14:21 +00001901atomic_store(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001902{
Howard Hinnant138f5922010-12-07 20:46:14 +00001903 __o->store(__d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001904}
1905
1906// atomic_store_explicit
1907
1908template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001909_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001910void
Howard Hinnanteee2c142012-04-11 20:14:21 +00001911atomic_store_explicit(volatile atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001912 _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001913{
Howard Hinnant138f5922010-12-07 20:46:14 +00001914 __o->store(__d, __m);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001915}
1916
1917template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001918_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001919void
Howard Hinnanteee2c142012-04-11 20:14:21 +00001920atomic_store_explicit(atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001921 _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001922{
Howard Hinnant138f5922010-12-07 20:46:14 +00001923 __o->store(__d, __m);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001924}
1925
1926// atomic_load
1927
1928template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001929_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001930_Tp
Howard Hinnanteee2c142012-04-11 20:14:21 +00001931atomic_load(const volatile atomic<_Tp>* __o) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001932{
Howard Hinnant138f5922010-12-07 20:46:14 +00001933 return __o->load();
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001934}
1935
1936template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001937_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001938_Tp
Howard Hinnanteee2c142012-04-11 20:14:21 +00001939atomic_load(const atomic<_Tp>* __o) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001940{
Howard Hinnant138f5922010-12-07 20:46:14 +00001941 return __o->load();
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001942}
1943
1944// atomic_load_explicit
1945
1946template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001947_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001948_Tp
Howard Hinnanteee2c142012-04-11 20:14:21 +00001949atomic_load_explicit(const volatile atomic<_Tp>* __o, memory_order __m) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001950 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001951{
Howard Hinnant138f5922010-12-07 20:46:14 +00001952 return __o->load(__m);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001953}
1954
1955template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001956_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001957_Tp
Howard Hinnanteee2c142012-04-11 20:14:21 +00001958atomic_load_explicit(const atomic<_Tp>* __o, memory_order __m) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001959 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001960{
Howard Hinnant138f5922010-12-07 20:46:14 +00001961 return __o->load(__m);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001962}
1963
1964// atomic_exchange
1965
1966template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001967_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001968_Tp
Howard Hinnanteee2c142012-04-11 20:14:21 +00001969atomic_exchange(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001970{
Howard Hinnant138f5922010-12-07 20:46:14 +00001971 return __o->exchange(__d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001972}
1973
1974template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001975_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001976_Tp
Howard Hinnanteee2c142012-04-11 20:14:21 +00001977atomic_exchange(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001978{
Howard Hinnant138f5922010-12-07 20:46:14 +00001979 return __o->exchange(__d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001980}
1981
1982// atomic_exchange_explicit
1983
1984template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001985_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001986_Tp
Howard Hinnanteee2c142012-04-11 20:14:21 +00001987atomic_exchange_explicit(volatile atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001988{
Howard Hinnant138f5922010-12-07 20:46:14 +00001989 return __o->exchange(__d, __m);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001990}
1991
1992template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00001993_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001994_Tp
Howard Hinnanteee2c142012-04-11 20:14:21 +00001995atomic_exchange_explicit(atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001996{
Howard Hinnant138f5922010-12-07 20:46:14 +00001997 return __o->exchange(__d, __m);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001998}
1999
2000// atomic_compare_exchange_weak
2001
2002template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002003_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002004bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00002005atomic_compare_exchange_weak(volatile atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002006{
Howard Hinnant138f5922010-12-07 20:46:14 +00002007 return __o->compare_exchange_weak(*__e, __d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002008}
2009
2010template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002011_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002012bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00002013atomic_compare_exchange_weak(atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002014{
Howard Hinnant138f5922010-12-07 20:46:14 +00002015 return __o->compare_exchange_weak(*__e, __d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002016}
2017
2018// atomic_compare_exchange_strong
2019
2020template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002021_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002022bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00002023atomic_compare_exchange_strong(volatile atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002024{
Howard Hinnant138f5922010-12-07 20:46:14 +00002025 return __o->compare_exchange_strong(*__e, __d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002026}
2027
2028template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002029_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002030bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00002031atomic_compare_exchange_strong(atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002032{
Howard Hinnant138f5922010-12-07 20:46:14 +00002033 return __o->compare_exchange_strong(*__e, __d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002034}
2035
2036// atomic_compare_exchange_weak_explicit
2037
2038template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002039_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002040bool
2041atomic_compare_exchange_weak_explicit(volatile atomic<_Tp>* __o, _Tp* __e,
2042 _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00002043 memory_order __s, memory_order __f) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00002044 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002045{
Howard Hinnant138f5922010-12-07 20:46:14 +00002046 return __o->compare_exchange_weak(*__e, __d, __s, __f);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002047}
2048
2049template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002050_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002051bool
2052atomic_compare_exchange_weak_explicit(atomic<_Tp>* __o, _Tp* __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00002053 memory_order __s, memory_order __f) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00002054 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002055{
Howard Hinnant138f5922010-12-07 20:46:14 +00002056 return __o->compare_exchange_weak(*__e, __d, __s, __f);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002057}
2058
2059// atomic_compare_exchange_strong_explicit
2060
2061template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002062_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002063bool
2064atomic_compare_exchange_strong_explicit(volatile atomic<_Tp>* __o,
2065 _Tp* __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00002066 memory_order __s, memory_order __f) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00002067 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002068{
Howard Hinnant138f5922010-12-07 20:46:14 +00002069 return __o->compare_exchange_strong(*__e, __d, __s, __f);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002070}
2071
2072template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002073_LIBCPP_INLINE_VISIBILITY
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002074bool
2075atomic_compare_exchange_strong_explicit(atomic<_Tp>* __o, _Tp* __e,
2076 _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00002077 memory_order __s, memory_order __f) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00002078 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002079{
Howard Hinnant138f5922010-12-07 20:46:14 +00002080 return __o->compare_exchange_strong(*__e, __d, __s, __f);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002081}
2082
Olivier Giroux161e6e82020-02-18 09:58:34 -05002083// atomic_wait
2084
2085template <class _Tp>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002086_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002087void atomic_wait(const volatile atomic<_Tp>* __o,
2088 typename atomic<_Tp>::value_type __v) _NOEXCEPT
2089{
2090 return __o->wait(__v);
2091}
2092
2093template <class _Tp>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002094_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002095void atomic_wait(const atomic<_Tp>* __o,
2096 typename atomic<_Tp>::value_type __v) _NOEXCEPT
2097{
2098 return __o->wait(__v);
2099}
2100
2101// atomic_wait_explicit
2102
2103template <class _Tp>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002104_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002105void atomic_wait_explicit(const volatile atomic<_Tp>* __o,
2106 typename atomic<_Tp>::value_type __v,
2107 memory_order __m) _NOEXCEPT
2108 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
2109{
2110 return __o->wait(__v, __m);
2111}
2112
2113template <class _Tp>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002114_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002115void atomic_wait_explicit(const atomic<_Tp>* __o,
2116 typename atomic<_Tp>::value_type __v,
2117 memory_order __m) _NOEXCEPT
2118 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
2119{
2120 return __o->wait(__v, __m);
2121}
2122
2123// atomic_notify_one
2124
2125template <class _Tp>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002126_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002127void atomic_notify_one(volatile atomic<_Tp>* __o) _NOEXCEPT
2128{
2129 __o->notify_one();
2130}
2131template <class _Tp>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002132_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002133void atomic_notify_one(atomic<_Tp>* __o) _NOEXCEPT
2134{
2135 __o->notify_one();
2136}
2137
2138// atomic_notify_one
2139
2140template <class _Tp>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002141_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002142void atomic_notify_all(volatile atomic<_Tp>* __o) _NOEXCEPT
2143{
2144 __o->notify_all();
2145}
2146template <class _Tp>
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002147_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002148void atomic_notify_all(atomic<_Tp>* __o) _NOEXCEPT
2149{
2150 __o->notify_all();
2151}
2152
Howard Hinnant138f5922010-12-07 20:46:14 +00002153// atomic_fetch_add
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002154
2155template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002156_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002157typename enable_if
2158<
2159 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2160 _Tp
2161>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00002162atomic_fetch_add(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002163{
Howard Hinnant138f5922010-12-07 20:46:14 +00002164 return __o->fetch_add(__op);
2165}
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002166
Howard Hinnant138f5922010-12-07 20:46:14 +00002167template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002168_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002169typename enable_if
2170<
2171 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2172 _Tp
2173>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00002174atomic_fetch_add(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002175{
2176 return __o->fetch_add(__op);
2177}
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002178
Howard Hinnant138f5922010-12-07 20:46:14 +00002179template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002180_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002181_Tp*
Howard Hinnanteee2c142012-04-11 20:14:21 +00002182atomic_fetch_add(volatile atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002183{
2184 return __o->fetch_add(__op);
2185}
2186
2187template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002188_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002189_Tp*
Howard Hinnanteee2c142012-04-11 20:14:21 +00002190atomic_fetch_add(atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002191{
2192 return __o->fetch_add(__op);
2193}
2194
2195// atomic_fetch_add_explicit
2196
2197template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002198_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002199typename enable_if
2200<
2201 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2202 _Tp
2203>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00002204atomic_fetch_add_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002205{
2206 return __o->fetch_add(__op, __m);
2207}
2208
2209template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002210_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002211typename enable_if
2212<
2213 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2214 _Tp
2215>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00002216atomic_fetch_add_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002217{
2218 return __o->fetch_add(__op, __m);
2219}
2220
2221template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002222_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002223_Tp*
2224atomic_fetch_add_explicit(volatile atomic<_Tp*>* __o, ptrdiff_t __op,
Howard Hinnanteee2c142012-04-11 20:14:21 +00002225 memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002226{
2227 return __o->fetch_add(__op, __m);
2228}
2229
2230template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002231_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002232_Tp*
Howard Hinnanteee2c142012-04-11 20:14:21 +00002233atomic_fetch_add_explicit(atomic<_Tp*>* __o, ptrdiff_t __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002234{
2235 return __o->fetch_add(__op, __m);
2236}
2237
2238// atomic_fetch_sub
2239
2240template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002241_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002242typename enable_if
2243<
2244 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2245 _Tp
2246>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00002247atomic_fetch_sub(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002248{
2249 return __o->fetch_sub(__op);
2250}
2251
2252template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002253_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002254typename enable_if
2255<
2256 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2257 _Tp
2258>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00002259atomic_fetch_sub(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002260{
2261 return __o->fetch_sub(__op);
2262}
2263
2264template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002265_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002266_Tp*
Howard Hinnanteee2c142012-04-11 20:14:21 +00002267atomic_fetch_sub(volatile atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002268{
2269 return __o->fetch_sub(__op);
2270}
2271
2272template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002273_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002274_Tp*
Howard Hinnanteee2c142012-04-11 20:14:21 +00002275atomic_fetch_sub(atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002276{
2277 return __o->fetch_sub(__op);
2278}
2279
2280// atomic_fetch_sub_explicit
2281
2282template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002283_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002284typename enable_if
2285<
2286 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2287 _Tp
2288>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00002289atomic_fetch_sub_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002290{
2291 return __o->fetch_sub(__op, __m);
2292}
2293
2294template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002295_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002296typename enable_if
2297<
2298 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2299 _Tp
2300>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00002301atomic_fetch_sub_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002302{
2303 return __o->fetch_sub(__op, __m);
2304}
2305
2306template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002307_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002308_Tp*
2309atomic_fetch_sub_explicit(volatile atomic<_Tp*>* __o, ptrdiff_t __op,
Howard Hinnanteee2c142012-04-11 20:14:21 +00002310 memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002311{
2312 return __o->fetch_sub(__op, __m);
2313}
2314
2315template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002316_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002317_Tp*
Howard Hinnanteee2c142012-04-11 20:14:21 +00002318atomic_fetch_sub_explicit(atomic<_Tp*>* __o, ptrdiff_t __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002319{
2320 return __o->fetch_sub(__op, __m);
2321}
2322
2323// atomic_fetch_and
2324
2325template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002326_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002327typename enable_if
2328<
2329 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2330 _Tp
2331>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00002332atomic_fetch_and(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002333{
2334 return __o->fetch_and(__op);
2335}
2336
2337template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002338_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002339typename enable_if
2340<
2341 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2342 _Tp
2343>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00002344atomic_fetch_and(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002345{
2346 return __o->fetch_and(__op);
2347}
2348
2349// atomic_fetch_and_explicit
2350
2351template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002352_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002353typename enable_if
2354<
2355 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2356 _Tp
2357>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00002358atomic_fetch_and_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002359{
2360 return __o->fetch_and(__op, __m);
2361}
2362
2363template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002364_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002365typename enable_if
2366<
2367 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2368 _Tp
2369>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00002370atomic_fetch_and_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002371{
2372 return __o->fetch_and(__op, __m);
2373}
2374
2375// atomic_fetch_or
2376
2377template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002378_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002379typename enable_if
2380<
2381 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2382 _Tp
2383>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00002384atomic_fetch_or(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002385{
2386 return __o->fetch_or(__op);
2387}
2388
2389template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002390_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002391typename enable_if
2392<
2393 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2394 _Tp
2395>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00002396atomic_fetch_or(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002397{
2398 return __o->fetch_or(__op);
2399}
2400
2401// atomic_fetch_or_explicit
2402
2403template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002404_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002405typename enable_if
2406<
2407 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2408 _Tp
2409>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00002410atomic_fetch_or_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002411{
2412 return __o->fetch_or(__op, __m);
2413}
2414
2415template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002416_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002417typename enable_if
2418<
2419 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2420 _Tp
2421>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00002422atomic_fetch_or_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002423{
2424 return __o->fetch_or(__op, __m);
2425}
2426
2427// atomic_fetch_xor
2428
2429template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002430_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002431typename enable_if
2432<
2433 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2434 _Tp
2435>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00002436atomic_fetch_xor(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002437{
2438 return __o->fetch_xor(__op);
2439}
2440
2441template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002442_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002443typename enable_if
2444<
2445 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2446 _Tp
2447>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00002448atomic_fetch_xor(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002449{
2450 return __o->fetch_xor(__op);
2451}
2452
2453// atomic_fetch_xor_explicit
2454
2455template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002456_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002457typename enable_if
2458<
2459 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2460 _Tp
2461>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00002462atomic_fetch_xor_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002463{
2464 return __o->fetch_xor(__op, __m);
2465}
2466
2467template <class _Tp>
Davide Italiano011f80a2019-03-05 18:40:49 +00002468_LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00002469typename enable_if
2470<
2471 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2472 _Tp
2473>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00002474atomic_fetch_xor_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00002475{
2476 return __o->fetch_xor(__op, __m);
2477}
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00002478
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002479// flag type and operations
2480
2481typedef struct atomic_flag
2482{
Davide Italiano011f80a2019-03-05 18:40:49 +00002483 __cxx_atomic_impl<_LIBCPP_ATOMIC_FLAG_TYPE> __a_;
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002484
2485 _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002486 bool test(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
2487 {return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m);}
2488 _LIBCPP_INLINE_VISIBILITY
2489 bool test(memory_order __m = memory_order_seq_cst) const _NOEXCEPT
2490 {return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m);}
2491
2492 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00002493 bool test_and_set(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00002494 {return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);}
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002495 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00002496 bool test_and_set(memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00002497 {return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);}
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002498 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00002499 void clear(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00002500 {__cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);}
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002501 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00002502 void clear(memory_order __m = memory_order_seq_cst) _NOEXCEPT
Davide Italiano011f80a2019-03-05 18:40:49 +00002503 {__cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);}
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002504
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002505 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002506 void wait(bool __v, memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
2507 {__cxx_atomic_wait(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002508 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002509 void wait(bool __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT
2510 {__cxx_atomic_wait(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002511 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002512 void notify_one() volatile _NOEXCEPT
2513 {__cxx_atomic_notify_one(&__a_);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002514 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002515 void notify_one() _NOEXCEPT
2516 {__cxx_atomic_notify_one(&__a_);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002517 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002518 void notify_all() volatile _NOEXCEPT
2519 {__cxx_atomic_notify_all(&__a_);}
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002520 _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
Olivier Giroux161e6e82020-02-18 09:58:34 -05002521 void notify_all() _NOEXCEPT
2522 {__cxx_atomic_notify_all(&__a_);}
2523
2524 _LIBCPP_INLINE_VISIBILITY
Davide Italiano011f80a2019-03-05 18:40:49 +00002525 atomic_flag() _NOEXCEPT _LIBCPP_DEFAULT
Howard Hinnant3d284222013-05-02 20:18:43 +00002526
Marshall Clowcf990752018-04-25 14:27:29 +00002527 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
Eric Fiselierfec26a92016-05-03 02:12:26 +00002528 atomic_flag(bool __b) _NOEXCEPT : __a_(__b) {} // EXTENSION
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002529
Eric Fiselier2d8515f2017-01-06 20:58:25 +00002530#ifndef _LIBCPP_CXX03_LANG
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002531 atomic_flag(const atomic_flag&) = delete;
2532 atomic_flag& operator=(const atomic_flag&) = delete;
2533 atomic_flag& operator=(const atomic_flag&) volatile = delete;
Eric Fiselier2d8515f2017-01-06 20:58:25 +00002534#else
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002535private:
Olivier Giroux161e6e82020-02-18 09:58:34 -05002536 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002537 atomic_flag(const atomic_flag&);
Olivier Giroux161e6e82020-02-18 09:58:34 -05002538 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002539 atomic_flag& operator=(const atomic_flag&);
Olivier Giroux161e6e82020-02-18 09:58:34 -05002540 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002541 atomic_flag& operator=(const atomic_flag&) volatile;
Eric Fiselier2d8515f2017-01-06 20:58:25 +00002542#endif
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002543} atomic_flag;
2544
Olivier Giroux161e6e82020-02-18 09:58:34 -05002545
2546inline _LIBCPP_INLINE_VISIBILITY
2547bool
2548atomic_flag_test(const volatile atomic_flag* __o) _NOEXCEPT
2549{
2550 return __o->test();
2551}
2552
2553inline _LIBCPP_INLINE_VISIBILITY
2554bool
2555atomic_flag_test(const atomic_flag* __o) _NOEXCEPT
2556{
2557 return __o->test();
2558}
2559
2560inline _LIBCPP_INLINE_VISIBILITY
2561bool
2562atomic_flag_test_explicit(const volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
2563{
2564 return __o->test(__m);
2565}
2566
2567inline _LIBCPP_INLINE_VISIBILITY
2568bool
2569atomic_flag_test_explicit(const atomic_flag* __o, memory_order __m) _NOEXCEPT
2570{
2571 return __o->test(__m);
2572}
2573
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002574inline _LIBCPP_INLINE_VISIBILITY
2575bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00002576atomic_flag_test_and_set(volatile atomic_flag* __o) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002577{
2578 return __o->test_and_set();
2579}
2580
2581inline _LIBCPP_INLINE_VISIBILITY
2582bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00002583atomic_flag_test_and_set(atomic_flag* __o) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002584{
2585 return __o->test_and_set();
2586}
2587
2588inline _LIBCPP_INLINE_VISIBILITY
2589bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00002590atomic_flag_test_and_set_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002591{
2592 return __o->test_and_set(__m);
2593}
2594
2595inline _LIBCPP_INLINE_VISIBILITY
2596bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00002597atomic_flag_test_and_set_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002598{
2599 return __o->test_and_set(__m);
2600}
2601
2602inline _LIBCPP_INLINE_VISIBILITY
2603void
Howard Hinnanteee2c142012-04-11 20:14:21 +00002604atomic_flag_clear(volatile atomic_flag* __o) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002605{
2606 __o->clear();
2607}
2608
2609inline _LIBCPP_INLINE_VISIBILITY
2610void
Howard Hinnanteee2c142012-04-11 20:14:21 +00002611atomic_flag_clear(atomic_flag* __o) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002612{
2613 __o->clear();
2614}
2615
2616inline _LIBCPP_INLINE_VISIBILITY
2617void
Howard Hinnanteee2c142012-04-11 20:14:21 +00002618atomic_flag_clear_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002619{
2620 __o->clear(__m);
2621}
2622
2623inline _LIBCPP_INLINE_VISIBILITY
2624void
Howard Hinnanteee2c142012-04-11 20:14:21 +00002625atomic_flag_clear_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002626{
2627 __o->clear(__m);
2628}
2629
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002630inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
Olivier Giroux161e6e82020-02-18 09:58:34 -05002631void
2632atomic_flag_wait(const volatile atomic_flag* __o, bool __v) _NOEXCEPT
2633{
2634 __o->wait(__v);
2635}
2636
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002637inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
Olivier Giroux161e6e82020-02-18 09:58:34 -05002638void
2639atomic_flag_wait(const atomic_flag* __o, bool __v) _NOEXCEPT
2640{
2641 __o->wait(__v);
2642}
2643
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002644inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
Olivier Giroux161e6e82020-02-18 09:58:34 -05002645void
2646atomic_flag_wait_explicit(const volatile atomic_flag* __o,
2647 bool __v, memory_order __m) _NOEXCEPT
2648{
2649 __o->wait(__v, __m);
2650}
2651
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002652inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
Olivier Giroux161e6e82020-02-18 09:58:34 -05002653void
2654atomic_flag_wait_explicit(const atomic_flag* __o,
2655 bool __v, memory_order __m) _NOEXCEPT
2656{
2657 __o->wait(__v, __m);
2658}
2659
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002660inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
Olivier Giroux161e6e82020-02-18 09:58:34 -05002661void
2662atomic_flag_notify_one(volatile atomic_flag* __o) _NOEXCEPT
2663{
2664 __o->notify_one();
2665}
2666
Louis Dionne3dde4ab2020-02-24 10:09:29 -05002667inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
Olivier Giroux161e6e82020-02-18 09:58:34 -05002668void
2669atomic_flag_notify_one(atomic_flag* __o) _NOEXCEPT
2670{
2671 __o->notify_one();
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_notify_all(volatile atomic_flag* __o) _NOEXCEPT
2677{
2678 __o->notify_all();
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_notify_all(atomic_flag* __o) _NOEXCEPT
2684{
2685 __o->notify_all();
2686}
2687
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002688// fences
2689
2690inline _LIBCPP_INLINE_VISIBILITY
2691void
Howard Hinnanteee2c142012-04-11 20:14:21 +00002692atomic_thread_fence(memory_order __m) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002693{
Davide Italiano011f80a2019-03-05 18:40:49 +00002694 __cxx_atomic_thread_fence(__m);
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002695}
2696
2697inline _LIBCPP_INLINE_VISIBILITY
2698void
Howard Hinnanteee2c142012-04-11 20:14:21 +00002699atomic_signal_fence(memory_order __m) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002700{
Davide Italiano011f80a2019-03-05 18:40:49 +00002701 __cxx_atomic_signal_fence(__m);
Howard Hinnant6ac60f82010-12-08 17:20:28 +00002702}
2703
Howard Hinnant96e4cd62010-12-07 23:24:41 +00002704// Atomics for standard typedef types
2705
Howard Hinnantf0af8d92013-01-04 18:58:50 +00002706typedef atomic<bool> atomic_bool;
Howard Hinnant96e4cd62010-12-07 23:24:41 +00002707typedef atomic<char> atomic_char;
2708typedef atomic<signed char> atomic_schar;
2709typedef atomic<unsigned char> atomic_uchar;
2710typedef atomic<short> atomic_short;
2711typedef atomic<unsigned short> atomic_ushort;
2712typedef atomic<int> atomic_int;
2713typedef atomic<unsigned int> atomic_uint;
2714typedef atomic<long> atomic_long;
2715typedef atomic<unsigned long> atomic_ulong;
2716typedef atomic<long long> atomic_llong;
2717typedef atomic<unsigned long long> atomic_ullong;
2718typedef atomic<char16_t> atomic_char16_t;
2719typedef atomic<char32_t> atomic_char32_t;
2720typedef atomic<wchar_t> atomic_wchar_t;
2721
2722typedef atomic<int_least8_t> atomic_int_least8_t;
2723typedef atomic<uint_least8_t> atomic_uint_least8_t;
2724typedef atomic<int_least16_t> atomic_int_least16_t;
2725typedef atomic<uint_least16_t> atomic_uint_least16_t;
2726typedef atomic<int_least32_t> atomic_int_least32_t;
2727typedef atomic<uint_least32_t> atomic_uint_least32_t;
2728typedef atomic<int_least64_t> atomic_int_least64_t;
2729typedef atomic<uint_least64_t> atomic_uint_least64_t;
2730
2731typedef atomic<int_fast8_t> atomic_int_fast8_t;
2732typedef atomic<uint_fast8_t> atomic_uint_fast8_t;
2733typedef atomic<int_fast16_t> atomic_int_fast16_t;
2734typedef atomic<uint_fast16_t> atomic_uint_fast16_t;
2735typedef atomic<int_fast32_t> atomic_int_fast32_t;
2736typedef atomic<uint_fast32_t> atomic_uint_fast32_t;
2737typedef atomic<int_fast64_t> atomic_int_fast64_t;
2738typedef atomic<uint_fast64_t> atomic_uint_fast64_t;
2739
Marshall Clowf710afc2016-06-30 15:28:38 +00002740typedef atomic< int8_t> atomic_int8_t;
2741typedef atomic<uint8_t> atomic_uint8_t;
2742typedef atomic< int16_t> atomic_int16_t;
2743typedef atomic<uint16_t> atomic_uint16_t;
2744typedef atomic< int32_t> atomic_int32_t;
2745typedef atomic<uint32_t> atomic_uint32_t;
2746typedef atomic< int64_t> atomic_int64_t;
2747typedef atomic<uint64_t> atomic_uint64_t;
2748
Howard Hinnant96e4cd62010-12-07 23:24:41 +00002749typedef atomic<intptr_t> atomic_intptr_t;
2750typedef atomic<uintptr_t> atomic_uintptr_t;
2751typedef atomic<size_t> atomic_size_t;
2752typedef atomic<ptrdiff_t> atomic_ptrdiff_t;
2753typedef atomic<intmax_t> atomic_intmax_t;
2754typedef atomic<uintmax_t> atomic_uintmax_t;
2755
Olivier Giroux161e6e82020-02-18 09:58:34 -05002756// atomic_*_lock_free : prefer the contention type most highly, then the largest lock-free type
2757
2758#ifdef __cpp_lib_atomic_is_always_lock_free
2759# define _LIBCPP_CONTENTION_LOCK_FREE __atomic_always_lock_free(sizeof(__cxx_contention_t), 0)
2760#else
2761# define _LIBCPP_CONTENTION_LOCK_FREE false
2762#endif
2763
2764#if ATOMIC_LLONG_LOCK_FREE == 2
2765typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, long long>::type __libcpp_signed_lock_free;
2766typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned long long>::type __libcpp_unsigned_lock_free;
2767#elif ATOMIC_INT_LOCK_FREE == 2
2768typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, int>::type __libcpp_signed_lock_free;
2769typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned int>::type __libcpp_unsigned_lock_free;
2770#elif ATOMIC_SHORT_LOCK_FREE == 2
2771typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, short>::type __libcpp_signed_lock_free;
2772typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned short>::type __libcpp_unsigned_lock_free;
2773#elif ATOMIC_CHAR_LOCK_FREE == 2
2774typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, char>::type __libcpp_signed_lock_free;
2775typedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned char>::type __libcpp_unsigned_lock_free;
2776#else
2777 // No signed/unsigned lock-free types
2778#endif
2779
2780typedef atomic<__libcpp_signed_lock_free> atomic_signed_lock_free;
2781typedef atomic<__libcpp_unsigned_lock_free> atomic_unsigned_lock_free;
2782
Howard Hinnantf1f066a2010-09-29 21:20:03 +00002783#define ATOMIC_FLAG_INIT {false}
Howard Hinnant953c31d2010-10-04 18:52:54 +00002784#define ATOMIC_VAR_INIT(__v) {__v}
2785
Howard Hinnant71be7292010-09-27 21:17:38 +00002786_LIBCPP_END_NAMESPACE_STD
2787
Howard Hinnant71be7292010-09-27 21:17:38 +00002788#endif // _LIBCPP_ATOMIC