xref: /llvm-project-15.0.7/libcxx/include/atomic (revision d64394b8)
1cd39d413SHoward Hinnant// -*- C++ -*-
2eb8650a7SLouis Dionne//===----------------------------------------------------------------------===//
3cd39d413SHoward Hinnant//
42946cd70SChandler Carruth// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
52946cd70SChandler Carruth// See https://llvm.org/LICENSE.txt for license information.
62946cd70SChandler Carruth// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7cd39d413SHoward Hinnant//
8cd39d413SHoward Hinnant//===----------------------------------------------------------------------===//
9cd39d413SHoward Hinnant
10cd39d413SHoward Hinnant#ifndef _LIBCPP_ATOMIC
11cd39d413SHoward Hinnant#define _LIBCPP_ATOMIC
12cd39d413SHoward Hinnant
13cd39d413SHoward Hinnant/*
14cd39d413SHoward Hinnant    atomic synopsis
15cd39d413SHoward Hinnant
16cd39d413SHoward Hinnantnamespace std
17cd39d413SHoward Hinnant{
18cd39d413SHoward Hinnant
19fc4bff0cSOlivier Giroux// feature test macro [version.syn]
20b95ee819SJF Bastien
21fc4bff0cSOlivier Giroux#define __cpp_lib_atomic_is_always_lock_free
22fc4bff0cSOlivier Giroux#define __cpp_lib_atomic_flag_test
23fc4bff0cSOlivier Giroux#define __cpp_lib_atomic_lock_free_type_aliases
24fc4bff0cSOlivier Giroux#define __cpp_lib_atomic_wait
25b95ee819SJF Bastien
26cd39d413SHoward Hinnant // order and consistency
27cd39d413SHoward Hinnant
286de760acSDavide Italiano enum memory_order: unspecified // enum class in C++20
29cd39d413SHoward Hinnant {
306de760acSDavide Italiano    relaxed,
316de760acSDavide Italiano    consume, // load-consume
326de760acSDavide Italiano    acquire, // load-acquire
336de760acSDavide Italiano    release, // store-release
346de760acSDavide Italiano    acq_rel, // store-release load-acquire
356de760acSDavide Italiano    seq_cst // store-release load-acquire
366de760acSDavide Italiano };
376de760acSDavide Italiano
386de760acSDavide Italiano inline constexpr auto memory_order_relaxed = memory_order::relaxed;
396de760acSDavide Italiano inline constexpr auto memory_order_consume = memory_order::consume;
406de760acSDavide Italiano inline constexpr auto memory_order_acquire = memory_order::acquire;
416de760acSDavide Italiano inline constexpr auto memory_order_release = memory_order::release;
426de760acSDavide Italiano inline constexpr auto memory_order_acq_rel = memory_order::acq_rel;
436de760acSDavide Italiano inline constexpr auto memory_order_seq_cst = memory_order::seq_cst;
44cd39d413SHoward Hinnant
45d01320c2SHoward Hinnanttemplate <class T> T kill_dependency(T y) noexcept;
46cd39d413SHoward Hinnant
47cd39d413SHoward Hinnant// lock-free property
48cd39d413SHoward Hinnant
49ead15d1fSHoward Hinnant#define ATOMIC_BOOL_LOCK_FREE unspecified
50cd39d413SHoward Hinnant#define ATOMIC_CHAR_LOCK_FREE unspecified
519c97e4efSMarek Kurdej#define ATOMIC_CHAR8_T_LOCK_FREE unspecified // C++20
52cd39d413SHoward Hinnant#define ATOMIC_CHAR16_T_LOCK_FREE unspecified
53cd39d413SHoward Hinnant#define ATOMIC_CHAR32_T_LOCK_FREE unspecified
54cd39d413SHoward Hinnant#define ATOMIC_WCHAR_T_LOCK_FREE unspecified
55cd39d413SHoward Hinnant#define ATOMIC_SHORT_LOCK_FREE unspecified
56cd39d413SHoward Hinnant#define ATOMIC_INT_LOCK_FREE unspecified
57cd39d413SHoward Hinnant#define ATOMIC_LONG_LOCK_FREE unspecified
58cd39d413SHoward Hinnant#define ATOMIC_LLONG_LOCK_FREE unspecified
59ead15d1fSHoward Hinnant#define ATOMIC_POINTER_LOCK_FREE unspecified
60cd39d413SHoward Hinnant
61cd39d413SHoward Hinnanttemplate <class T>
62cd39d413SHoward Hinnantstruct atomic
63cd39d413SHoward Hinnant{
6406aaf0b3SOlivier Giroux    using value_type = T;
6506aaf0b3SOlivier Giroux
66b95ee819SJF Bastien    static constexpr bool is_always_lock_free;
67d01320c2SHoward Hinnant    bool is_lock_free() const volatile noexcept;
68d01320c2SHoward Hinnant    bool is_lock_free() const noexcept;
6906aaf0b3SOlivier Giroux
7056aac567SRaul Tambre    atomic() noexcept = default; // until C++20
7156aac567SRaul Tambre    constexpr atomic() noexcept(is_nothrow_default_constructible_v<T>); // since C++20
7206aaf0b3SOlivier Giroux    constexpr atomic(T desr) noexcept;
7306aaf0b3SOlivier Giroux    atomic(const atomic&) = delete;
7406aaf0b3SOlivier Giroux    atomic& operator=(const atomic&) = delete;
7506aaf0b3SOlivier Giroux    atomic& operator=(const atomic&) volatile = delete;
7606aaf0b3SOlivier Giroux
77d01320c2SHoward Hinnant    T load(memory_order m = memory_order_seq_cst) const volatile noexcept;
78d01320c2SHoward Hinnant    T load(memory_order m = memory_order_seq_cst) const noexcept;
79d01320c2SHoward Hinnant    operator T() const volatile noexcept;
80d01320c2SHoward Hinnant    operator T() const noexcept;
8106aaf0b3SOlivier Giroux    void store(T desr, memory_order m = memory_order_seq_cst) volatile noexcept;
8206aaf0b3SOlivier Giroux    void store(T desr, memory_order m = memory_order_seq_cst) noexcept;
8306aaf0b3SOlivier Giroux    T operator=(T) volatile noexcept;
8406aaf0b3SOlivier Giroux    T operator=(T) noexcept;
8506aaf0b3SOlivier Giroux
86d01320c2SHoward Hinnant    T exchange(T desr, memory_order m = memory_order_seq_cst) volatile noexcept;
87d01320c2SHoward Hinnant    T exchange(T desr, memory_order m = memory_order_seq_cst) noexcept;
889847abacSHoward Hinnant    bool compare_exchange_weak(T& expc, T desr,
89d01320c2SHoward Hinnant                               memory_order s, memory_order f) volatile noexcept;
90d01320c2SHoward Hinnant    bool compare_exchange_weak(T& expc, T desr, memory_order s, memory_order f) noexcept;
919847abacSHoward Hinnant    bool compare_exchange_strong(T& expc, T desr,
92d01320c2SHoward Hinnant                                 memory_order s, memory_order f) volatile noexcept;
939847abacSHoward Hinnant    bool compare_exchange_strong(T& expc, T desr,
94d01320c2SHoward Hinnant                                 memory_order s, memory_order f) noexcept;
959847abacSHoward Hinnant    bool compare_exchange_weak(T& expc, T desr,
96d01320c2SHoward Hinnant                               memory_order m = memory_order_seq_cst) volatile noexcept;
979847abacSHoward Hinnant    bool compare_exchange_weak(T& expc, T desr,
98d01320c2SHoward Hinnant                               memory_order m = memory_order_seq_cst) noexcept;
999847abacSHoward Hinnant    bool compare_exchange_strong(T& expc, T desr,
100d01320c2SHoward Hinnant                                memory_order m = memory_order_seq_cst) volatile noexcept;
1019847abacSHoward Hinnant    bool compare_exchange_strong(T& expc, T desr,
102d01320c2SHoward Hinnant                                 memory_order m = memory_order_seq_cst) noexcept;
103cd39d413SHoward Hinnant
10406aaf0b3SOlivier Giroux    void wait(T, memory_order = memory_order::seq_cst) const volatile noexcept;
10506aaf0b3SOlivier Giroux    void wait(T, memory_order = memory_order::seq_cst) const noexcept;
10606aaf0b3SOlivier Giroux    void notify_one() volatile noexcept;
10706aaf0b3SOlivier Giroux    void notify_one() noexcept;
10806aaf0b3SOlivier Giroux    void notify_all() volatile noexcept;
10906aaf0b3SOlivier Giroux    void notify_all() noexcept;
110cd39d413SHoward Hinnant};
111cd39d413SHoward Hinnant
112cd39d413SHoward Hinnanttemplate <>
1139847abacSHoward Hinnantstruct atomic<integral>
114cd39d413SHoward Hinnant{
11506aaf0b3SOlivier Giroux    using value_type = integral;
116fc4bff0cSOlivier Giroux    using difference_type = value_type;
11706aaf0b3SOlivier Giroux
118b95ee819SJF Bastien    static constexpr bool is_always_lock_free;
119d01320c2SHoward Hinnant    bool is_lock_free() const volatile noexcept;
120d01320c2SHoward Hinnant    bool is_lock_free() const noexcept;
12106aaf0b3SOlivier Giroux
12206aaf0b3SOlivier Giroux    atomic() noexcept = default;
12306aaf0b3SOlivier Giroux    constexpr atomic(integral desr) noexcept;
12406aaf0b3SOlivier Giroux    atomic(const atomic&) = delete;
12506aaf0b3SOlivier Giroux    atomic& operator=(const atomic&) = delete;
12606aaf0b3SOlivier Giroux    atomic& operator=(const atomic&) volatile = delete;
12706aaf0b3SOlivier Giroux
128d01320c2SHoward Hinnant    integral load(memory_order m = memory_order_seq_cst) const volatile noexcept;
129d01320c2SHoward Hinnant    integral load(memory_order m = memory_order_seq_cst) const noexcept;
130d01320c2SHoward Hinnant    operator integral() const volatile noexcept;
131d01320c2SHoward Hinnant    operator integral() const noexcept;
13206aaf0b3SOlivier Giroux    void store(integral desr, memory_order m = memory_order_seq_cst) volatile noexcept;
13306aaf0b3SOlivier Giroux    void store(integral desr, memory_order m = memory_order_seq_cst) noexcept;
13406aaf0b3SOlivier Giroux    integral operator=(integral desr) volatile noexcept;
13506aaf0b3SOlivier Giroux    integral operator=(integral desr) noexcept;
13606aaf0b3SOlivier Giroux
1379847abacSHoward Hinnant    integral exchange(integral desr,
138d01320c2SHoward Hinnant                      memory_order m = memory_order_seq_cst) volatile noexcept;
139d01320c2SHoward Hinnant    integral exchange(integral desr, memory_order m = memory_order_seq_cst) noexcept;
1409847abacSHoward Hinnant    bool compare_exchange_weak(integral& expc, integral desr,
141d01320c2SHoward Hinnant                               memory_order s, memory_order f) volatile noexcept;
1429847abacSHoward Hinnant    bool compare_exchange_weak(integral& expc, integral desr,
143d01320c2SHoward Hinnant                               memory_order s, memory_order f) noexcept;
1449847abacSHoward Hinnant    bool compare_exchange_strong(integral& expc, integral desr,
145d01320c2SHoward Hinnant                                 memory_order s, memory_order f) volatile noexcept;
1469847abacSHoward Hinnant    bool compare_exchange_strong(integral& expc, integral desr,
147d01320c2SHoward Hinnant                                 memory_order s, memory_order f) noexcept;
1489847abacSHoward Hinnant    bool compare_exchange_weak(integral& expc, integral desr,
149d01320c2SHoward Hinnant                               memory_order m = memory_order_seq_cst) volatile noexcept;
1509847abacSHoward Hinnant    bool compare_exchange_weak(integral& expc, integral desr,
151d01320c2SHoward Hinnant                               memory_order m = memory_order_seq_cst) noexcept;
1529847abacSHoward Hinnant    bool compare_exchange_strong(integral& expc, integral desr,
153d01320c2SHoward Hinnant                                memory_order m = memory_order_seq_cst) volatile noexcept;
1549847abacSHoward Hinnant    bool compare_exchange_strong(integral& expc, integral desr,
155d01320c2SHoward Hinnant                                 memory_order m = memory_order_seq_cst) noexcept;
156cd39d413SHoward Hinnant
15706aaf0b3SOlivier Giroux    integral fetch_add(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
158d01320c2SHoward Hinnant    integral fetch_add(integral op, memory_order m = memory_order_seq_cst) noexcept;
15906aaf0b3SOlivier Giroux    integral fetch_sub(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
160d01320c2SHoward Hinnant    integral fetch_sub(integral op, memory_order m = memory_order_seq_cst) noexcept;
16106aaf0b3SOlivier Giroux    integral fetch_and(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
162d01320c2SHoward Hinnant    integral fetch_and(integral op, memory_order m = memory_order_seq_cst) noexcept;
16306aaf0b3SOlivier Giroux    integral fetch_or(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
164d01320c2SHoward Hinnant    integral fetch_or(integral op, memory_order m = memory_order_seq_cst) noexcept;
16506aaf0b3SOlivier Giroux    integral fetch_xor(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
166d01320c2SHoward Hinnant    integral fetch_xor(integral op, memory_order m = memory_order_seq_cst) noexcept;
167cd39d413SHoward Hinnant
168d01320c2SHoward Hinnant    integral operator++(int) volatile noexcept;
169d01320c2SHoward Hinnant    integral operator++(int) noexcept;
170d01320c2SHoward Hinnant    integral operator--(int) volatile noexcept;
171d01320c2SHoward Hinnant    integral operator--(int) noexcept;
172d01320c2SHoward Hinnant    integral operator++() volatile noexcept;
173d01320c2SHoward Hinnant    integral operator++() noexcept;
174d01320c2SHoward Hinnant    integral operator--() volatile noexcept;
175d01320c2SHoward Hinnant    integral operator--() noexcept;
176d01320c2SHoward Hinnant    integral operator+=(integral op) volatile noexcept;
177d01320c2SHoward Hinnant    integral operator+=(integral op) noexcept;
178d01320c2SHoward Hinnant    integral operator-=(integral op) volatile noexcept;
179d01320c2SHoward Hinnant    integral operator-=(integral op) noexcept;
180d01320c2SHoward Hinnant    integral operator&=(integral op) volatile noexcept;
181d01320c2SHoward Hinnant    integral operator&=(integral op) noexcept;
182d01320c2SHoward Hinnant    integral operator|=(integral op) volatile noexcept;
183d01320c2SHoward Hinnant    integral operator|=(integral op) noexcept;
184d01320c2SHoward Hinnant    integral operator^=(integral op) volatile noexcept;
185d01320c2SHoward Hinnant    integral operator^=(integral op) noexcept;
18606aaf0b3SOlivier Giroux
18706aaf0b3SOlivier Giroux    void wait(integral, memory_order = memory_order::seq_cst) const volatile noexcept;
18806aaf0b3SOlivier Giroux    void wait(integral, memory_order = memory_order::seq_cst) const noexcept;
18906aaf0b3SOlivier Giroux    void notify_one() volatile noexcept;
19006aaf0b3SOlivier Giroux    void notify_one() noexcept;
19106aaf0b3SOlivier Giroux    void notify_all() volatile noexcept;
19206aaf0b3SOlivier Giroux    void notify_all() noexcept;
193cd39d413SHoward Hinnant};
194cd39d413SHoward Hinnant
195cd39d413SHoward Hinnanttemplate <class T>
196cd39d413SHoward Hinnantstruct atomic<T*>
197cd39d413SHoward Hinnant{
19806aaf0b3SOlivier Giroux    using value_type = T*;
199fc4bff0cSOlivier Giroux    using difference_type = ptrdiff_t;
20006aaf0b3SOlivier Giroux
201b95ee819SJF Bastien    static constexpr bool is_always_lock_free;
202d01320c2SHoward Hinnant    bool is_lock_free() const volatile noexcept;
203d01320c2SHoward Hinnant    bool is_lock_free() const noexcept;
20406aaf0b3SOlivier Giroux
20556aac567SRaul Tambre    atomic() noexcept = default; // until C++20
20656aac567SRaul Tambre    constexpr atomic() noexcept; // since C++20
20706aaf0b3SOlivier Giroux    constexpr atomic(T* desr) noexcept;
20806aaf0b3SOlivier Giroux    atomic(const atomic&) = delete;
20906aaf0b3SOlivier Giroux    atomic& operator=(const atomic&) = delete;
21006aaf0b3SOlivier Giroux    atomic& operator=(const atomic&) volatile = delete;
21106aaf0b3SOlivier Giroux
212d01320c2SHoward Hinnant    T* load(memory_order m = memory_order_seq_cst) const volatile noexcept;
213d01320c2SHoward Hinnant    T* load(memory_order m = memory_order_seq_cst) const noexcept;
214d01320c2SHoward Hinnant    operator T*() const volatile noexcept;
215d01320c2SHoward Hinnant    operator T*() const noexcept;
21606aaf0b3SOlivier Giroux    void store(T* desr, memory_order m = memory_order_seq_cst) volatile noexcept;
21706aaf0b3SOlivier Giroux    void store(T* desr, memory_order m = memory_order_seq_cst) noexcept;
21806aaf0b3SOlivier Giroux    T* operator=(T*) volatile noexcept;
21906aaf0b3SOlivier Giroux    T* operator=(T*) noexcept;
22006aaf0b3SOlivier Giroux
221d01320c2SHoward Hinnant    T* exchange(T* desr, memory_order m = memory_order_seq_cst) volatile noexcept;
222d01320c2SHoward Hinnant    T* exchange(T* desr, memory_order m = memory_order_seq_cst) noexcept;
2239847abacSHoward Hinnant    bool compare_exchange_weak(T*& expc, T* desr,
224d01320c2SHoward Hinnant                               memory_order s, memory_order f) volatile noexcept;
2259847abacSHoward Hinnant    bool compare_exchange_weak(T*& expc, T* desr,
226d01320c2SHoward Hinnant                               memory_order s, memory_order f) noexcept;
2279847abacSHoward Hinnant    bool compare_exchange_strong(T*& expc, T* desr,
228d01320c2SHoward Hinnant                                 memory_order s, memory_order f) volatile noexcept;
2299847abacSHoward Hinnant    bool compare_exchange_strong(T*& expc, T* desr,
230d01320c2SHoward Hinnant                                 memory_order s, memory_order f) noexcept;
2319847abacSHoward Hinnant    bool compare_exchange_weak(T*& expc, T* desr,
232d01320c2SHoward Hinnant                               memory_order m = memory_order_seq_cst) volatile noexcept;
2339847abacSHoward Hinnant    bool compare_exchange_weak(T*& expc, T* desr,
234d01320c2SHoward Hinnant                               memory_order m = memory_order_seq_cst) noexcept;
2359847abacSHoward Hinnant    bool compare_exchange_strong(T*& expc, T* desr,
236d01320c2SHoward Hinnant                                memory_order m = memory_order_seq_cst) volatile noexcept;
2379847abacSHoward Hinnant    bool compare_exchange_strong(T*& expc, T* desr,
238d01320c2SHoward Hinnant                                 memory_order m = memory_order_seq_cst) noexcept;
239d01320c2SHoward Hinnant    T* fetch_add(ptrdiff_t op, memory_order m = memory_order_seq_cst) volatile noexcept;
240d01320c2SHoward Hinnant    T* fetch_add(ptrdiff_t op, memory_order m = memory_order_seq_cst) noexcept;
241d01320c2SHoward Hinnant    T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst) volatile noexcept;
242d01320c2SHoward Hinnant    T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst) noexcept;
2439847abacSHoward Hinnant
244d01320c2SHoward Hinnant    T* operator++(int) volatile noexcept;
245d01320c2SHoward Hinnant    T* operator++(int) noexcept;
246d01320c2SHoward Hinnant    T* operator--(int) volatile noexcept;
247d01320c2SHoward Hinnant    T* operator--(int) noexcept;
248d01320c2SHoward Hinnant    T* operator++() volatile noexcept;
249d01320c2SHoward Hinnant    T* operator++() noexcept;
250d01320c2SHoward Hinnant    T* operator--() volatile noexcept;
251d01320c2SHoward Hinnant    T* operator--() noexcept;
252d01320c2SHoward Hinnant    T* operator+=(ptrdiff_t op) volatile noexcept;
253d01320c2SHoward Hinnant    T* operator+=(ptrdiff_t op) noexcept;
254d01320c2SHoward Hinnant    T* operator-=(ptrdiff_t op) volatile noexcept;
255d01320c2SHoward Hinnant    T* operator-=(ptrdiff_t op) noexcept;
25606aaf0b3SOlivier Giroux
25706aaf0b3SOlivier Giroux    void wait(T*, memory_order = memory_order::seq_cst) const volatile noexcept;
25806aaf0b3SOlivier Giroux    void wait(T*, memory_order = memory_order::seq_cst) const noexcept;
25906aaf0b3SOlivier Giroux    void notify_one() volatile noexcept;
26006aaf0b3SOlivier Giroux    void notify_one() noexcept;
26106aaf0b3SOlivier Giroux    void notify_all() volatile noexcept;
26206aaf0b3SOlivier Giroux    void notify_all() noexcept;
263cd39d413SHoward Hinnant};
264cd39d413SHoward Hinnant
2659847abacSHoward Hinnant
266a76e6987SMark de Wever// [atomics.nonmembers], non-member functions
2679847abacSHoward Hinnanttemplate<class T>
268a76e6987SMark de Wever  bool atomic_is_lock_free(const volatile atomic<T>*) noexcept;
269a76e6987SMark de Wevertemplate<class T>
270a76e6987SMark de Wever  bool atomic_is_lock_free(const atomic<T>*) noexcept;
271a76e6987SMark de Wevertemplate<class T>
272a76e6987SMark de Wever  void atomic_store(volatile atomic<T>*, atomic<T>::value_type) noexcept;
273a76e6987SMark de Wevertemplate<class T>
274a76e6987SMark de Wever  void atomic_store(atomic<T>*, atomic<T>::value_type) noexcept;
275a76e6987SMark de Wevertemplate<class T>
276a76e6987SMark de Wever  void atomic_store_explicit(volatile atomic<T>*, atomic<T>::value_type,
277a76e6987SMark de Wever                             memory_order) noexcept;
278a76e6987SMark de Wevertemplate<class T>
279a76e6987SMark de Wever  void atomic_store_explicit(atomic<T>*, atomic<T>::value_type,
280a76e6987SMark de Wever                             memory_order) noexcept;
281a76e6987SMark de Wevertemplate<class T>
282a76e6987SMark de Wever  T atomic_load(const volatile atomic<T>*) noexcept;
283a76e6987SMark de Wevertemplate<class T>
284a76e6987SMark de Wever  T atomic_load(const atomic<T>*) noexcept;
285a76e6987SMark de Wevertemplate<class T>
286a76e6987SMark de Wever  T atomic_load_explicit(const volatile atomic<T>*, memory_order) noexcept;
287a76e6987SMark de Wevertemplate<class T>
288a76e6987SMark de Wever  T atomic_load_explicit(const atomic<T>*, memory_order) noexcept;
289a76e6987SMark de Wevertemplate<class T>
290a76e6987SMark de Wever  T atomic_exchange(volatile atomic<T>*, atomic<T>::value_type) noexcept;
291a76e6987SMark de Wevertemplate<class T>
292a76e6987SMark de Wever  T atomic_exchange(atomic<T>*, atomic<T>::value_type) noexcept;
293a76e6987SMark de Wevertemplate<class T>
294a76e6987SMark de Wever  T atomic_exchange_explicit(volatile atomic<T>*, atomic<T>::value_type,
295a76e6987SMark de Wever                             memory_order) noexcept;
296a76e6987SMark de Wevertemplate<class T>
297a76e6987SMark de Wever  T atomic_exchange_explicit(atomic<T>*, atomic<T>::value_type,
298a76e6987SMark de Wever                             memory_order) noexcept;
299a76e6987SMark de Wevertemplate<class T>
300a76e6987SMark de Wever  bool atomic_compare_exchange_weak(volatile atomic<T>*, atomic<T>::value_type*,
301a76e6987SMark de Wever                                    atomic<T>::value_type) noexcept;
302a76e6987SMark de Wevertemplate<class T>
303a76e6987SMark de Wever  bool atomic_compare_exchange_weak(atomic<T>*, atomic<T>::value_type*,
304a76e6987SMark de Wever                                    atomic<T>::value_type) noexcept;
305a76e6987SMark de Wevertemplate<class T>
306a76e6987SMark de Wever  bool atomic_compare_exchange_strong(volatile atomic<T>*, atomic<T>::value_type*,
307a76e6987SMark de Wever                                      atomic<T>::value_type) noexcept;
308a76e6987SMark de Wevertemplate<class T>
309a76e6987SMark de Wever  bool atomic_compare_exchange_strong(atomic<T>*, atomic<T>::value_type*,
310a76e6987SMark de Wever                                      atomic<T>::value_type) noexcept;
311a76e6987SMark de Wevertemplate<class T>
312a76e6987SMark de Wever  bool atomic_compare_exchange_weak_explicit(volatile atomic<T>*, atomic<T>::value_type*,
313a76e6987SMark de Wever                                             atomic<T>::value_type,
314a76e6987SMark de Wever                                             memory_order, memory_order) noexcept;
315a76e6987SMark de Wevertemplate<class T>
316a76e6987SMark de Wever  bool atomic_compare_exchange_weak_explicit(atomic<T>*, atomic<T>::value_type*,
317a76e6987SMark de Wever                                             atomic<T>::value_type,
318a76e6987SMark de Wever                                             memory_order, memory_order) noexcept;
319a76e6987SMark de Wevertemplate<class T>
320a76e6987SMark de Wever  bool atomic_compare_exchange_strong_explicit(volatile atomic<T>*, atomic<T>::value_type*,
321a76e6987SMark de Wever                                               atomic<T>::value_type,
322a76e6987SMark de Wever                                               memory_order, memory_order) noexcept;
323a76e6987SMark de Wevertemplate<class T>
324a76e6987SMark de Wever  bool atomic_compare_exchange_strong_explicit(atomic<T>*, atomic<T>::value_type*,
325a76e6987SMark de Wever                                               atomic<T>::value_type,
326a76e6987SMark de Wever                                               memory_order, memory_order) noexcept;
3279847abacSHoward Hinnant
3289847abacSHoward Hinnanttemplate<class T>
329a76e6987SMark de Wever  T atomic_fetch_add(volatile atomic<T>*, atomic<T>::difference_type) noexcept;
330a76e6987SMark de Wevertemplate<class T>
331a76e6987SMark de Wever  T atomic_fetch_add(atomic<T>*, atomic<T>::difference_type) noexcept;
332a76e6987SMark de Wevertemplate<class T>
333a76e6987SMark de Wever  T atomic_fetch_add_explicit(volatile atomic<T>*, atomic<T>::difference_type,
334a76e6987SMark de Wever                              memory_order) noexcept;
335a76e6987SMark de Wevertemplate<class T>
336a76e6987SMark de Wever  T atomic_fetch_add_explicit(atomic<T>*, atomic<T>::difference_type,
337a76e6987SMark de Wever                              memory_order) noexcept;
338a76e6987SMark de Wevertemplate<class T>
339a76e6987SMark de Wever  T atomic_fetch_sub(volatile atomic<T>*, atomic<T>::difference_type) noexcept;
340a76e6987SMark de Wevertemplate<class T>
341a76e6987SMark de Wever  T atomic_fetch_sub(atomic<T>*, atomic<T>::difference_type) noexcept;
342a76e6987SMark de Wevertemplate<class T>
343a76e6987SMark de Wever  T atomic_fetch_sub_explicit(volatile atomic<T>*, atomic<T>::difference_type,
344a76e6987SMark de Wever                              memory_order) noexcept;
345a76e6987SMark de Wevertemplate<class T>
346a76e6987SMark de Wever  T atomic_fetch_sub_explicit(atomic<T>*, atomic<T>::difference_type,
347a76e6987SMark de Wever                              memory_order) noexcept;
348a76e6987SMark de Wevertemplate<class T>
349a76e6987SMark de Wever  T atomic_fetch_and(volatile atomic<T>*, atomic<T>::value_type) noexcept;
350a76e6987SMark de Wevertemplate<class T>
351a76e6987SMark de Wever  T atomic_fetch_and(atomic<T>*, atomic<T>::value_type) noexcept;
352a76e6987SMark de Wevertemplate<class T>
353a76e6987SMark de Wever  T atomic_fetch_and_explicit(volatile atomic<T>*, atomic<T>::value_type,
354a76e6987SMark de Wever                              memory_order) noexcept;
355a76e6987SMark de Wevertemplate<class T>
356a76e6987SMark de Wever  T atomic_fetch_and_explicit(atomic<T>*, atomic<T>::value_type,
357a76e6987SMark de Wever                              memory_order) noexcept;
358a76e6987SMark de Wevertemplate<class T>
359a76e6987SMark de Wever  T atomic_fetch_or(volatile atomic<T>*, atomic<T>::value_type) noexcept;
360a76e6987SMark de Wevertemplate<class T>
361a76e6987SMark de Wever  T atomic_fetch_or(atomic<T>*, atomic<T>::value_type) noexcept;
362a76e6987SMark de Wevertemplate<class T>
363a76e6987SMark de Wever  T atomic_fetch_or_explicit(volatile atomic<T>*, atomic<T>::value_type,
364a76e6987SMark de Wever                             memory_order) noexcept;
365a76e6987SMark de Wevertemplate<class T>
366a76e6987SMark de Wever  T atomic_fetch_or_explicit(atomic<T>*, atomic<T>::value_type,
367a76e6987SMark de Wever                             memory_order) noexcept;
368a76e6987SMark de Wevertemplate<class T>
369a76e6987SMark de Wever  T atomic_fetch_xor(volatile atomic<T>*, atomic<T>::value_type) noexcept;
370a76e6987SMark de Wevertemplate<class T>
371a76e6987SMark de Wever  T atomic_fetch_xor(atomic<T>*, atomic<T>::value_type) noexcept;
372a76e6987SMark de Wevertemplate<class T>
373a76e6987SMark de Wever  T atomic_fetch_xor_explicit(volatile atomic<T>*, atomic<T>::value_type,
374a76e6987SMark de Wever                              memory_order) noexcept;
375a76e6987SMark de Wevertemplate<class T>
376a76e6987SMark de Wever  T atomic_fetch_xor_explicit(atomic<T>*, atomic<T>::value_type,
377a76e6987SMark de Wever                              memory_order) noexcept;
3789847abacSHoward Hinnant
3799847abacSHoward Hinnanttemplate<class T>
380a76e6987SMark de Wever  void atomic_wait(const volatile atomic<T>*, atomic<T>::value_type);
3819847abacSHoward Hinnanttemplate<class T>
382a76e6987SMark de Wever  void atomic_wait(const atomic<T>*, atomic<T>::value_type);
3839847abacSHoward Hinnanttemplate<class T>
384a76e6987SMark de Wever  void atomic_wait_explicit(const volatile atomic<T>*, atomic<T>::value_type,
385a76e6987SMark de Wever                            memory_order);
3869847abacSHoward Hinnanttemplate<class T>
387a76e6987SMark de Wever  void atomic_wait_explicit(const atomic<T>*, atomic<T>::value_type,
388a76e6987SMark de Wever                            memory_order);
3899847abacSHoward Hinnanttemplate<class T>
390a76e6987SMark de Wever  void atomic_notify_one(volatile atomic<T>*);
3919847abacSHoward Hinnanttemplate<class T>
392a76e6987SMark de Wever  void atomic_notify_one(atomic<T>*);
3939847abacSHoward Hinnanttemplate<class T>
394a76e6987SMark de Wever  void atomic_notify_all(volatile atomic<T>*);
3959847abacSHoward Hinnanttemplate<class T>
396a76e6987SMark de Wever  void atomic_notify_all(atomic<T>*);
3979847abacSHoward Hinnant
3989847abacSHoward Hinnant// Atomics for standard typedef types
3999847abacSHoward Hinnant
40011467662SHoward Hinnanttypedef atomic<bool>               atomic_bool;
4019847abacSHoward Hinnanttypedef atomic<char>               atomic_char;
4029847abacSHoward Hinnanttypedef atomic<signed char>        atomic_schar;
4039847abacSHoward Hinnanttypedef atomic<unsigned char>      atomic_uchar;
4049847abacSHoward Hinnanttypedef atomic<short>              atomic_short;
4059847abacSHoward Hinnanttypedef atomic<unsigned short>     atomic_ushort;
4069847abacSHoward Hinnanttypedef atomic<int>                atomic_int;
4079847abacSHoward Hinnanttypedef atomic<unsigned int>       atomic_uint;
4089847abacSHoward Hinnanttypedef atomic<long>               atomic_long;
4099847abacSHoward Hinnanttypedef atomic<unsigned long>      atomic_ulong;
4109847abacSHoward Hinnanttypedef atomic<long long>          atomic_llong;
4119847abacSHoward Hinnanttypedef atomic<unsigned long long> atomic_ullong;
4129c97e4efSMarek Kurdejtypedef atomic<char8_t>            atomic_char8_t; // C++20
4139847abacSHoward Hinnanttypedef atomic<char16_t>           atomic_char16_t;
4149847abacSHoward Hinnanttypedef atomic<char32_t>           atomic_char32_t;
4159847abacSHoward Hinnanttypedef atomic<wchar_t>            atomic_wchar_t;
4169847abacSHoward Hinnant
4179847abacSHoward Hinnanttypedef atomic<int_least8_t>   atomic_int_least8_t;
4189847abacSHoward Hinnanttypedef atomic<uint_least8_t>  atomic_uint_least8_t;
4199847abacSHoward Hinnanttypedef atomic<int_least16_t>  atomic_int_least16_t;
4209847abacSHoward Hinnanttypedef atomic<uint_least16_t> atomic_uint_least16_t;
4219847abacSHoward Hinnanttypedef atomic<int_least32_t>  atomic_int_least32_t;
4229847abacSHoward Hinnanttypedef atomic<uint_least32_t> atomic_uint_least32_t;
4239847abacSHoward Hinnanttypedef atomic<int_least64_t>  atomic_int_least64_t;
4249847abacSHoward Hinnanttypedef atomic<uint_least64_t> atomic_uint_least64_t;
4259847abacSHoward Hinnant
4269847abacSHoward Hinnanttypedef atomic<int_fast8_t>   atomic_int_fast8_t;
4279847abacSHoward Hinnanttypedef atomic<uint_fast8_t>  atomic_uint_fast8_t;
4289847abacSHoward Hinnanttypedef atomic<int_fast16_t>  atomic_int_fast16_t;
4299847abacSHoward Hinnanttypedef atomic<uint_fast16_t> atomic_uint_fast16_t;
4309847abacSHoward Hinnanttypedef atomic<int_fast32_t>  atomic_int_fast32_t;
4319847abacSHoward Hinnanttypedef atomic<uint_fast32_t> atomic_uint_fast32_t;
4329847abacSHoward Hinnanttypedef atomic<int_fast64_t>  atomic_int_fast64_t;
4339847abacSHoward Hinnanttypedef atomic<uint_fast64_t> atomic_uint_fast64_t;
4349847abacSHoward Hinnant
435e766a87bSMarshall Clowtypedef atomic<int8_t>   atomic_int8_t;
436e766a87bSMarshall Clowtypedef atomic<uint8_t>  atomic_uint8_t;
437e766a87bSMarshall Clowtypedef atomic<int16_t>  atomic_int16_t;
438e766a87bSMarshall Clowtypedef atomic<uint16_t> atomic_uint16_t;
439e766a87bSMarshall Clowtypedef atomic<int32_t>  atomic_int32_t;
440e766a87bSMarshall Clowtypedef atomic<uint32_t> atomic_uint32_t;
441e766a87bSMarshall Clowtypedef atomic<int64_t>  atomic_int64_t;
442e766a87bSMarshall Clowtypedef atomic<uint64_t> atomic_uint64_t;
443e766a87bSMarshall Clow
4449847abacSHoward Hinnanttypedef atomic<intptr_t>  atomic_intptr_t;
4459847abacSHoward Hinnanttypedef atomic<uintptr_t> atomic_uintptr_t;
4469847abacSHoward Hinnanttypedef atomic<size_t>    atomic_size_t;
4479847abacSHoward Hinnanttypedef atomic<ptrdiff_t> atomic_ptrdiff_t;
4489847abacSHoward Hinnanttypedef atomic<intmax_t>  atomic_intmax_t;
4499847abacSHoward Hinnanttypedef atomic<uintmax_t> atomic_uintmax_t;
4509847abacSHoward Hinnant
45106aaf0b3SOlivier Giroux// flag type and operations
45206aaf0b3SOlivier Giroux
45306aaf0b3SOlivier Girouxtypedef struct atomic_flag
45406aaf0b3SOlivier Giroux{
45556aac567SRaul Tambre    atomic_flag() noexcept = default; // until C++20
45656aac567SRaul Tambre    constexpr atomic_flag() noexcept; // since C++20
45706aaf0b3SOlivier Giroux    atomic_flag(const atomic_flag&) = delete;
45806aaf0b3SOlivier Giroux    atomic_flag& operator=(const atomic_flag&) = delete;
45906aaf0b3SOlivier Giroux    atomic_flag& operator=(const atomic_flag&) volatile = delete;
46006aaf0b3SOlivier Giroux
46106aaf0b3SOlivier Giroux    bool test(memory_order m = memory_order_seq_cst) volatile noexcept;
46206aaf0b3SOlivier Giroux    bool test(memory_order m = memory_order_seq_cst) noexcept;
46306aaf0b3SOlivier Giroux    bool test_and_set(memory_order m = memory_order_seq_cst) volatile noexcept;
46406aaf0b3SOlivier Giroux    bool test_and_set(memory_order m = memory_order_seq_cst) noexcept;
46506aaf0b3SOlivier Giroux    void clear(memory_order m = memory_order_seq_cst) volatile noexcept;
46606aaf0b3SOlivier Giroux    void clear(memory_order m = memory_order_seq_cst) noexcept;
46706aaf0b3SOlivier Giroux
46806aaf0b3SOlivier Giroux    void wait(bool, memory_order = memory_order::seq_cst) const volatile noexcept;
46906aaf0b3SOlivier Giroux    void wait(bool, memory_order = memory_order::seq_cst) const noexcept;
47006aaf0b3SOlivier Giroux    void notify_one() volatile noexcept;
47106aaf0b3SOlivier Giroux    void notify_one() noexcept;
47206aaf0b3SOlivier Giroux    void notify_all() volatile noexcept;
47306aaf0b3SOlivier Giroux    void notify_all() noexcept;
47406aaf0b3SOlivier Giroux} atomic_flag;
47506aaf0b3SOlivier Giroux
47606aaf0b3SOlivier Girouxbool atomic_flag_test(volatile atomic_flag* obj) noexcept;
47706aaf0b3SOlivier Girouxbool atomic_flag_test(atomic_flag* obj) noexcept;
47806aaf0b3SOlivier Girouxbool atomic_flag_test_explicit(volatile atomic_flag* obj,
47906aaf0b3SOlivier Giroux                               memory_order m) noexcept;
48006aaf0b3SOlivier Girouxbool atomic_flag_test_explicit(atomic_flag* obj, memory_order m) noexcept;
48106aaf0b3SOlivier Girouxbool atomic_flag_test_and_set(volatile atomic_flag* obj) noexcept;
48206aaf0b3SOlivier Girouxbool atomic_flag_test_and_set(atomic_flag* obj) noexcept;
48306aaf0b3SOlivier Girouxbool atomic_flag_test_and_set_explicit(volatile atomic_flag* obj,
48406aaf0b3SOlivier Giroux                                       memory_order m) noexcept;
48506aaf0b3SOlivier Girouxbool atomic_flag_test_and_set_explicit(atomic_flag* obj, memory_order m) noexcept;
48606aaf0b3SOlivier Girouxvoid atomic_flag_clear(volatile atomic_flag* obj) noexcept;
48706aaf0b3SOlivier Girouxvoid atomic_flag_clear(atomic_flag* obj) noexcept;
48806aaf0b3SOlivier Girouxvoid atomic_flag_clear_explicit(volatile atomic_flag* obj, memory_order m) noexcept;
48906aaf0b3SOlivier Girouxvoid atomic_flag_clear_explicit(atomic_flag* obj, memory_order m) noexcept;
49006aaf0b3SOlivier Giroux
49106aaf0b3SOlivier Girouxvoid atomic_wait(const volatile atomic_flag* obj, T old) noexcept;
49206aaf0b3SOlivier Girouxvoid atomic_wait(const atomic_flag* obj, T old) noexcept;
49306aaf0b3SOlivier Girouxvoid atomic_wait_explicit(const volatile atomic_flag* obj, T old, memory_order m) noexcept;
49406aaf0b3SOlivier Girouxvoid atomic_wait_explicit(const atomic_flag* obj, T old, memory_order m) noexcept;
49506aaf0b3SOlivier Girouxvoid atomic_one(volatile atomic_flag* obj) noexcept;
49606aaf0b3SOlivier Girouxvoid atomic_one(atomic_flag* obj) noexcept;
49706aaf0b3SOlivier Girouxvoid atomic_all(volatile atomic_flag* obj) noexcept;
49806aaf0b3SOlivier Girouxvoid atomic_all(atomic_flag* obj) noexcept;
49906aaf0b3SOlivier Giroux
500cd39d413SHoward Hinnant// fences
501cd39d413SHoward Hinnant
502d01320c2SHoward Hinnantvoid atomic_thread_fence(memory_order m) noexcept;
503d01320c2SHoward Hinnantvoid atomic_signal_fence(memory_order m) noexcept;
504cd39d413SHoward Hinnant
50506aaf0b3SOlivier Giroux// deprecated
50606aaf0b3SOlivier Giroux
50706aaf0b3SOlivier Girouxtemplate <class T>
508a76e6987SMark de Wever  void atomic_init(volatile atomic<T>* obj, atomic<T>::value_type desr) noexcept;
50906aaf0b3SOlivier Giroux
51006aaf0b3SOlivier Girouxtemplate <class T>
511a76e6987SMark de Wever  void atomic_init(atomic<T>* obj, atomic<T>::value_type desr) noexcept;
51206aaf0b3SOlivier Giroux
51306aaf0b3SOlivier Giroux#define ATOMIC_VAR_INIT(value) see below
51406aaf0b3SOlivier Giroux
51506aaf0b3SOlivier Giroux#define ATOMIC_FLAG_INIT see below
51606aaf0b3SOlivier Giroux
517cd39d413SHoward Hinnant}  // std
518cd39d413SHoward Hinnant
519cd39d413SHoward Hinnant*/
520cd39d413SHoward Hinnant
521385cc25aSLouis Dionne#include <__assert> // all public C++ headers provide the assertion handler
5222eadbc86SLouis Dionne#include <__availability>
523489637e6SNikolas Klauser#include <__chrono/duration.h>
524bfbd73f8SArthur O'Dwyer#include <__config>
52592832e48SLouis Dionne#include <__thread/poll_with_backoff.h>
526df51be85SLouis Dionne#include <__thread/timed_backoff_policy.h>
5279847abacSHoward Hinnant#include <cstddef>
5289847abacSHoward Hinnant#include <cstdint>
52954fa9ecdSOlivier Giroux#include <cstring>
5309847abacSHoward Hinnant#include <type_traits>
531f56972e2SMarshall Clow#include <version>
532cd39d413SHoward Hinnant
53392832e48SLouis Dionne#ifndef _LIBCPP_HAS_NO_THREADS
53492832e48SLouis Dionne# include <__threading_support>
53592832e48SLouis Dionne#endif
53692832e48SLouis Dionne
537de4a57cbSLouis Dionne#ifndef _LIBCPP_REMOVE_TRANSITIVE_INCLUDES
538de4a57cbSLouis Dionne#  include <chrono>
539de4a57cbSLouis Dionne#endif
540de4a57cbSLouis Dionne
541073458b1SHoward Hinnant#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
542cd39d413SHoward Hinnant#  pragma GCC system_header
543073458b1SHoward Hinnant#endif
544cd39d413SHoward Hinnant
5456de760acSDavide Italiano#ifdef _LIBCPP_HAS_NO_ATOMIC_HEADER
546749adebaSEric Fiselier# error <atomic> is not implemented
547749adebaSEric Fiselier#endif
54885d3a702SVolodymyr Sapsai#ifdef kill_dependency
549586efd52SLouis Dionne# error <atomic> is incompatible with <stdatomic.h> before C++23. Please compile with -std=c++23.
55085d3a702SVolodymyr Sapsai#endif
551b3fcc67fSJonathan Roelofs
552faf2a813SEric Fiselier#define _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) \
553faf2a813SEric Fiselier  _LIBCPP_DIAGNOSE_WARNING(__m == memory_order_consume || \
554faf2a813SEric Fiselier                           __m == memory_order_acquire || \
555faf2a813SEric Fiselier                           __m == memory_order_acq_rel,   \
556faf2a813SEric Fiselier                        "memory order argument to atomic operation is invalid")
557faf2a813SEric Fiselier
558faf2a813SEric Fiselier#define _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) \
559faf2a813SEric Fiselier  _LIBCPP_DIAGNOSE_WARNING(__m == memory_order_release || \
560faf2a813SEric Fiselier                           __m == memory_order_acq_rel,   \
561faf2a813SEric Fiselier                        "memory order argument to atomic operation is invalid")
562faf2a813SEric Fiselier
563faf2a813SEric Fiselier#define _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__m, __f) \
564faf2a813SEric Fiselier  _LIBCPP_DIAGNOSE_WARNING(__f == memory_order_release || \
565faf2a813SEric Fiselier                           __f == memory_order_acq_rel,   \
566faf2a813SEric Fiselier                        "memory order argument to atomic operation is invalid")
567faf2a813SEric Fiselier
568cd39d413SHoward Hinnant_LIBCPP_BEGIN_NAMESPACE_STD
569cd39d413SHoward Hinnant
5700e1586c4SEric Fiselier// Figure out what the underlying type for `memory_order` would be if it were
5710e1586c4SEric Fiselier// declared as an unscoped enum (accounting for -fshort-enums). Use this result
5720e1586c4SEric Fiselier// to pin the underlying type in C++20.
5730e1586c4SEric Fiselierenum __legacy_memory_order {
5740e1586c4SEric Fiselier    __mo_relaxed,
5750e1586c4SEric Fiselier    __mo_consume,
5760e1586c4SEric Fiselier    __mo_acquire,
5770e1586c4SEric Fiselier    __mo_release,
5780e1586c4SEric Fiselier    __mo_acq_rel,
5790e1586c4SEric Fiselier    __mo_seq_cst
5800e1586c4SEric Fiselier};
5810e1586c4SEric Fiselier
5820e1586c4SEric Fiseliertypedef underlying_type<__legacy_memory_order>::type __memory_order_underlying_t;
5830e1586c4SEric Fiselier
5846de760acSDavide Italiano#if _LIBCPP_STD_VER > 17
5856de760acSDavide Italiano
5860e1586c4SEric Fiselierenum class memory_order : __memory_order_underlying_t {
5870e1586c4SEric Fiselier  relaxed = __mo_relaxed,
5880e1586c4SEric Fiselier  consume = __mo_consume,
5890e1586c4SEric Fiselier  acquire = __mo_acquire,
5900e1586c4SEric Fiselier  release = __mo_release,
5910e1586c4SEric Fiselier  acq_rel = __mo_acq_rel,
5920e1586c4SEric Fiselier  seq_cst = __mo_seq_cst
5936de760acSDavide Italiano};
5946de760acSDavide Italiano
5956de760acSDavide Italianoinline constexpr auto memory_order_relaxed = memory_order::relaxed;
5966de760acSDavide Italianoinline constexpr auto memory_order_consume = memory_order::consume;
5976de760acSDavide Italianoinline constexpr auto memory_order_acquire = memory_order::acquire;
5986de760acSDavide Italianoinline constexpr auto memory_order_release = memory_order::release;
5996de760acSDavide Italianoinline constexpr auto memory_order_acq_rel = memory_order::acq_rel;
6006de760acSDavide Italianoinline constexpr auto memory_order_seq_cst = memory_order::seq_cst;
6016de760acSDavide Italiano
6026de760acSDavide Italiano#else
6036de760acSDavide Italiano
6046de760acSDavide Italianotypedef enum memory_order {
6050e1586c4SEric Fiselier  memory_order_relaxed = __mo_relaxed,
6060e1586c4SEric Fiselier  memory_order_consume = __mo_consume,
6070e1586c4SEric Fiselier  memory_order_acquire = __mo_acquire,
6080e1586c4SEric Fiselier  memory_order_release = __mo_release,
6090e1586c4SEric Fiselier  memory_order_acq_rel = __mo_acq_rel,
6100e1586c4SEric Fiselier  memory_order_seq_cst = __mo_seq_cst,
611cfe0b0a1SHoward Hinnant} memory_order;
612cfe0b0a1SHoward Hinnant
6136de760acSDavide Italiano#endif // _LIBCPP_STD_VER > 17
6146de760acSDavide Italiano
61554fa9ecdSOlivier Girouxtemplate <typename _Tp> _LIBCPP_INLINE_VISIBILITY
61654fa9ecdSOlivier Girouxbool __cxx_nonatomic_compare_equal(_Tp const& __lhs, _Tp const& __rhs) {
6173696227cSArthur O'Dwyer    return _VSTD::memcmp(&__lhs, &__rhs, sizeof(_Tp)) == 0;
61854fa9ecdSOlivier Giroux}
61954fa9ecdSOlivier Giroux
6203e3d6c90SEric Fiselierstatic_assert((is_same<underlying_type<memory_order>::type, __memory_order_underlying_t>::value),
6210e1586c4SEric Fiselier  "unexpected underlying type for std::memory_order");
6226de760acSDavide Italiano
6236de760acSDavide Italiano#if defined(_LIBCPP_HAS_GCC_ATOMIC_IMP) || \
6246de760acSDavide Italiano    defined(_LIBCPP_ATOMIC_ONLY_USE_BUILTINS)
6256de760acSDavide Italiano
6266de760acSDavide Italiano// [atomics.types.generic]p1 guarantees _Tp is trivially copyable. Because
6276de760acSDavide Italiano// the default operator= in an object is not volatile, a byte-by-byte copy
6286de760acSDavide Italiano// is required.
6296de760acSDavide Italianotemplate <typename _Tp, typename _Tv> _LIBCPP_INLINE_VISIBILITY
6306de760acSDavide Italianotypename enable_if<is_assignable<_Tp&, _Tv>::value>::type
6316de760acSDavide Italiano__cxx_atomic_assign_volatile(_Tp& __a_value, _Tv const& __val) {
6326de760acSDavide Italiano  __a_value = __val;
6336de760acSDavide Italiano}
6346de760acSDavide Italianotemplate <typename _Tp, typename _Tv> _LIBCPP_INLINE_VISIBILITY
6356de760acSDavide Italianotypename enable_if<is_assignable<_Tp&, _Tv>::value>::type
6366de760acSDavide Italiano__cxx_atomic_assign_volatile(_Tp volatile& __a_value, _Tv volatile const& __val) {
6376de760acSDavide Italiano  volatile char* __to = reinterpret_cast<volatile char*>(&__a_value);
6386de760acSDavide Italiano  volatile char* __end = __to + sizeof(_Tp);
6396de760acSDavide Italiano  volatile const char* __from = reinterpret_cast<volatile const char*>(&__val);
6406de760acSDavide Italiano  while (__to != __end)
6416de760acSDavide Italiano    *__to++ = *__from++;
6426de760acSDavide Italiano}
6436de760acSDavide Italiano
6441061cb6aSDavide Italiano#endif
64521450545SLouis Dionne
6466de760acSDavide Italiano#if defined(_LIBCPP_HAS_GCC_ATOMIC_IMP)
6476de760acSDavide Italiano
6486de760acSDavide Italianotemplate <typename _Tp>
6496de760acSDavide Italianostruct __cxx_atomic_base_impl {
6506de760acSDavide Italiano
651d97b084bSEric Fiselier  _LIBCPP_INLINE_VISIBILITY
652f9980200SEric Fiselier#ifndef _LIBCPP_CXX03_LANG
6536de760acSDavide Italiano    __cxx_atomic_base_impl() _NOEXCEPT = default;
654d97b084bSEric Fiselier#else
6556de760acSDavide Italiano    __cxx_atomic_base_impl() _NOEXCEPT : __a_value() {}
656f9980200SEric Fiselier#endif // _LIBCPP_CXX03_LANG
6576de760acSDavide Italiano  _LIBCPP_CONSTEXPR explicit __cxx_atomic_base_impl(_Tp value) _NOEXCEPT
658092c475eSEric Fiselier    : __a_value(value) {}
65993179005SMarshall Clow  _Tp __a_value;
660502dca7bSDan Albert};
661502dca7bSDan Albert
6626de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY inline _LIBCPP_CONSTEXPR int __to_gcc_order(memory_order __order) {
663502dca7bSDan Albert  // Avoid switch statement to make this a constexpr.
664502dca7bSDan Albert  return __order == memory_order_relaxed ? __ATOMIC_RELAXED:
665502dca7bSDan Albert         (__order == memory_order_acquire ? __ATOMIC_ACQUIRE:
666502dca7bSDan Albert          (__order == memory_order_release ? __ATOMIC_RELEASE:
667502dca7bSDan Albert           (__order == memory_order_seq_cst ? __ATOMIC_SEQ_CST:
668502dca7bSDan Albert            (__order == memory_order_acq_rel ? __ATOMIC_ACQ_REL:
669502dca7bSDan Albert              __ATOMIC_CONSUME))));
670502dca7bSDan Albert}
671502dca7bSDan Albert
6726de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY inline _LIBCPP_CONSTEXPR int __to_gcc_failure_order(memory_order __order) {
673872bad5aSDan Albert  // Avoid switch statement to make this a constexpr.
674872bad5aSDan Albert  return __order == memory_order_relaxed ? __ATOMIC_RELAXED:
675872bad5aSDan Albert         (__order == memory_order_acquire ? __ATOMIC_ACQUIRE:
676872bad5aSDan Albert          (__order == memory_order_release ? __ATOMIC_RELAXED:
677872bad5aSDan Albert           (__order == memory_order_seq_cst ? __ATOMIC_SEQ_CST:
678872bad5aSDan Albert            (__order == memory_order_acq_rel ? __ATOMIC_ACQUIRE:
679872bad5aSDan Albert              __ATOMIC_CONSUME))));
680872bad5aSDan Albert}
681872bad5aSDan Albert
6826de760acSDavide Italianotemplate <typename _Tp>
6836de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
6846de760acSDavide Italianovoid __cxx_atomic_init(volatile __cxx_atomic_base_impl<_Tp>* __a,  _Tp __val) {
6856de760acSDavide Italiano  __cxx_atomic_assign_volatile(__a->__a_value, __val);
6866de760acSDavide Italiano}
687502dca7bSDan Albert
688502dca7bSDan Alberttemplate <typename _Tp>
6896de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
6906de760acSDavide Italianovoid __cxx_atomic_init(__cxx_atomic_base_impl<_Tp>* __a,  _Tp __val) {
691502dca7bSDan Albert  __a->__a_value = __val;
692502dca7bSDan Albert}
693502dca7bSDan Albert
6946de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY inline
6956de760acSDavide Italianovoid __cxx_atomic_thread_fence(memory_order __order) {
6966de760acSDavide Italiano  __atomic_thread_fence(__to_gcc_order(__order));
697502dca7bSDan Albert}
6986de760acSDavide Italiano
6996de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY inline
7006de760acSDavide Italianovoid __cxx_atomic_signal_fence(memory_order __order) {
7016de760acSDavide Italiano  __atomic_signal_fence(__to_gcc_order(__order));
702502dca7bSDan Albert}
703502dca7bSDan Albert
704502dca7bSDan Alberttemplate <typename _Tp>
7056de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
7066de760acSDavide Italianovoid __cxx_atomic_store(volatile __cxx_atomic_base_impl<_Tp>* __a,  _Tp __val,
707f764dbd0SJF Bastien                        memory_order __order) {
708872bad5aSDan Albert  __atomic_store(&__a->__a_value, &__val,
7096de760acSDavide Italiano                 __to_gcc_order(__order));
710502dca7bSDan Albert}
711502dca7bSDan Albert
712502dca7bSDan Alberttemplate <typename _Tp>
7136de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
7146de760acSDavide Italianovoid __cxx_atomic_store(__cxx_atomic_base_impl<_Tp>* __a,  _Tp __val,
7156de760acSDavide Italiano                        memory_order __order) {
7166de760acSDavide Italiano  __atomic_store(&__a->__a_value, &__val,
7176de760acSDavide Italiano                 __to_gcc_order(__order));
7186de760acSDavide Italiano}
7196de760acSDavide Italiano
7206de760acSDavide Italianotemplate <typename _Tp>
7216de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
7226de760acSDavide Italiano_Tp __cxx_atomic_load(const volatile __cxx_atomic_base_impl<_Tp>* __a,
723f764dbd0SJF Bastien                      memory_order __order) {
724502dca7bSDan Albert  _Tp __ret;
725502dca7bSDan Albert  __atomic_load(&__a->__a_value, &__ret,
7266de760acSDavide Italiano                __to_gcc_order(__order));
727502dca7bSDan Albert  return __ret;
728502dca7bSDan Albert}
729502dca7bSDan Albert
730502dca7bSDan Alberttemplate <typename _Tp>
7316de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
7326de760acSDavide Italiano_Tp __cxx_atomic_load(const __cxx_atomic_base_impl<_Tp>* __a, memory_order __order) {
733502dca7bSDan Albert  _Tp __ret;
734502dca7bSDan Albert  __atomic_load(&__a->__a_value, &__ret,
7356de760acSDavide Italiano                __to_gcc_order(__order));
736502dca7bSDan Albert  return __ret;
737502dca7bSDan Albert}
738502dca7bSDan Albert
739502dca7bSDan Alberttemplate <typename _Tp>
7406de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
7416de760acSDavide Italiano_Tp __cxx_atomic_exchange(volatile __cxx_atomic_base_impl<_Tp>* __a,
742f764dbd0SJF Bastien                          _Tp __value, memory_order __order) {
743502dca7bSDan Albert  _Tp __ret;
744502dca7bSDan Albert  __atomic_exchange(&__a->__a_value, &__value, &__ret,
7456de760acSDavide Italiano                    __to_gcc_order(__order));
746502dca7bSDan Albert  return __ret;
747502dca7bSDan Albert}
748502dca7bSDan Albert
749502dca7bSDan Alberttemplate <typename _Tp>
7506de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
7516de760acSDavide Italiano_Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp>* __a, _Tp __value,
752f764dbd0SJF Bastien                          memory_order __order) {
753502dca7bSDan Albert  _Tp __ret;
754502dca7bSDan Albert  __atomic_exchange(&__a->__a_value, &__value, &__ret,
7556de760acSDavide Italiano                    __to_gcc_order(__order));
756502dca7bSDan Albert  return __ret;
757502dca7bSDan Albert}
758502dca7bSDan Albert
759502dca7bSDan Alberttemplate <typename _Tp>
7606de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
7616de760acSDavide Italianobool __cxx_atomic_compare_exchange_strong(
7626de760acSDavide Italiano    volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value,
763f764dbd0SJF Bastien    memory_order __success, memory_order __failure) {
764502dca7bSDan Albert  return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
765502dca7bSDan Albert                                   false,
7666de760acSDavide Italiano                                   __to_gcc_order(__success),
7676de760acSDavide Italiano                                   __to_gcc_failure_order(__failure));
768502dca7bSDan Albert}
769502dca7bSDan Albert
770502dca7bSDan Alberttemplate <typename _Tp>
7716de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
7726de760acSDavide Italianobool __cxx_atomic_compare_exchange_strong(
7736de760acSDavide Italiano    __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success,
774f764dbd0SJF Bastien    memory_order __failure) {
775502dca7bSDan Albert  return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
776502dca7bSDan Albert                                   false,
7776de760acSDavide Italiano                                   __to_gcc_order(__success),
7786de760acSDavide Italiano                                   __to_gcc_failure_order(__failure));
779502dca7bSDan Albert}
780502dca7bSDan Albert
781502dca7bSDan Alberttemplate <typename _Tp>
7826de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
7836de760acSDavide Italianobool __cxx_atomic_compare_exchange_weak(
7846de760acSDavide Italiano    volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value,
785f764dbd0SJF Bastien    memory_order __success, memory_order __failure) {
786502dca7bSDan Albert  return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
787502dca7bSDan Albert                                   true,
7886de760acSDavide Italiano                                   __to_gcc_order(__success),
7896de760acSDavide Italiano                                   __to_gcc_failure_order(__failure));
790502dca7bSDan Albert}
791502dca7bSDan Albert
792502dca7bSDan Alberttemplate <typename _Tp>
7936de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
7946de760acSDavide Italianobool __cxx_atomic_compare_exchange_weak(
7956de760acSDavide Italiano    __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success,
796f764dbd0SJF Bastien    memory_order __failure) {
797502dca7bSDan Albert  return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
798502dca7bSDan Albert                                   true,
7996de760acSDavide Italiano                                   __to_gcc_order(__success),
8006de760acSDavide Italiano                                   __to_gcc_failure_order(__failure));
801502dca7bSDan Albert}
802502dca7bSDan Albert
803502dca7bSDan Alberttemplate <typename _Tp>
804502dca7bSDan Albertstruct __skip_amt { enum {value = 1}; };
805502dca7bSDan Albert
806502dca7bSDan Alberttemplate <typename _Tp>
807502dca7bSDan Albertstruct __skip_amt<_Tp*> { enum {value = sizeof(_Tp)}; };
808502dca7bSDan Albert
809502dca7bSDan Albert// FIXME: Haven't figured out what the spec says about using arrays with
810502dca7bSDan Albert// atomic_fetch_add. Force a failure rather than creating bad behavior.
811502dca7bSDan Alberttemplate <typename _Tp>
812502dca7bSDan Albertstruct __skip_amt<_Tp[]> { };
813502dca7bSDan Alberttemplate <typename _Tp, int n>
814502dca7bSDan Albertstruct __skip_amt<_Tp[n]> { };
815502dca7bSDan Albert
816502dca7bSDan Alberttemplate <typename _Tp, typename _Td>
8176de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
8186de760acSDavide Italiano_Tp __cxx_atomic_fetch_add(volatile __cxx_atomic_base_impl<_Tp>* __a,
819f764dbd0SJF Bastien                           _Td __delta, memory_order __order) {
820502dca7bSDan Albert  return __atomic_fetch_add(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
8216de760acSDavide Italiano                            __to_gcc_order(__order));
822502dca7bSDan Albert}
823502dca7bSDan Albert
824502dca7bSDan Alberttemplate <typename _Tp, typename _Td>
8256de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
8266de760acSDavide Italiano_Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp>* __a, _Td __delta,
827f764dbd0SJF Bastien                           memory_order __order) {
828502dca7bSDan Albert  return __atomic_fetch_add(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
8296de760acSDavide Italiano                            __to_gcc_order(__order));
830502dca7bSDan Albert}
831502dca7bSDan Albert
832502dca7bSDan Alberttemplate <typename _Tp, typename _Td>
8336de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
8346de760acSDavide Italiano_Tp __cxx_atomic_fetch_sub(volatile __cxx_atomic_base_impl<_Tp>* __a,
835f764dbd0SJF Bastien                           _Td __delta, memory_order __order) {
836502dca7bSDan Albert  return __atomic_fetch_sub(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
8376de760acSDavide Italiano                            __to_gcc_order(__order));
838502dca7bSDan Albert}
839502dca7bSDan Albert
840502dca7bSDan Alberttemplate <typename _Tp, typename _Td>
8416de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
8426de760acSDavide Italiano_Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp>* __a, _Td __delta,
843f764dbd0SJF Bastien                           memory_order __order) {
844502dca7bSDan Albert  return __atomic_fetch_sub(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
8456de760acSDavide Italiano                            __to_gcc_order(__order));
846502dca7bSDan Albert}
847502dca7bSDan Albert
848502dca7bSDan Alberttemplate <typename _Tp>
8496de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
8506de760acSDavide Italiano_Tp __cxx_atomic_fetch_and(volatile __cxx_atomic_base_impl<_Tp>* __a,
851f764dbd0SJF Bastien                           _Tp __pattern, memory_order __order) {
852502dca7bSDan Albert  return __atomic_fetch_and(&__a->__a_value, __pattern,
8536de760acSDavide Italiano                            __to_gcc_order(__order));
854502dca7bSDan Albert}
855502dca7bSDan Albert
856502dca7bSDan Alberttemplate <typename _Tp>
8576de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
8586de760acSDavide Italiano_Tp __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp>* __a,
859f764dbd0SJF Bastien                           _Tp __pattern, memory_order __order) {
860502dca7bSDan Albert  return __atomic_fetch_and(&__a->__a_value, __pattern,
8616de760acSDavide Italiano                            __to_gcc_order(__order));
862502dca7bSDan Albert}
863502dca7bSDan Albert
864502dca7bSDan Alberttemplate <typename _Tp>
8656de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
8666de760acSDavide Italiano_Tp __cxx_atomic_fetch_or(volatile __cxx_atomic_base_impl<_Tp>* __a,
867f764dbd0SJF Bastien                          _Tp __pattern, memory_order __order) {
868502dca7bSDan Albert  return __atomic_fetch_or(&__a->__a_value, __pattern,
8696de760acSDavide Italiano                           __to_gcc_order(__order));
870502dca7bSDan Albert}
871502dca7bSDan Albert
872502dca7bSDan Alberttemplate <typename _Tp>
8736de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
8746de760acSDavide Italiano_Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern,
875f764dbd0SJF Bastien                          memory_order __order) {
876502dca7bSDan Albert  return __atomic_fetch_or(&__a->__a_value, __pattern,
8776de760acSDavide Italiano                           __to_gcc_order(__order));
878502dca7bSDan Albert}
879502dca7bSDan Albert
880502dca7bSDan Alberttemplate <typename _Tp>
8816de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
8826de760acSDavide Italiano_Tp __cxx_atomic_fetch_xor(volatile __cxx_atomic_base_impl<_Tp>* __a,
883f764dbd0SJF Bastien                           _Tp __pattern, memory_order __order) {
884502dca7bSDan Albert  return __atomic_fetch_xor(&__a->__a_value, __pattern,
8856de760acSDavide Italiano                            __to_gcc_order(__order));
886502dca7bSDan Albert}
887502dca7bSDan Albert
888502dca7bSDan Alberttemplate <typename _Tp>
8896de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
8906de760acSDavide Italiano_Tp __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern,
891f764dbd0SJF Bastien                           memory_order __order) {
892502dca7bSDan Albert  return __atomic_fetch_xor(&__a->__a_value, __pattern,
8936de760acSDavide Italiano                            __to_gcc_order(__order));
894502dca7bSDan Albert}
8956de760acSDavide Italiano
8966de760acSDavide Italiano#define __cxx_atomic_is_lock_free(__s) __atomic_is_lock_free(__s, 0)
8976de760acSDavide Italiano
8986de760acSDavide Italiano#elif defined(_LIBCPP_HAS_C_ATOMIC_IMP)
8996de760acSDavide Italiano
9006de760acSDavide Italianotemplate <typename _Tp>
9016de760acSDavide Italianostruct __cxx_atomic_base_impl {
9026de760acSDavide Italiano
9036de760acSDavide Italiano  _LIBCPP_INLINE_VISIBILITY
9046de760acSDavide Italiano#ifndef _LIBCPP_CXX03_LANG
9056de760acSDavide Italiano    __cxx_atomic_base_impl() _NOEXCEPT = default;
9066de760acSDavide Italiano#else
9076de760acSDavide Italiano    __cxx_atomic_base_impl() _NOEXCEPT : __a_value() {}
9086de760acSDavide Italiano#endif // _LIBCPP_CXX03_LANG
909b48c5010SNikolas Klauser  _LIBCPP_CONSTEXPR explicit __cxx_atomic_base_impl(_Tp __value) _NOEXCEPT
910b48c5010SNikolas Klauser    : __a_value(__value) {}
911801f6a49SLouis Dionne  _LIBCPP_DISABLE_EXTENSION_WARNING _Atomic(_Tp) __a_value;
9126de760acSDavide Italiano};
9136de760acSDavide Italiano
9146de760acSDavide Italiano#define __cxx_atomic_is_lock_free(__s) __c11_atomic_is_lock_free(__s)
9156de760acSDavide Italiano
9166de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY inline
917cf92a1f6SEric Fiseliervoid __cxx_atomic_thread_fence(memory_order __order) _NOEXCEPT {
9186de760acSDavide Italiano    __c11_atomic_thread_fence(static_cast<__memory_order_underlying_t>(__order));
9196de760acSDavide Italiano}
9206de760acSDavide Italiano
9216de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY inline
922cf92a1f6SEric Fiseliervoid __cxx_atomic_signal_fence(memory_order __order) _NOEXCEPT {
9236de760acSDavide Italiano    __c11_atomic_signal_fence(static_cast<__memory_order_underlying_t>(__order));
9246de760acSDavide Italiano}
925502dca7bSDan Albert
926cfe0b0a1SHoward Hinnanttemplate<class _Tp>
9276de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
928cf92a1f6SEric Fiseliervoid __cxx_atomic_init(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __val) _NOEXCEPT {
9296de760acSDavide Italiano    __c11_atomic_init(&__a->__a_value, __val);
9306de760acSDavide Italiano}
9316de760acSDavide Italianotemplate<class _Tp>
9326de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
933cf92a1f6SEric Fiseliervoid __cxx_atomic_init(__cxx_atomic_base_impl<_Tp> * __a, _Tp __val) _NOEXCEPT {
9346de760acSDavide Italiano    __c11_atomic_init(&__a->__a_value, __val);
9356de760acSDavide Italiano}
9366de760acSDavide Italiano
9376de760acSDavide Italianotemplate<class _Tp>
9386de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
939cf92a1f6SEric Fiseliervoid __cxx_atomic_store(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __val, memory_order __order) _NOEXCEPT {
9406de760acSDavide Italiano    __c11_atomic_store(&__a->__a_value, __val, static_cast<__memory_order_underlying_t>(__order));
9416de760acSDavide Italiano}
9426de760acSDavide Italianotemplate<class _Tp>
9436de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
944cf92a1f6SEric Fiseliervoid __cxx_atomic_store(__cxx_atomic_base_impl<_Tp> * __a, _Tp __val, memory_order __order) _NOEXCEPT {
9456de760acSDavide Italiano    __c11_atomic_store(&__a->__a_value, __val, static_cast<__memory_order_underlying_t>(__order));
9466de760acSDavide Italiano}
9476de760acSDavide Italiano
9486de760acSDavide Italianotemplate<class _Tp>
9496de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
950cf92a1f6SEric Fiselier_Tp __cxx_atomic_load(__cxx_atomic_base_impl<_Tp> const volatile* __a, memory_order __order) _NOEXCEPT {
9516de760acSDavide Italiano    using __ptr_type = typename remove_const<decltype(__a->__a_value)>::type*;
9526de760acSDavide Italiano    return __c11_atomic_load(const_cast<__ptr_type>(&__a->__a_value), static_cast<__memory_order_underlying_t>(__order));
9536de760acSDavide Italiano}
9546de760acSDavide Italianotemplate<class _Tp>
9556de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
956cf92a1f6SEric Fiselier_Tp __cxx_atomic_load(__cxx_atomic_base_impl<_Tp> const* __a, memory_order __order) _NOEXCEPT {
9576de760acSDavide Italiano    using __ptr_type = typename remove_const<decltype(__a->__a_value)>::type*;
9586de760acSDavide Italiano    return __c11_atomic_load(const_cast<__ptr_type>(&__a->__a_value), static_cast<__memory_order_underlying_t>(__order));
9596de760acSDavide Italiano}
9606de760acSDavide Italiano
9616de760acSDavide Italianotemplate<class _Tp>
9626de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
963cf92a1f6SEric Fiselier_Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __value, memory_order __order) _NOEXCEPT {
9646de760acSDavide Italiano    return __c11_atomic_exchange(&__a->__a_value, __value, static_cast<__memory_order_underlying_t>(__order));
9656de760acSDavide Italiano}
9666de760acSDavide Italianotemplate<class _Tp>
9676de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
968cf92a1f6SEric Fiselier_Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp> * __a, _Tp __value, memory_order __order) _NOEXCEPT {
9696de760acSDavide Italiano    return __c11_atomic_exchange(&__a->__a_value, __value, static_cast<__memory_order_underlying_t>(__order));
9706de760acSDavide Italiano}
9716de760acSDavide Italiano
9726d33362dSJordan Rupprecht_LIBCPP_INLINE_VISIBILITY inline _LIBCPP_CONSTEXPR memory_order __to_failure_order(memory_order __order) {
9736d33362dSJordan Rupprecht  // Avoid switch statement to make this a constexpr.
9746d33362dSJordan Rupprecht  return __order == memory_order_release ? memory_order_relaxed:
9756d33362dSJordan Rupprecht         (__order == memory_order_acq_rel ? memory_order_acquire:
9766d33362dSJordan Rupprecht             __order);
9776d33362dSJordan Rupprecht}
9786d33362dSJordan Rupprecht
9796de760acSDavide Italianotemplate<class _Tp>
9806de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
981cf92a1f6SEric Fiselierbool __cxx_atomic_compare_exchange_strong(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT {
9826d33362dSJordan Rupprecht    return __c11_atomic_compare_exchange_strong(&__a->__a_value, __expected, __value, static_cast<__memory_order_underlying_t>(__success), static_cast<__memory_order_underlying_t>(__to_failure_order(__failure)));
9836de760acSDavide Italiano}
9846de760acSDavide Italianotemplate<class _Tp>
9856de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
986cf92a1f6SEric Fiselierbool __cxx_atomic_compare_exchange_strong(__cxx_atomic_base_impl<_Tp> * __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT {
9876d33362dSJordan Rupprecht    return __c11_atomic_compare_exchange_strong(&__a->__a_value, __expected, __value, static_cast<__memory_order_underlying_t>(__success), static_cast<__memory_order_underlying_t>(__to_failure_order(__failure)));
9886de760acSDavide Italiano}
9896de760acSDavide Italiano
9906de760acSDavide Italianotemplate<class _Tp>
9916de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
992cf92a1f6SEric Fiselierbool __cxx_atomic_compare_exchange_weak(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT {
9936d33362dSJordan Rupprecht    return __c11_atomic_compare_exchange_weak(&__a->__a_value, __expected, __value, static_cast<__memory_order_underlying_t>(__success), static_cast<__memory_order_underlying_t>(__to_failure_order(__failure)));
9946de760acSDavide Italiano}
9956de760acSDavide Italianotemplate<class _Tp>
9966de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
997cf92a1f6SEric Fiselierbool __cxx_atomic_compare_exchange_weak(__cxx_atomic_base_impl<_Tp> * __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT {
9986d33362dSJordan Rupprecht    return __c11_atomic_compare_exchange_weak(&__a->__a_value, __expected, __value,  static_cast<__memory_order_underlying_t>(__success), static_cast<__memory_order_underlying_t>(__to_failure_order(__failure)));
9996de760acSDavide Italiano}
10006de760acSDavide Italiano
10016de760acSDavide Italianotemplate<class _Tp>
10026de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
1003cf92a1f6SEric Fiselier_Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __delta, memory_order __order) _NOEXCEPT {
10046de760acSDavide Italiano    return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
10056de760acSDavide Italiano}
10066de760acSDavide Italianotemplate<class _Tp>
10076de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
1008cf92a1f6SEric Fiselier_Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp> * __a, _Tp __delta, memory_order __order) _NOEXCEPT {
10096de760acSDavide Italiano    return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
10106de760acSDavide Italiano}
10116de760acSDavide Italiano
10126de760acSDavide Italianotemplate<class _Tp>
10136de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
1014cf92a1f6SEric Fiselier_Tp* __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp*> volatile* __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT {
10156de760acSDavide Italiano    return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
10166de760acSDavide Italiano}
10176de760acSDavide Italianotemplate<class _Tp>
10186de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
1019cf92a1f6SEric Fiselier_Tp* __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp*> * __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT {
10206de760acSDavide Italiano    return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
10216de760acSDavide Italiano}
10226de760acSDavide Italiano
10236de760acSDavide Italianotemplate<class _Tp>
10246de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
1025cf92a1f6SEric Fiselier_Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __delta, memory_order __order) _NOEXCEPT {
10266de760acSDavide Italiano    return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
10276de760acSDavide Italiano}
10286de760acSDavide Italianotemplate<class _Tp>
10296de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
1030cf92a1f6SEric Fiselier_Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp> * __a, _Tp __delta, memory_order __order) _NOEXCEPT {
10316de760acSDavide Italiano    return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
10326de760acSDavide Italiano}
10336de760acSDavide Italianotemplate<class _Tp>
10346de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
1035cf92a1f6SEric Fiselier_Tp* __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp*> volatile* __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT {
10366de760acSDavide Italiano    return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
10376de760acSDavide Italiano}
10386de760acSDavide Italianotemplate<class _Tp>
10396de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
1040cf92a1f6SEric Fiselier_Tp* __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp*> * __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT {
10416de760acSDavide Italiano    return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
10426de760acSDavide Italiano}
10436de760acSDavide Italiano
10446de760acSDavide Italianotemplate<class _Tp>
10456de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
1046cf92a1f6SEric Fiselier_Tp __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
10476de760acSDavide Italiano    return __c11_atomic_fetch_and(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
10486de760acSDavide Italiano}
10496de760acSDavide Italianotemplate<class _Tp>
10506de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
1051cf92a1f6SEric Fiselier_Tp __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
10526de760acSDavide Italiano    return __c11_atomic_fetch_and(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
10536de760acSDavide Italiano}
10546de760acSDavide Italiano
10556de760acSDavide Italianotemplate<class _Tp>
10566de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
1057cf92a1f6SEric Fiselier_Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
10586de760acSDavide Italiano    return __c11_atomic_fetch_or(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
10596de760acSDavide Italiano}
10606de760acSDavide Italianotemplate<class _Tp>
10616de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
1062cf92a1f6SEric Fiselier_Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
10636de760acSDavide Italiano    return __c11_atomic_fetch_or(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
10646de760acSDavide Italiano}
10656de760acSDavide Italiano
10666de760acSDavide Italianotemplate<class _Tp>
10676de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
1068cf92a1f6SEric Fiselier_Tp __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
10696de760acSDavide Italiano    return __c11_atomic_fetch_xor(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
10706de760acSDavide Italiano}
10716de760acSDavide Italianotemplate<class _Tp>
10726de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
1073cf92a1f6SEric Fiselier_Tp __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
10746de760acSDavide Italiano    return __c11_atomic_fetch_xor(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
10756de760acSDavide Italiano}
10766de760acSDavide Italiano
10776de760acSDavide Italiano#endif // _LIBCPP_HAS_GCC_ATOMIC_IMP, _LIBCPP_HAS_C_ATOMIC_IMP
10786de760acSDavide Italiano
10796de760acSDavide Italianotemplate <class _Tp>
10806de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
10816de760acSDavide Italiano_Tp kill_dependency(_Tp __y) _NOEXCEPT
1082cfe0b0a1SHoward Hinnant{
1083cfe0b0a1SHoward Hinnant    return __y;
1084cfe0b0a1SHoward Hinnant}
1085cd39d413SHoward Hinnant
1086c4112254SEric Fiselier#if defined(__CLANG_ATOMIC_BOOL_LOCK_FREE)
1087c4112254SEric Fiselier# define ATOMIC_BOOL_LOCK_FREE      __CLANG_ATOMIC_BOOL_LOCK_FREE
1088c4112254SEric Fiselier# define ATOMIC_CHAR_LOCK_FREE      __CLANG_ATOMIC_CHAR_LOCK_FREE
10895c40c994SArthur O'Dwyer#ifndef _LIBCPP_HAS_NO_CHAR8_T
10909c97e4efSMarek Kurdej# define ATOMIC_CHAR8_T_LOCK_FREE   __CLANG_ATOMIC_CHAR8_T_LOCK_FREE
10919c97e4efSMarek Kurdej#endif
1092c4112254SEric Fiselier# define ATOMIC_CHAR16_T_LOCK_FREE  __CLANG_ATOMIC_CHAR16_T_LOCK_FREE
1093c4112254SEric Fiselier# define ATOMIC_CHAR32_T_LOCK_FREE  __CLANG_ATOMIC_CHAR32_T_LOCK_FREE
1094c4112254SEric Fiselier# define ATOMIC_WCHAR_T_LOCK_FREE   __CLANG_ATOMIC_WCHAR_T_LOCK_FREE
1095c4112254SEric Fiselier# define ATOMIC_SHORT_LOCK_FREE     __CLANG_ATOMIC_SHORT_LOCK_FREE
1096c4112254SEric Fiselier# define ATOMIC_INT_LOCK_FREE       __CLANG_ATOMIC_INT_LOCK_FREE
1097c4112254SEric Fiselier# define ATOMIC_LONG_LOCK_FREE      __CLANG_ATOMIC_LONG_LOCK_FREE
1098c4112254SEric Fiselier# define ATOMIC_LLONG_LOCK_FREE     __CLANG_ATOMIC_LLONG_LOCK_FREE
1099c4112254SEric Fiselier# define ATOMIC_POINTER_LOCK_FREE   __CLANG_ATOMIC_POINTER_LOCK_FREE
11006de760acSDavide Italiano#elif defined(__GCC_ATOMIC_BOOL_LOCK_FREE)
1101b95ee819SJF Bastien# define ATOMIC_BOOL_LOCK_FREE      __GCC_ATOMIC_BOOL_LOCK_FREE
1102b95ee819SJF Bastien# define ATOMIC_CHAR_LOCK_FREE      __GCC_ATOMIC_CHAR_LOCK_FREE
11035c40c994SArthur O'Dwyer#ifndef _LIBCPP_HAS_NO_CHAR8_T
11049c97e4efSMarek Kurdej# define ATOMIC_CHAR8_T_LOCK_FREE   __GCC_ATOMIC_CHAR8_T_LOCK_FREE
11059c97e4efSMarek Kurdej#endif
1106b95ee819SJF Bastien# define ATOMIC_CHAR16_T_LOCK_FREE  __GCC_ATOMIC_CHAR16_T_LOCK_FREE
1107b95ee819SJF Bastien# define ATOMIC_CHAR32_T_LOCK_FREE  __GCC_ATOMIC_CHAR32_T_LOCK_FREE
1108b95ee819SJF Bastien# define ATOMIC_WCHAR_T_LOCK_FREE   __GCC_ATOMIC_WCHAR_T_LOCK_FREE
1109b95ee819SJF Bastien# define ATOMIC_SHORT_LOCK_FREE     __GCC_ATOMIC_SHORT_LOCK_FREE
1110b95ee819SJF Bastien# define ATOMIC_INT_LOCK_FREE       __GCC_ATOMIC_INT_LOCK_FREE
1111b95ee819SJF Bastien# define ATOMIC_LONG_LOCK_FREE      __GCC_ATOMIC_LONG_LOCK_FREE
1112b95ee819SJF Bastien# define ATOMIC_LLONG_LOCK_FREE     __GCC_ATOMIC_LLONG_LOCK_FREE
1113b95ee819SJF Bastien# define ATOMIC_POINTER_LOCK_FREE   __GCC_ATOMIC_POINTER_LOCK_FREE
1114c4112254SEric Fiselier#endif
1115b95ee819SJF Bastien
1116*d64394b8SLouis Dionnetemplate <class _Tp>
1117*d64394b8SLouis Dionnestruct __libcpp_is_always_lock_free {
1118*d64394b8SLouis Dionne  // __atomic_always_lock_free is available in all Standard modes
1119*d64394b8SLouis Dionne  static const bool __value = __atomic_always_lock_free(sizeof(_Tp), 0);
1120*d64394b8SLouis Dionne};
1121*d64394b8SLouis Dionne
11226de760acSDavide Italiano#ifdef _LIBCPP_ATOMIC_ONLY_USE_BUILTINS
11236de760acSDavide Italiano
11246de760acSDavide Italianotemplate<typename _Tp>
11256de760acSDavide Italianostruct __cxx_atomic_lock_impl {
11266de760acSDavide Italiano
11276de760acSDavide Italiano  _LIBCPP_INLINE_VISIBILITY
11286de760acSDavide Italiano  __cxx_atomic_lock_impl() _NOEXCEPT
11296de760acSDavide Italiano    : __a_value(), __a_lock(0) {}
11306de760acSDavide Italiano  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR explicit
11316de760acSDavide Italiano  __cxx_atomic_lock_impl(_Tp value) _NOEXCEPT
11326de760acSDavide Italiano    : __a_value(value), __a_lock(0) {}
11336de760acSDavide Italiano
11346de760acSDavide Italiano  _Tp __a_value;
11356de760acSDavide Italiano  mutable __cxx_atomic_base_impl<_LIBCPP_ATOMIC_FLAG_TYPE> __a_lock;
11366de760acSDavide Italiano
11376de760acSDavide Italiano  _LIBCPP_INLINE_VISIBILITY void __lock() const volatile {
11386de760acSDavide Italiano    while(1 == __cxx_atomic_exchange(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(true), memory_order_acquire))
11396de760acSDavide Italiano        /*spin*/;
11406de760acSDavide Italiano  }
11416de760acSDavide Italiano  _LIBCPP_INLINE_VISIBILITY void __lock() const {
11426de760acSDavide Italiano    while(1 == __cxx_atomic_exchange(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(true), memory_order_acquire))
11436de760acSDavide Italiano        /*spin*/;
11446de760acSDavide Italiano  }
11456de760acSDavide Italiano  _LIBCPP_INLINE_VISIBILITY void __unlock() const volatile {
11466de760acSDavide Italiano    __cxx_atomic_store(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(false), memory_order_release);
11476de760acSDavide Italiano  }
11486de760acSDavide Italiano  _LIBCPP_INLINE_VISIBILITY void __unlock() const {
11496de760acSDavide Italiano    __cxx_atomic_store(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(false), memory_order_release);
11506de760acSDavide Italiano  }
11516de760acSDavide Italiano  _LIBCPP_INLINE_VISIBILITY _Tp __read() const volatile {
11526de760acSDavide Italiano    __lock();
11536de760acSDavide Italiano    _Tp __old;
11546de760acSDavide Italiano    __cxx_atomic_assign_volatile(__old, __a_value);
11556de760acSDavide Italiano    __unlock();
11566de760acSDavide Italiano    return __old;
11576de760acSDavide Italiano  }
11586de760acSDavide Italiano  _LIBCPP_INLINE_VISIBILITY _Tp __read() const {
11596de760acSDavide Italiano    __lock();
11606de760acSDavide Italiano    _Tp __old = __a_value;
11616de760acSDavide Italiano    __unlock();
11626de760acSDavide Italiano    return __old;
11636de760acSDavide Italiano  }
11646de760acSDavide Italiano};
11656de760acSDavide Italiano
11666de760acSDavide Italianotemplate <typename _Tp>
11676de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
11686de760acSDavide Italianovoid __cxx_atomic_init(volatile __cxx_atomic_lock_impl<_Tp>* __a,  _Tp __val) {
11696de760acSDavide Italiano  __cxx_atomic_assign_volatile(__a->__a_value, __val);
11706de760acSDavide Italiano}
11716de760acSDavide Italianotemplate <typename _Tp>
11726de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
11736de760acSDavide Italianovoid __cxx_atomic_init(__cxx_atomic_lock_impl<_Tp>* __a,  _Tp __val) {
11746de760acSDavide Italiano  __a->__a_value = __val;
11756de760acSDavide Italiano}
11766de760acSDavide Italiano
11776de760acSDavide Italianotemplate <typename _Tp>
11786de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
11796de760acSDavide Italianovoid __cxx_atomic_store(volatile __cxx_atomic_lock_impl<_Tp>* __a,  _Tp __val, memory_order) {
11806de760acSDavide Italiano  __a->__lock();
11816de760acSDavide Italiano  __cxx_atomic_assign_volatile(__a->__a_value, __val);
11826de760acSDavide Italiano  __a->__unlock();
11836de760acSDavide Italiano}
11846de760acSDavide Italianotemplate <typename _Tp>
11856de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
11866de760acSDavide Italianovoid __cxx_atomic_store(__cxx_atomic_lock_impl<_Tp>* __a,  _Tp __val, memory_order) {
11876de760acSDavide Italiano  __a->__lock();
11886de760acSDavide Italiano  __a->__a_value = __val;
11896de760acSDavide Italiano  __a->__unlock();
11906de760acSDavide Italiano}
11916de760acSDavide Italiano
11926de760acSDavide Italianotemplate <typename _Tp>
11936de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
11946de760acSDavide Italiano_Tp __cxx_atomic_load(const volatile __cxx_atomic_lock_impl<_Tp>* __a, memory_order) {
11956de760acSDavide Italiano  return __a->__read();
11966de760acSDavide Italiano}
11976de760acSDavide Italianotemplate <typename _Tp>
11986de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
11996de760acSDavide Italiano_Tp __cxx_atomic_load(const __cxx_atomic_lock_impl<_Tp>* __a, memory_order) {
12006de760acSDavide Italiano  return __a->__read();
12016de760acSDavide Italiano}
12026de760acSDavide Italiano
12036de760acSDavide Italianotemplate <typename _Tp>
12046de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
12056de760acSDavide Italiano_Tp __cxx_atomic_exchange(volatile __cxx_atomic_lock_impl<_Tp>* __a, _Tp __value, memory_order) {
12066de760acSDavide Italiano  __a->__lock();
12076de760acSDavide Italiano  _Tp __old;
12086de760acSDavide Italiano  __cxx_atomic_assign_volatile(__old, __a->__a_value);
12096de760acSDavide Italiano  __cxx_atomic_assign_volatile(__a->__a_value, __value);
12106de760acSDavide Italiano  __a->__unlock();
12116de760acSDavide Italiano  return __old;
12126de760acSDavide Italiano}
12136de760acSDavide Italianotemplate <typename _Tp>
12146de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
12156de760acSDavide Italiano_Tp __cxx_atomic_exchange(__cxx_atomic_lock_impl<_Tp>* __a, _Tp __value, memory_order) {
12166de760acSDavide Italiano  __a->__lock();
12176de760acSDavide Italiano  _Tp __old = __a->__a_value;
12186de760acSDavide Italiano  __a->__a_value = __value;
12196de760acSDavide Italiano  __a->__unlock();
12206de760acSDavide Italiano  return __old;
12216de760acSDavide Italiano}
12226de760acSDavide Italiano
12236de760acSDavide Italianotemplate <typename _Tp>
12246de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
12256de760acSDavide Italianobool __cxx_atomic_compare_exchange_strong(volatile __cxx_atomic_lock_impl<_Tp>* __a,
12266de760acSDavide Italiano                                          _Tp* __expected, _Tp __value, memory_order, memory_order) {
122754fa9ecdSOlivier Giroux  _Tp __temp;
1228fc4bff0cSOlivier Giroux  __a->__lock();
122954fa9ecdSOlivier Giroux  __cxx_atomic_assign_volatile(__temp, __a->__a_value);
12303696227cSArthur O'Dwyer  bool __ret = (_VSTD::memcmp(&__temp, __expected, sizeof(_Tp)) == 0);
12316de760acSDavide Italiano  if(__ret)
12326de760acSDavide Italiano    __cxx_atomic_assign_volatile(__a->__a_value, __value);
12336de760acSDavide Italiano  else
12346de760acSDavide Italiano    __cxx_atomic_assign_volatile(*__expected, __a->__a_value);
12356de760acSDavide Italiano  __a->__unlock();
12366de760acSDavide Italiano  return __ret;
12376de760acSDavide Italiano}
12386de760acSDavide Italianotemplate <typename _Tp>
12396de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
12406de760acSDavide Italianobool __cxx_atomic_compare_exchange_strong(__cxx_atomic_lock_impl<_Tp>* __a,
12416de760acSDavide Italiano                                          _Tp* __expected, _Tp __value, memory_order, memory_order) {
12426de760acSDavide Italiano  __a->__lock();
12433696227cSArthur O'Dwyer  bool __ret = (_VSTD::memcmp(&__a->__a_value, __expected, sizeof(_Tp)) == 0);
12446de760acSDavide Italiano  if(__ret)
12453696227cSArthur O'Dwyer    _VSTD::memcpy(&__a->__a_value, &__value, sizeof(_Tp));
12466de760acSDavide Italiano  else
12473696227cSArthur O'Dwyer    _VSTD::memcpy(__expected, &__a->__a_value, sizeof(_Tp));
12486de760acSDavide Italiano  __a->__unlock();
12496de760acSDavide Italiano  return __ret;
12506de760acSDavide Italiano}
12516de760acSDavide Italiano
12526de760acSDavide Italianotemplate <typename _Tp>
12536de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
12546de760acSDavide Italianobool __cxx_atomic_compare_exchange_weak(volatile __cxx_atomic_lock_impl<_Tp>* __a,
12556de760acSDavide Italiano                                        _Tp* __expected, _Tp __value, memory_order, memory_order) {
125654fa9ecdSOlivier Giroux  _Tp __temp;
1257fc4bff0cSOlivier Giroux  __a->__lock();
125854fa9ecdSOlivier Giroux  __cxx_atomic_assign_volatile(__temp, __a->__a_value);
12593696227cSArthur O'Dwyer  bool __ret = (_VSTD::memcmp(&__temp, __expected, sizeof(_Tp)) == 0);
12606de760acSDavide Italiano  if(__ret)
12616de760acSDavide Italiano    __cxx_atomic_assign_volatile(__a->__a_value, __value);
12626de760acSDavide Italiano  else
12636de760acSDavide Italiano    __cxx_atomic_assign_volatile(*__expected, __a->__a_value);
12646de760acSDavide Italiano  __a->__unlock();
12656de760acSDavide Italiano  return __ret;
12666de760acSDavide Italiano}
12676de760acSDavide Italianotemplate <typename _Tp>
12686de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
12696de760acSDavide Italianobool __cxx_atomic_compare_exchange_weak(__cxx_atomic_lock_impl<_Tp>* __a,
12706de760acSDavide Italiano                                        _Tp* __expected, _Tp __value, memory_order, memory_order) {
12716de760acSDavide Italiano  __a->__lock();
12723696227cSArthur O'Dwyer  bool __ret = (_VSTD::memcmp(&__a->__a_value, __expected, sizeof(_Tp)) == 0);
12736de760acSDavide Italiano  if(__ret)
12743696227cSArthur O'Dwyer    _VSTD::memcpy(&__a->__a_value, &__value, sizeof(_Tp));
12756de760acSDavide Italiano  else
12763696227cSArthur O'Dwyer    _VSTD::memcpy(__expected, &__a->__a_value, sizeof(_Tp));
12776de760acSDavide Italiano  __a->__unlock();
12786de760acSDavide Italiano  return __ret;
12796de760acSDavide Italiano}
12806de760acSDavide Italiano
12816de760acSDavide Italianotemplate <typename _Tp, typename _Td>
12826de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
12836de760acSDavide Italiano_Tp __cxx_atomic_fetch_add(volatile __cxx_atomic_lock_impl<_Tp>* __a,
12846de760acSDavide Italiano                           _Td __delta, memory_order) {
12856de760acSDavide Italiano  __a->__lock();
12866de760acSDavide Italiano  _Tp __old;
12876de760acSDavide Italiano  __cxx_atomic_assign_volatile(__old, __a->__a_value);
12886de760acSDavide Italiano  __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old + __delta));
12896de760acSDavide Italiano  __a->__unlock();
12906de760acSDavide Italiano  return __old;
12916de760acSDavide Italiano}
12926de760acSDavide Italianotemplate <typename _Tp, typename _Td>
12936de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
12946de760acSDavide Italiano_Tp __cxx_atomic_fetch_add(__cxx_atomic_lock_impl<_Tp>* __a,
12956de760acSDavide Italiano                           _Td __delta, memory_order) {
12966de760acSDavide Italiano  __a->__lock();
12976de760acSDavide Italiano  _Tp __old = __a->__a_value;
12986de760acSDavide Italiano  __a->__a_value += __delta;
12996de760acSDavide Italiano  __a->__unlock();
13006de760acSDavide Italiano  return __old;
13016de760acSDavide Italiano}
13026de760acSDavide Italiano
13036de760acSDavide Italianotemplate <typename _Tp, typename _Td>
13046de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
13056de760acSDavide Italiano_Tp* __cxx_atomic_fetch_add(volatile __cxx_atomic_lock_impl<_Tp*>* __a,
13066de760acSDavide Italiano                           ptrdiff_t __delta, memory_order) {
13076de760acSDavide Italiano  __a->__lock();
13086de760acSDavide Italiano  _Tp* __old;
13096de760acSDavide Italiano  __cxx_atomic_assign_volatile(__old, __a->__a_value);
13106de760acSDavide Italiano  __cxx_atomic_assign_volatile(__a->__a_value, __old + __delta);
13116de760acSDavide Italiano  __a->__unlock();
13126de760acSDavide Italiano  return __old;
13136de760acSDavide Italiano}
13146de760acSDavide Italianotemplate <typename _Tp, typename _Td>
13156de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
13166de760acSDavide Italiano_Tp* __cxx_atomic_fetch_add(__cxx_atomic_lock_impl<_Tp*>* __a,
13176de760acSDavide Italiano                           ptrdiff_t __delta, memory_order) {
13186de760acSDavide Italiano  __a->__lock();
13196de760acSDavide Italiano  _Tp* __old = __a->__a_value;
13206de760acSDavide Italiano  __a->__a_value += __delta;
13216de760acSDavide Italiano  __a->__unlock();
13226de760acSDavide Italiano  return __old;
13236de760acSDavide Italiano}
13246de760acSDavide Italiano
13256de760acSDavide Italianotemplate <typename _Tp, typename _Td>
13266de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
13276de760acSDavide Italiano_Tp __cxx_atomic_fetch_sub(volatile __cxx_atomic_lock_impl<_Tp>* __a,
13286de760acSDavide Italiano                           _Td __delta, memory_order) {
13296de760acSDavide Italiano  __a->__lock();
13306de760acSDavide Italiano  _Tp __old;
13316de760acSDavide Italiano  __cxx_atomic_assign_volatile(__old, __a->__a_value);
13326de760acSDavide Italiano  __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old - __delta));
13336de760acSDavide Italiano  __a->__unlock();
13346de760acSDavide Italiano  return __old;
13356de760acSDavide Italiano}
13366de760acSDavide Italianotemplate <typename _Tp, typename _Td>
13376de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
13386de760acSDavide Italiano_Tp __cxx_atomic_fetch_sub(__cxx_atomic_lock_impl<_Tp>* __a,
13396de760acSDavide Italiano                           _Td __delta, memory_order) {
13406de760acSDavide Italiano  __a->__lock();
13416de760acSDavide Italiano  _Tp __old = __a->__a_value;
13426de760acSDavide Italiano  __a->__a_value -= __delta;
13436de760acSDavide Italiano  __a->__unlock();
13446de760acSDavide Italiano  return __old;
13456de760acSDavide Italiano}
13466de760acSDavide Italiano
13476de760acSDavide Italianotemplate <typename _Tp>
13486de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
13496de760acSDavide Italiano_Tp __cxx_atomic_fetch_and(volatile __cxx_atomic_lock_impl<_Tp>* __a,
13506de760acSDavide Italiano                           _Tp __pattern, memory_order) {
13516de760acSDavide Italiano  __a->__lock();
13526de760acSDavide Italiano  _Tp __old;
13536de760acSDavide Italiano  __cxx_atomic_assign_volatile(__old, __a->__a_value);
13546de760acSDavide Italiano  __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old & __pattern));
13556de760acSDavide Italiano  __a->__unlock();
13566de760acSDavide Italiano  return __old;
13576de760acSDavide Italiano}
13586de760acSDavide Italianotemplate <typename _Tp>
13596de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
13606de760acSDavide Italiano_Tp __cxx_atomic_fetch_and(__cxx_atomic_lock_impl<_Tp>* __a,
13616de760acSDavide Italiano                           _Tp __pattern, memory_order) {
13626de760acSDavide Italiano  __a->__lock();
13636de760acSDavide Italiano  _Tp __old = __a->__a_value;
13646de760acSDavide Italiano  __a->__a_value &= __pattern;
13656de760acSDavide Italiano  __a->__unlock();
13666de760acSDavide Italiano  return __old;
13676de760acSDavide Italiano}
13686de760acSDavide Italiano
13696de760acSDavide Italianotemplate <typename _Tp>
13706de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
13716de760acSDavide Italiano_Tp __cxx_atomic_fetch_or(volatile __cxx_atomic_lock_impl<_Tp>* __a,
13726de760acSDavide Italiano                          _Tp __pattern, memory_order) {
13736de760acSDavide Italiano  __a->__lock();
13746de760acSDavide Italiano  _Tp __old;
13756de760acSDavide Italiano  __cxx_atomic_assign_volatile(__old, __a->__a_value);
13766de760acSDavide Italiano  __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old | __pattern));
13776de760acSDavide Italiano  __a->__unlock();
13786de760acSDavide Italiano  return __old;
13796de760acSDavide Italiano}
13806de760acSDavide Italianotemplate <typename _Tp>
13816de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
13826de760acSDavide Italiano_Tp __cxx_atomic_fetch_or(__cxx_atomic_lock_impl<_Tp>* __a,
13836de760acSDavide Italiano                          _Tp __pattern, memory_order) {
13846de760acSDavide Italiano  __a->__lock();
13856de760acSDavide Italiano  _Tp __old = __a->__a_value;
13866de760acSDavide Italiano  __a->__a_value |= __pattern;
13876de760acSDavide Italiano  __a->__unlock();
13886de760acSDavide Italiano  return __old;
13896de760acSDavide Italiano}
13906de760acSDavide Italiano
13916de760acSDavide Italianotemplate <typename _Tp>
13926de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
13936de760acSDavide Italiano_Tp __cxx_atomic_fetch_xor(volatile __cxx_atomic_lock_impl<_Tp>* __a,
13946de760acSDavide Italiano                           _Tp __pattern, memory_order) {
13956de760acSDavide Italiano  __a->__lock();
13966de760acSDavide Italiano  _Tp __old;
13976de760acSDavide Italiano  __cxx_atomic_assign_volatile(__old, __a->__a_value);
13986de760acSDavide Italiano  __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old ^ __pattern));
13996de760acSDavide Italiano  __a->__unlock();
14006de760acSDavide Italiano  return __old;
14016de760acSDavide Italiano}
14026de760acSDavide Italianotemplate <typename _Tp>
14036de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
14046de760acSDavide Italiano_Tp __cxx_atomic_fetch_xor(__cxx_atomic_lock_impl<_Tp>* __a,
14056de760acSDavide Italiano                           _Tp __pattern, memory_order) {
14066de760acSDavide Italiano  __a->__lock();
14076de760acSDavide Italiano  _Tp __old = __a->__a_value;
14086de760acSDavide Italiano  __a->__a_value ^= __pattern;
14096de760acSDavide Italiano  __a->__unlock();
14106de760acSDavide Italiano  return __old;
14116de760acSDavide Italiano}
14126de760acSDavide Italiano
14136de760acSDavide Italianotemplate <typename _Tp,
1414*d64394b8SLouis Dionne          typename _Base = typename conditional<__libcpp_is_always_lock_free<_Tp>::__value,
14156de760acSDavide Italiano                                                __cxx_atomic_base_impl<_Tp>,
14166de760acSDavide Italiano                                                __cxx_atomic_lock_impl<_Tp> >::type>
14176de760acSDavide Italiano#else
14186de760acSDavide Italianotemplate <typename _Tp,
14196de760acSDavide Italiano          typename _Base = __cxx_atomic_base_impl<_Tp> >
14206de760acSDavide Italiano#endif //_LIBCPP_ATOMIC_ONLY_USE_BUILTINS
14216de760acSDavide Italianostruct __cxx_atomic_impl : public _Base {
14226de760acSDavide Italiano    static_assert(is_trivially_copyable<_Tp>::value,
14233e957e5dSLouis Dionne      "std::atomic<T> requires that 'T' be a trivially copyable type");
14246de760acSDavide Italiano
14254955095fSNikolas Klauser  _LIBCPP_INLINE_VISIBILITY __cxx_atomic_impl() _NOEXCEPT = default;
1426b48c5010SNikolas Klauser  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR explicit __cxx_atomic_impl(_Tp __value) _NOEXCEPT
1427b48c5010SNikolas Klauser    : _Base(__value) {}
14286de760acSDavide Italiano};
14296de760acSDavide Italiano
143039328a65SMartin Storsjö#if defined(__linux__) || (defined(_AIX) && !defined(__64BIT__))
143154fa9ecdSOlivier Giroux    using __cxx_contention_t = int32_t;
143254fa9ecdSOlivier Giroux#else
143354fa9ecdSOlivier Giroux    using __cxx_contention_t = int64_t;
143439328a65SMartin Storsjö#endif // __linux__ || (_AIX && !__64BIT__)
143554fa9ecdSOlivier Giroux
143654fa9ecdSOlivier Girouxusing __cxx_atomic_contention_t = __cxx_atomic_impl<__cxx_contention_t>;
143754fa9ecdSOlivier Giroux
143892832e48SLouis Dionne#if defined(_LIBCPP_HAS_NO_THREADS)
143992832e48SLouis Dionne#   define _LIBCPP_HAS_NO_PLATFORM_WAIT
144092832e48SLouis Dionne#endif
144192832e48SLouis Dionne
144292832e48SLouis Dionne// TODO:
144392832e48SLouis Dionne// _LIBCPP_HAS_NO_PLATFORM_WAIT is currently a "dead" macro, in the sense that
144492832e48SLouis Dionne// it is not tied anywhere into the build system or even documented. We should
144592832e48SLouis Dionne// clean it up because it is technically never defined except when threads are
144692832e48SLouis Dionne// disabled. We should clean it up in its own changeset in case we break "bad"
144792832e48SLouis Dionne// users.
144854fa9ecdSOlivier Giroux#ifndef _LIBCPP_HAS_NO_PLATFORM_WAIT
144954fa9ecdSOlivier Giroux
145080e73f22SLouis Dionne_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_one(void const volatile*);
145180e73f22SLouis Dionne_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_all(void const volatile*);
145280e73f22SLouis Dionne_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t __libcpp_atomic_monitor(void const volatile*);
145380e73f22SLouis Dionne_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __libcpp_atomic_wait(void const volatile*, __cxx_contention_t);
145454fa9ecdSOlivier Giroux
145580e73f22SLouis Dionne_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_one(__cxx_atomic_contention_t const volatile*);
145680e73f22SLouis Dionne_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_all(__cxx_atomic_contention_t const volatile*);
145780e73f22SLouis Dionne_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t __libcpp_atomic_monitor(__cxx_atomic_contention_t const volatile*);
145880e73f22SLouis Dionne_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __libcpp_atomic_wait(__cxx_atomic_contention_t const volatile*, __cxx_contention_t);
145954fa9ecdSOlivier Giroux
146054fa9ecdSOlivier Girouxtemplate <class _Atp, class _Fn>
1461b21405d1SLouis Dionnestruct __libcpp_atomic_wait_backoff_impl {
1462b21405d1SLouis Dionne    _Atp* __a;
1463b21405d1SLouis Dionne    _Fn __test_fn;
146446c38761SLouis Dionne    _LIBCPP_AVAILABILITY_SYNC
1465b21405d1SLouis Dionne    _LIBCPP_INLINE_VISIBILITY bool operator()(chrono::nanoseconds __elapsed) const
146654fa9ecdSOlivier Giroux    {
146754fa9ecdSOlivier Giroux        if(__elapsed > chrono::microseconds(64))
146854fa9ecdSOlivier Giroux        {
146954fa9ecdSOlivier Giroux            auto const __monitor = __libcpp_atomic_monitor(__a);
147054fa9ecdSOlivier Giroux            if(__test_fn())
147154fa9ecdSOlivier Giroux                return true;
147254fa9ecdSOlivier Giroux            __libcpp_atomic_wait(__a, __monitor);
147354fa9ecdSOlivier Giroux        }
147454fa9ecdSOlivier Giroux        else if(__elapsed > chrono::microseconds(4))
147554fa9ecdSOlivier Giroux            __libcpp_thread_yield();
147654fa9ecdSOlivier Giroux        else
1477d2acf229SMarek Kurdej            {} // poll
147854fa9ecdSOlivier Giroux        return false;
1479b21405d1SLouis Dionne    }
148054fa9ecdSOlivier Giroux};
1481b21405d1SLouis Dionne
1482b21405d1SLouis Dionnetemplate <class _Atp, class _Fn>
148346c38761SLouis Dionne_LIBCPP_AVAILABILITY_SYNC
1484b21405d1SLouis Dionne_LIBCPP_INLINE_VISIBILITY bool __cxx_atomic_wait(_Atp* __a, _Fn && __test_fn)
1485b21405d1SLouis Dionne{
1486b21405d1SLouis Dionne    __libcpp_atomic_wait_backoff_impl<_Atp, typename decay<_Fn>::type> __backoff_fn = {__a, __test_fn};
1487b21405d1SLouis Dionne    return __libcpp_thread_poll_with_backoff(__test_fn, __backoff_fn);
148854fa9ecdSOlivier Giroux}
148954fa9ecdSOlivier Giroux
149054fa9ecdSOlivier Giroux#else // _LIBCPP_HAS_NO_PLATFORM_WAIT
149154fa9ecdSOlivier Giroux
149254fa9ecdSOlivier Girouxtemplate <class _Tp>
149354fa9ecdSOlivier Giroux_LIBCPP_INLINE_VISIBILITY void __cxx_atomic_notify_all(__cxx_atomic_impl<_Tp> const volatile*) { }
149454fa9ecdSOlivier Girouxtemplate <class _Tp>
149554fa9ecdSOlivier Giroux_LIBCPP_INLINE_VISIBILITY void __cxx_atomic_notify_one(__cxx_atomic_impl<_Tp> const volatile*) { }
149654fa9ecdSOlivier Girouxtemplate <class _Atp, class _Fn>
149754fa9ecdSOlivier Giroux_LIBCPP_INLINE_VISIBILITY bool __cxx_atomic_wait(_Atp*, _Fn && __test_fn)
149854fa9ecdSOlivier Giroux{
149992832e48SLouis Dionne#if defined(_LIBCPP_HAS_NO_THREADS)
150092832e48SLouis Dionne    using _Policy = __spinning_backoff_policy;
150192832e48SLouis Dionne#else
150292832e48SLouis Dionne    using _Policy = __libcpp_timed_backoff_policy;
150392832e48SLouis Dionne#endif
150492832e48SLouis Dionne    return __libcpp_thread_poll_with_backoff(__test_fn, _Policy());
150554fa9ecdSOlivier Giroux}
150654fa9ecdSOlivier Giroux
150754fa9ecdSOlivier Giroux#endif // _LIBCPP_HAS_NO_PLATFORM_WAIT
150854fa9ecdSOlivier Giroux
150954fa9ecdSOlivier Girouxtemplate <class _Atp, class _Tp>
1510b21405d1SLouis Dionnestruct __cxx_atomic_wait_test_fn_impl {
1511b21405d1SLouis Dionne    _Atp* __a;
1512b21405d1SLouis Dionne    _Tp __val;
1513b21405d1SLouis Dionne    memory_order __order;
1514b21405d1SLouis Dionne    _LIBCPP_INLINE_VISIBILITY bool operator()() const
1515b21405d1SLouis Dionne    {
1516b21405d1SLouis Dionne        return !__cxx_nonatomic_compare_equal(__cxx_atomic_load(__a, __order), __val);
1517b21405d1SLouis Dionne    }
1518b21405d1SLouis Dionne};
1519b21405d1SLouis Dionne
1520b21405d1SLouis Dionnetemplate <class _Atp, class _Tp>
152146c38761SLouis Dionne_LIBCPP_AVAILABILITY_SYNC
152254fa9ecdSOlivier Giroux_LIBCPP_INLINE_VISIBILITY bool __cxx_atomic_wait(_Atp* __a, _Tp const __val, memory_order __order)
152354fa9ecdSOlivier Giroux{
1524b21405d1SLouis Dionne    __cxx_atomic_wait_test_fn_impl<_Atp, _Tp> __test_fn = {__a, __val, __order};
152554fa9ecdSOlivier Giroux    return __cxx_atomic_wait(__a, __test_fn);
152654fa9ecdSOlivier Giroux}
152754fa9ecdSOlivier Giroux
1528c772a620SHoward Hinnant// general atomic<T>
1529c772a620SHoward Hinnant
1530c772a620SHoward Hinnanttemplate <class _Tp, bool = is_integral<_Tp>::value && !is_same<_Tp, bool>::value>
1531c772a620SHoward Hinnantstruct __atomic_base  // false
1532c772a620SHoward Hinnant{
15336de760acSDavide Italiano    mutable __cxx_atomic_impl<_Tp> __a_;
1534c772a620SHoward Hinnant
1535b95ee819SJF Bastien#if defined(__cpp_lib_atomic_is_always_lock_free)
1536*d64394b8SLouis Dionne  static _LIBCPP_CONSTEXPR bool is_always_lock_free = __libcpp_is_always_lock_free<__cxx_atomic_impl<_Tp> >::__value;
1537b95ee819SJF Bastien#endif
1538b95ee819SJF Bastien
1539c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1540d01320c2SHoward Hinnant    bool is_lock_free() const volatile _NOEXCEPT
15416de760acSDavide Italiano        {return __cxx_atomic_is_lock_free(sizeof(_Tp));}
1542c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1543d01320c2SHoward Hinnant    bool is_lock_free() const _NOEXCEPT
1544776cc6e4SEric Fiselier        {return static_cast<__atomic_base const volatile*>(this)->is_lock_free();}
1545c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1546d01320c2SHoward Hinnant    void store(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
1547faf2a813SEric Fiselier      _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
15486de760acSDavide Italiano        {__cxx_atomic_store(&__a_, __d, __m);}
1549c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1550d01320c2SHoward Hinnant    void store(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT
1551faf2a813SEric Fiselier      _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
15526de760acSDavide Italiano        {__cxx_atomic_store(&__a_, __d, __m);}
1553c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1554d01320c2SHoward Hinnant    _Tp load(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
1555faf2a813SEric Fiselier      _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
15566de760acSDavide Italiano        {return __cxx_atomic_load(&__a_, __m);}
1557c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1558d01320c2SHoward Hinnant    _Tp load(memory_order __m = memory_order_seq_cst) const _NOEXCEPT
1559faf2a813SEric Fiselier      _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
15606de760acSDavide Italiano        {return __cxx_atomic_load(&__a_, __m);}
1561c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1562d01320c2SHoward Hinnant    operator _Tp() const volatile _NOEXCEPT {return load();}
1563c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1564d01320c2SHoward Hinnant    operator _Tp() const _NOEXCEPT          {return load();}
1565c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1566d01320c2SHoward Hinnant    _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
15676de760acSDavide Italiano        {return __cxx_atomic_exchange(&__a_, __d, __m);}
1568c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1569d01320c2SHoward Hinnant    _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT
15706de760acSDavide Italiano        {return __cxx_atomic_exchange(&__a_, __d, __m);}
1571c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1572c772a620SHoward Hinnant    bool compare_exchange_weak(_Tp& __e, _Tp __d,
1573d01320c2SHoward Hinnant                               memory_order __s, memory_order __f) volatile _NOEXCEPT
1574faf2a813SEric Fiselier      _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
15756de760acSDavide Italiano        {return __cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);}
1576c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1577c772a620SHoward Hinnant    bool compare_exchange_weak(_Tp& __e, _Tp __d,
1578d01320c2SHoward Hinnant                               memory_order __s, memory_order __f) _NOEXCEPT
1579faf2a813SEric Fiselier      _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
15806de760acSDavide Italiano        {return __cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);}
1581c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1582c772a620SHoward Hinnant    bool compare_exchange_strong(_Tp& __e, _Tp __d,
1583d01320c2SHoward Hinnant                                 memory_order __s, memory_order __f) volatile _NOEXCEPT
1584faf2a813SEric Fiselier      _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
15856de760acSDavide Italiano        {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);}
1586c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1587c772a620SHoward Hinnant    bool compare_exchange_strong(_Tp& __e, _Tp __d,
1588d01320c2SHoward Hinnant                                 memory_order __s, memory_order __f) _NOEXCEPT
1589faf2a813SEric Fiselier      _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
15906de760acSDavide Italiano        {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);}
1591c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1592c772a620SHoward Hinnant    bool compare_exchange_weak(_Tp& __e, _Tp __d,
1593d01320c2SHoward Hinnant                              memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
15946de760acSDavide Italiano        {return __cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);}
1595c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1596c772a620SHoward Hinnant    bool compare_exchange_weak(_Tp& __e, _Tp __d,
1597d01320c2SHoward Hinnant                               memory_order __m = memory_order_seq_cst) _NOEXCEPT
15986de760acSDavide Italiano        {return __cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);}
1599c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1600c772a620SHoward Hinnant    bool compare_exchange_strong(_Tp& __e, _Tp __d,
1601d01320c2SHoward Hinnant                              memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
16026de760acSDavide Italiano        {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}
1603c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1604c772a620SHoward Hinnant    bool compare_exchange_strong(_Tp& __e, _Tp __d,
1605d01320c2SHoward Hinnant                                 memory_order __m = memory_order_seq_cst) _NOEXCEPT
16066de760acSDavide Italiano        {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}
1607c772a620SHoward Hinnant
160846c38761SLouis Dionne    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void wait(_Tp __v, memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
160954fa9ecdSOlivier Giroux        {__cxx_atomic_wait(&__a_, __v, __m);}
161046c38761SLouis Dionne    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void wait(_Tp __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT
161154fa9ecdSOlivier Giroux        {__cxx_atomic_wait(&__a_, __v, __m);}
161246c38761SLouis Dionne    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_one() volatile _NOEXCEPT
161354fa9ecdSOlivier Giroux        {__cxx_atomic_notify_one(&__a_);}
161446c38761SLouis Dionne    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_one() _NOEXCEPT
161554fa9ecdSOlivier Giroux        {__cxx_atomic_notify_one(&__a_);}
161646c38761SLouis Dionne    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_all() volatile _NOEXCEPT
161754fa9ecdSOlivier Giroux        {__cxx_atomic_notify_all(&__a_);}
161846c38761SLouis Dionne    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_all() _NOEXCEPT
161954fa9ecdSOlivier Giroux        {__cxx_atomic_notify_all(&__a_);}
162054fa9ecdSOlivier Giroux
162156aac567SRaul Tambre#if _LIBCPP_STD_VER > 17
162256aac567SRaul Tambre    _LIBCPP_INLINE_VISIBILITY constexpr
162356aac567SRaul Tambre    __atomic_base() noexcept(is_nothrow_default_constructible_v<_Tp>) : __a_(_Tp()) {}
162456aac567SRaul Tambre#else
1625c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
16264955095fSNikolas Klauser    __atomic_base() _NOEXCEPT = default;
162756aac567SRaul Tambre#endif
1628da9ca0b4SHoward Hinnant
16296de760acSDavide Italiano    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
16306de760acSDavide Italiano    __atomic_base(_Tp __d) _NOEXCEPT : __a_(__d) {}
16316de760acSDavide Italiano
1632c772a620SHoward Hinnant    __atomic_base(const __atomic_base&) = delete;
1633c772a620SHoward Hinnant};
1634c772a620SHoward Hinnant
1635b95ee819SJF Bastien#if defined(__cpp_lib_atomic_is_always_lock_free)
1636b95ee819SJF Bastientemplate <class _Tp, bool __b>
1637b95ee819SJF Bastien_LIBCPP_CONSTEXPR bool __atomic_base<_Tp, __b>::is_always_lock_free;
1638b95ee819SJF Bastien#endif
1639b95ee819SJF Bastien
1640c772a620SHoward Hinnant// atomic<Integral>
1641c772a620SHoward Hinnant
1642c772a620SHoward Hinnanttemplate <class _Tp>
1643c772a620SHoward Hinnantstruct __atomic_base<_Tp, true>
1644c772a620SHoward Hinnant    : public __atomic_base<_Tp, false>
1645c772a620SHoward Hinnant{
1646c772a620SHoward Hinnant    typedef __atomic_base<_Tp, false> __base;
164756aac567SRaul Tambre
164856aac567SRaul Tambre    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
16494955095fSNikolas Klauser    __atomic_base() _NOEXCEPT = default;
165056aac567SRaul Tambre
1651c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1652d01320c2SHoward Hinnant    _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __base(__d) {}
1653c772a620SHoward Hinnant
1654c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1655d01320c2SHoward Hinnant    _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
16566de760acSDavide Italiano        {return __cxx_atomic_fetch_add(&this->__a_, __op, __m);}
1657c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1658d01320c2SHoward Hinnant    _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
16596de760acSDavide Italiano        {return __cxx_atomic_fetch_add(&this->__a_, __op, __m);}
1660c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1661d01320c2SHoward Hinnant    _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
16626de760acSDavide Italiano        {return __cxx_atomic_fetch_sub(&this->__a_, __op, __m);}
1663c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1664d01320c2SHoward Hinnant    _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
16656de760acSDavide Italiano        {return __cxx_atomic_fetch_sub(&this->__a_, __op, __m);}
1666c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1667d01320c2SHoward Hinnant    _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
16686de760acSDavide Italiano        {return __cxx_atomic_fetch_and(&this->__a_, __op, __m);}
1669c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1670d01320c2SHoward Hinnant    _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
16716de760acSDavide Italiano        {return __cxx_atomic_fetch_and(&this->__a_, __op, __m);}
1672c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1673d01320c2SHoward Hinnant    _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
16746de760acSDavide Italiano        {return __cxx_atomic_fetch_or(&this->__a_, __op, __m);}
1675c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1676d01320c2SHoward Hinnant    _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
16776de760acSDavide Italiano        {return __cxx_atomic_fetch_or(&this->__a_, __op, __m);}
1678c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1679d01320c2SHoward Hinnant    _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
16806de760acSDavide Italiano        {return __cxx_atomic_fetch_xor(&this->__a_, __op, __m);}
1681c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1682d01320c2SHoward Hinnant    _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
16836de760acSDavide Italiano        {return __cxx_atomic_fetch_xor(&this->__a_, __op, __m);}
1684c772a620SHoward Hinnant
1685c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1686d01320c2SHoward Hinnant    _Tp operator++(int) volatile _NOEXCEPT      {return fetch_add(_Tp(1));}
1687c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1688d01320c2SHoward Hinnant    _Tp operator++(int) _NOEXCEPT               {return fetch_add(_Tp(1));}
1689c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1690d01320c2SHoward Hinnant    _Tp operator--(int) volatile _NOEXCEPT      {return fetch_sub(_Tp(1));}
1691c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1692d01320c2SHoward Hinnant    _Tp operator--(int) _NOEXCEPT               {return fetch_sub(_Tp(1));}
1693c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1694d01320c2SHoward Hinnant    _Tp operator++() volatile _NOEXCEPT         {return fetch_add(_Tp(1)) + _Tp(1);}
1695c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1696d01320c2SHoward Hinnant    _Tp operator++() _NOEXCEPT                  {return fetch_add(_Tp(1)) + _Tp(1);}
1697c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1698d01320c2SHoward Hinnant    _Tp operator--() volatile _NOEXCEPT         {return fetch_sub(_Tp(1)) - _Tp(1);}
1699c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1700d01320c2SHoward Hinnant    _Tp operator--() _NOEXCEPT                  {return fetch_sub(_Tp(1)) - _Tp(1);}
1701c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1702d01320c2SHoward Hinnant    _Tp operator+=(_Tp __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;}
1703c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1704d01320c2SHoward Hinnant    _Tp operator+=(_Tp __op) _NOEXCEPT          {return fetch_add(__op) + __op;}
1705c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1706d01320c2SHoward Hinnant    _Tp operator-=(_Tp __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;}
1707c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1708d01320c2SHoward Hinnant    _Tp operator-=(_Tp __op) _NOEXCEPT          {return fetch_sub(__op) - __op;}
1709c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1710d01320c2SHoward Hinnant    _Tp operator&=(_Tp __op) volatile _NOEXCEPT {return fetch_and(__op) & __op;}
1711c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1712d01320c2SHoward Hinnant    _Tp operator&=(_Tp __op) _NOEXCEPT          {return fetch_and(__op) & __op;}
1713c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1714d01320c2SHoward Hinnant    _Tp operator|=(_Tp __op) volatile _NOEXCEPT {return fetch_or(__op) | __op;}
1715c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1716d01320c2SHoward Hinnant    _Tp operator|=(_Tp __op) _NOEXCEPT          {return fetch_or(__op) | __op;}
1717c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1718d01320c2SHoward Hinnant    _Tp operator^=(_Tp __op) volatile _NOEXCEPT {return fetch_xor(__op) ^ __op;}
1719c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1720d01320c2SHoward Hinnant    _Tp operator^=(_Tp __op) _NOEXCEPT          {return fetch_xor(__op) ^ __op;}
1721c772a620SHoward Hinnant};
1722c772a620SHoward Hinnant
1723c772a620SHoward Hinnant// atomic<T>
1724c772a620SHoward Hinnant
1725c772a620SHoward Hinnanttemplate <class _Tp>
1726c772a620SHoward Hinnantstruct atomic
1727c772a620SHoward Hinnant    : public __atomic_base<_Tp>
1728c772a620SHoward Hinnant{
1729c772a620SHoward Hinnant    typedef __atomic_base<_Tp> __base;
173054fa9ecdSOlivier Giroux    typedef _Tp value_type;
1731fc4bff0cSOlivier Giroux    typedef value_type difference_type;
173256aac567SRaul Tambre
173356aac567SRaul Tambre#if _LIBCPP_STD_VER > 17
173456aac567SRaul Tambre    _LIBCPP_INLINE_VISIBILITY
173556aac567SRaul Tambre    atomic() = default;
173656aac567SRaul Tambre#else
1737c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
17384955095fSNikolas Klauser    atomic() _NOEXCEPT = default;
173956aac567SRaul Tambre#endif
174056aac567SRaul Tambre
1741c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1742d01320c2SHoward Hinnant    _LIBCPP_CONSTEXPR atomic(_Tp __d) _NOEXCEPT : __base(__d) {}
1743c5f5f0a1SHoward Hinnant
1744c5f5f0a1SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1745d01320c2SHoward Hinnant    _Tp operator=(_Tp __d) volatile _NOEXCEPT
1746c5f5f0a1SHoward Hinnant        {__base::store(__d); return __d;}
1747c5f5f0a1SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1748d01320c2SHoward Hinnant    _Tp operator=(_Tp __d) _NOEXCEPT
1749c5f5f0a1SHoward Hinnant        {__base::store(__d); return __d;}
1750c448ea94SRuslan Arutyunyan
1751c448ea94SRuslan Arutyunyan    atomic& operator=(const atomic&) = delete;
1752c448ea94SRuslan Arutyunyan    atomic& operator=(const atomic&) volatile = delete;
1753c772a620SHoward Hinnant};
1754c772a620SHoward Hinnant
1755c772a620SHoward Hinnant// atomic<T*>
1756c772a620SHoward Hinnant
1757c772a620SHoward Hinnanttemplate <class _Tp>
1758c772a620SHoward Hinnantstruct atomic<_Tp*>
1759c772a620SHoward Hinnant    : public __atomic_base<_Tp*>
1760c772a620SHoward Hinnant{
1761c5f5f0a1SHoward Hinnant    typedef __atomic_base<_Tp*> __base;
176254fa9ecdSOlivier Giroux    typedef _Tp* value_type;
1763fc4bff0cSOlivier Giroux    typedef ptrdiff_t difference_type;
176456aac567SRaul Tambre
1765c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
17664955095fSNikolas Klauser    atomic() _NOEXCEPT = default;
176756aac567SRaul Tambre
1768c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1769d01320c2SHoward Hinnant    _LIBCPP_CONSTEXPR atomic(_Tp* __d) _NOEXCEPT : __base(__d) {}
1770c772a620SHoward Hinnant
1771c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1772d01320c2SHoward Hinnant    _Tp* operator=(_Tp* __d) volatile _NOEXCEPT
1773c5f5f0a1SHoward Hinnant        {__base::store(__d); return __d;}
1774c5f5f0a1SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1775d01320c2SHoward Hinnant    _Tp* operator=(_Tp* __d) _NOEXCEPT
1776c5f5f0a1SHoward Hinnant        {__base::store(__d); return __d;}
1777c5f5f0a1SHoward Hinnant
1778c5f5f0a1SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1779aac5b84dSMark de Wever    _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
1780aac5b84dSMark de Wever        // __atomic_fetch_add accepts function pointers, guard against them.
1781aac5b84dSMark de Wever        static_assert(!is_function<typename remove_pointer<_Tp>::type>::value, "Pointer to function isn't allowed");
1782aac5b84dSMark de Wever        return __cxx_atomic_fetch_add(&this->__a_, __op, __m);
1783aac5b84dSMark de Wever    }
1784aac5b84dSMark de Wever
1785c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1786aac5b84dSMark de Wever    _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
1787aac5b84dSMark de Wever        // __atomic_fetch_add accepts function pointers, guard against them.
1788aac5b84dSMark de Wever        static_assert(!is_function<typename remove_pointer<_Tp>::type>::value, "Pointer to function isn't allowed");
1789aac5b84dSMark de Wever        return __cxx_atomic_fetch_add(&this->__a_, __op, __m);
1790aac5b84dSMark de Wever    }
1791aac5b84dSMark de Wever
1792c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1793aac5b84dSMark de Wever    _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
1794aac5b84dSMark de Wever        // __atomic_fetch_add accepts function pointers, guard against them.
1795aac5b84dSMark de Wever        static_assert(!is_function<typename remove_pointer<_Tp>::type>::value, "Pointer to function isn't allowed");
1796aac5b84dSMark de Wever        return __cxx_atomic_fetch_sub(&this->__a_, __op, __m);
1797aac5b84dSMark de Wever    }
1798aac5b84dSMark de Wever
1799c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1800aac5b84dSMark de Wever    _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
1801aac5b84dSMark de Wever        // __atomic_fetch_add accepts function pointers, guard against them.
1802aac5b84dSMark de Wever        static_assert(!is_function<typename remove_pointer<_Tp>::type>::value, "Pointer to function isn't allowed");
1803aac5b84dSMark de Wever        return __cxx_atomic_fetch_sub(&this->__a_, __op, __m);
1804aac5b84dSMark de Wever    }
1805c772a620SHoward Hinnant
1806c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1807d01320c2SHoward Hinnant    _Tp* operator++(int) volatile _NOEXCEPT            {return fetch_add(1);}
1808c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1809d01320c2SHoward Hinnant    _Tp* operator++(int) _NOEXCEPT                     {return fetch_add(1);}
1810c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1811d01320c2SHoward Hinnant    _Tp* operator--(int) volatile _NOEXCEPT            {return fetch_sub(1);}
1812c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1813d01320c2SHoward Hinnant    _Tp* operator--(int) _NOEXCEPT                     {return fetch_sub(1);}
1814c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1815d01320c2SHoward Hinnant    _Tp* operator++() volatile _NOEXCEPT               {return fetch_add(1) + 1;}
1816c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1817d01320c2SHoward Hinnant    _Tp* operator++() _NOEXCEPT                        {return fetch_add(1) + 1;}
1818c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1819d01320c2SHoward Hinnant    _Tp* operator--() volatile _NOEXCEPT               {return fetch_sub(1) - 1;}
1820c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1821d01320c2SHoward Hinnant    _Tp* operator--() _NOEXCEPT                        {return fetch_sub(1) - 1;}
1822c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1823d01320c2SHoward Hinnant    _Tp* operator+=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;}
1824c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1825d01320c2SHoward Hinnant    _Tp* operator+=(ptrdiff_t __op) _NOEXCEPT          {return fetch_add(__op) + __op;}
1826c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1827d01320c2SHoward Hinnant    _Tp* operator-=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;}
1828c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1829d01320c2SHoward Hinnant    _Tp* operator-=(ptrdiff_t __op) _NOEXCEPT          {return fetch_sub(__op) - __op;}
1830c448ea94SRuslan Arutyunyan
1831c448ea94SRuslan Arutyunyan    atomic& operator=(const atomic&) = delete;
1832c448ea94SRuslan Arutyunyan    atomic& operator=(const atomic&) volatile = delete;
1833c772a620SHoward Hinnant};
18349847abacSHoward Hinnant
18359847abacSHoward Hinnant// atomic_is_lock_free
18369847abacSHoward Hinnant
18379847abacSHoward Hinnanttemplate <class _Tp>
18386de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
18399847abacSHoward Hinnantbool
1840d01320c2SHoward Hinnantatomic_is_lock_free(const volatile atomic<_Tp>* __o) _NOEXCEPT
18419847abacSHoward Hinnant{
1842c772a620SHoward Hinnant    return __o->is_lock_free();
18439847abacSHoward Hinnant}
18449847abacSHoward Hinnant
18459847abacSHoward Hinnanttemplate <class _Tp>
18466de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
18479847abacSHoward Hinnantbool
1848d01320c2SHoward Hinnantatomic_is_lock_free(const atomic<_Tp>* __o) _NOEXCEPT
18499847abacSHoward Hinnant{
1850c772a620SHoward Hinnant    return __o->is_lock_free();
18519847abacSHoward Hinnant}
18529847abacSHoward Hinnant
18539847abacSHoward Hinnant// atomic_init
18549847abacSHoward Hinnant
18559847abacSHoward Hinnanttemplate <class _Tp>
185656aac567SRaul Tambre_LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_INLINE_VISIBILITY
18579847abacSHoward Hinnantvoid
1858fc4bff0cSOlivier Girouxatomic_init(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
18599847abacSHoward Hinnant{
18606de760acSDavide Italiano    __cxx_atomic_init(&__o->__a_, __d);
18619847abacSHoward Hinnant}
18629847abacSHoward Hinnant
18639847abacSHoward Hinnanttemplate <class _Tp>
186456aac567SRaul Tambre_LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_INLINE_VISIBILITY
18659847abacSHoward Hinnantvoid
1866fc4bff0cSOlivier Girouxatomic_init(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
18679847abacSHoward Hinnant{
18686de760acSDavide Italiano    __cxx_atomic_init(&__o->__a_, __d);
18699847abacSHoward Hinnant}
18709847abacSHoward Hinnant
18719847abacSHoward Hinnant// atomic_store
18729847abacSHoward Hinnant
18739847abacSHoward Hinnanttemplate <class _Tp>
18746de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
18759847abacSHoward Hinnantvoid
1876fc4bff0cSOlivier Girouxatomic_store(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
18779847abacSHoward Hinnant{
1878c772a620SHoward Hinnant    __o->store(__d);
18799847abacSHoward Hinnant}
18809847abacSHoward Hinnant
18819847abacSHoward Hinnanttemplate <class _Tp>
18826de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
18839847abacSHoward Hinnantvoid
1884fc4bff0cSOlivier Girouxatomic_store(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
18859847abacSHoward Hinnant{
1886c772a620SHoward Hinnant    __o->store(__d);
18879847abacSHoward Hinnant}
18889847abacSHoward Hinnant
18899847abacSHoward Hinnant// atomic_store_explicit
18909847abacSHoward Hinnant
18919847abacSHoward Hinnanttemplate <class _Tp>
18926de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
18939847abacSHoward Hinnantvoid
1894fc4bff0cSOlivier Girouxatomic_store_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT
1895faf2a813SEric Fiselier  _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
18969847abacSHoward Hinnant{
1897c772a620SHoward Hinnant    __o->store(__d, __m);
18989847abacSHoward Hinnant}
18999847abacSHoward Hinnant
19009847abacSHoward Hinnanttemplate <class _Tp>
19016de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
19029847abacSHoward Hinnantvoid
1903fc4bff0cSOlivier Girouxatomic_store_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT
1904faf2a813SEric Fiselier  _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
19059847abacSHoward Hinnant{
1906c772a620SHoward Hinnant    __o->store(__d, __m);
19079847abacSHoward Hinnant}
19089847abacSHoward Hinnant
19099847abacSHoward Hinnant// atomic_load
19109847abacSHoward Hinnant
19119847abacSHoward Hinnanttemplate <class _Tp>
19126de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
19139847abacSHoward Hinnant_Tp
1914d01320c2SHoward Hinnantatomic_load(const volatile atomic<_Tp>* __o) _NOEXCEPT
19159847abacSHoward Hinnant{
1916c772a620SHoward Hinnant    return __o->load();
19179847abacSHoward Hinnant}
19189847abacSHoward Hinnant
19199847abacSHoward Hinnanttemplate <class _Tp>
19206de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
19219847abacSHoward Hinnant_Tp
1922d01320c2SHoward Hinnantatomic_load(const atomic<_Tp>* __o) _NOEXCEPT
19239847abacSHoward Hinnant{
1924c772a620SHoward Hinnant    return __o->load();
19259847abacSHoward Hinnant}
19269847abacSHoward Hinnant
19279847abacSHoward Hinnant// atomic_load_explicit
19289847abacSHoward Hinnant
19299847abacSHoward Hinnanttemplate <class _Tp>
19306de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
19319847abacSHoward Hinnant_Tp
1932d01320c2SHoward Hinnantatomic_load_explicit(const volatile atomic<_Tp>* __o, memory_order __m) _NOEXCEPT
1933faf2a813SEric Fiselier  _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
19349847abacSHoward Hinnant{
1935c772a620SHoward Hinnant    return __o->load(__m);
19369847abacSHoward Hinnant}
19379847abacSHoward Hinnant
19389847abacSHoward Hinnanttemplate <class _Tp>
19396de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
19409847abacSHoward Hinnant_Tp
1941d01320c2SHoward Hinnantatomic_load_explicit(const atomic<_Tp>* __o, memory_order __m) _NOEXCEPT
1942faf2a813SEric Fiselier  _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
19439847abacSHoward Hinnant{
1944c772a620SHoward Hinnant    return __o->load(__m);
19459847abacSHoward Hinnant}
19469847abacSHoward Hinnant
19479847abacSHoward Hinnant// atomic_exchange
19489847abacSHoward Hinnant
19499847abacSHoward Hinnanttemplate <class _Tp>
19506de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
19519847abacSHoward Hinnant_Tp
1952fc4bff0cSOlivier Girouxatomic_exchange(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
19539847abacSHoward Hinnant{
1954c772a620SHoward Hinnant    return __o->exchange(__d);
19559847abacSHoward Hinnant}
19569847abacSHoward Hinnant
19579847abacSHoward Hinnanttemplate <class _Tp>
19586de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
19599847abacSHoward Hinnant_Tp
1960fc4bff0cSOlivier Girouxatomic_exchange(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
19619847abacSHoward Hinnant{
1962c772a620SHoward Hinnant    return __o->exchange(__d);
19639847abacSHoward Hinnant}
19649847abacSHoward Hinnant
19659847abacSHoward Hinnant// atomic_exchange_explicit
19669847abacSHoward Hinnant
19679847abacSHoward Hinnanttemplate <class _Tp>
19686de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
19699847abacSHoward Hinnant_Tp
1970fc4bff0cSOlivier Girouxatomic_exchange_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT
19719847abacSHoward Hinnant{
1972c772a620SHoward Hinnant    return __o->exchange(__d, __m);
19739847abacSHoward Hinnant}
19749847abacSHoward Hinnant
19759847abacSHoward Hinnanttemplate <class _Tp>
19766de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
19779847abacSHoward Hinnant_Tp
1978fc4bff0cSOlivier Girouxatomic_exchange_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT
19799847abacSHoward Hinnant{
1980c772a620SHoward Hinnant    return __o->exchange(__d, __m);
19819847abacSHoward Hinnant}
19829847abacSHoward Hinnant
19839847abacSHoward Hinnant// atomic_compare_exchange_weak
19849847abacSHoward Hinnant
19859847abacSHoward Hinnanttemplate <class _Tp>
19866de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
19879847abacSHoward Hinnantbool
1988fc4bff0cSOlivier Girouxatomic_compare_exchange_weak(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT
19899847abacSHoward Hinnant{
1990c772a620SHoward Hinnant    return __o->compare_exchange_weak(*__e, __d);
19919847abacSHoward Hinnant}
19929847abacSHoward Hinnant
19939847abacSHoward Hinnanttemplate <class _Tp>
19946de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
19959847abacSHoward Hinnantbool
1996fc4bff0cSOlivier Girouxatomic_compare_exchange_weak(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT
19979847abacSHoward Hinnant{
1998c772a620SHoward Hinnant    return __o->compare_exchange_weak(*__e, __d);
19999847abacSHoward Hinnant}
20009847abacSHoward Hinnant
20019847abacSHoward Hinnant// atomic_compare_exchange_strong
20029847abacSHoward Hinnant
20039847abacSHoward Hinnanttemplate <class _Tp>
20046de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
20059847abacSHoward Hinnantbool
2006fc4bff0cSOlivier Girouxatomic_compare_exchange_strong(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT
20079847abacSHoward Hinnant{
2008c772a620SHoward Hinnant    return __o->compare_exchange_strong(*__e, __d);
20099847abacSHoward Hinnant}
20109847abacSHoward Hinnant
20119847abacSHoward Hinnanttemplate <class _Tp>
20126de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
20139847abacSHoward Hinnantbool
2014fc4bff0cSOlivier Girouxatomic_compare_exchange_strong(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT
20159847abacSHoward Hinnant{
2016c772a620SHoward Hinnant    return __o->compare_exchange_strong(*__e, __d);
20179847abacSHoward Hinnant}
20189847abacSHoward Hinnant
20199847abacSHoward Hinnant// atomic_compare_exchange_weak_explicit
20209847abacSHoward Hinnant
20219847abacSHoward Hinnanttemplate <class _Tp>
20226de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
20239847abacSHoward Hinnantbool
2024fc4bff0cSOlivier Girouxatomic_compare_exchange_weak_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e,
2025fc4bff0cSOlivier Giroux                                      typename atomic<_Tp>::value_type __d,
2026d01320c2SHoward Hinnant                                      memory_order __s, memory_order __f) _NOEXCEPT
2027faf2a813SEric Fiselier  _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
20289847abacSHoward Hinnant{
2029c772a620SHoward Hinnant    return __o->compare_exchange_weak(*__e, __d, __s, __f);
20309847abacSHoward Hinnant}
20319847abacSHoward Hinnant
20329847abacSHoward Hinnanttemplate <class _Tp>
20336de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
20349847abacSHoward Hinnantbool
2035fc4bff0cSOlivier Girouxatomic_compare_exchange_weak_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d,
2036d01320c2SHoward Hinnant                                      memory_order __s, memory_order __f) _NOEXCEPT
2037faf2a813SEric Fiselier  _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
20389847abacSHoward Hinnant{
2039c772a620SHoward Hinnant    return __o->compare_exchange_weak(*__e, __d, __s, __f);
20409847abacSHoward Hinnant}
20419847abacSHoward Hinnant
20429847abacSHoward Hinnant// atomic_compare_exchange_strong_explicit
20439847abacSHoward Hinnant
20449847abacSHoward Hinnanttemplate <class _Tp>
20456de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
20469847abacSHoward Hinnantbool
20479847abacSHoward Hinnantatomic_compare_exchange_strong_explicit(volatile atomic<_Tp>* __o,
2048fc4bff0cSOlivier Giroux                                        typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d,
2049d01320c2SHoward Hinnant                                        memory_order __s, memory_order __f) _NOEXCEPT
2050faf2a813SEric Fiselier  _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
20519847abacSHoward Hinnant{
2052c772a620SHoward Hinnant    return __o->compare_exchange_strong(*__e, __d, __s, __f);
20539847abacSHoward Hinnant}
20549847abacSHoward Hinnant
20559847abacSHoward Hinnanttemplate <class _Tp>
20566de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
20579847abacSHoward Hinnantbool
2058fc4bff0cSOlivier Girouxatomic_compare_exchange_strong_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e,
2059fc4bff0cSOlivier Giroux                                        typename atomic<_Tp>::value_type __d,
2060d01320c2SHoward Hinnant                                        memory_order __s, memory_order __f) _NOEXCEPT
2061faf2a813SEric Fiselier  _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
20629847abacSHoward Hinnant{
2063c772a620SHoward Hinnant    return __o->compare_exchange_strong(*__e, __d, __s, __f);
20649847abacSHoward Hinnant}
20659847abacSHoward Hinnant
206654fa9ecdSOlivier Giroux// atomic_wait
206754fa9ecdSOlivier Giroux
206854fa9ecdSOlivier Girouxtemplate <class _Tp>
206946c38761SLouis Dionne_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
207054fa9ecdSOlivier Girouxvoid atomic_wait(const volatile atomic<_Tp>* __o,
207154fa9ecdSOlivier Giroux                 typename atomic<_Tp>::value_type __v) _NOEXCEPT
207254fa9ecdSOlivier Giroux{
207354fa9ecdSOlivier Giroux    return __o->wait(__v);
207454fa9ecdSOlivier Giroux}
207554fa9ecdSOlivier Giroux
207654fa9ecdSOlivier Girouxtemplate <class _Tp>
207746c38761SLouis Dionne_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
207854fa9ecdSOlivier Girouxvoid atomic_wait(const atomic<_Tp>* __o,
207954fa9ecdSOlivier Giroux                 typename atomic<_Tp>::value_type __v) _NOEXCEPT
208054fa9ecdSOlivier Giroux{
208154fa9ecdSOlivier Giroux    return __o->wait(__v);
208254fa9ecdSOlivier Giroux}
208354fa9ecdSOlivier Giroux
208454fa9ecdSOlivier Giroux// atomic_wait_explicit
208554fa9ecdSOlivier Giroux
208654fa9ecdSOlivier Girouxtemplate <class _Tp>
208746c38761SLouis Dionne_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
208854fa9ecdSOlivier Girouxvoid atomic_wait_explicit(const volatile atomic<_Tp>* __o,
208954fa9ecdSOlivier Giroux                          typename atomic<_Tp>::value_type __v,
209054fa9ecdSOlivier Giroux                          memory_order __m) _NOEXCEPT
209154fa9ecdSOlivier Giroux  _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
209254fa9ecdSOlivier Giroux{
209354fa9ecdSOlivier Giroux    return __o->wait(__v, __m);
209454fa9ecdSOlivier Giroux}
209554fa9ecdSOlivier Giroux
209654fa9ecdSOlivier Girouxtemplate <class _Tp>
209746c38761SLouis Dionne_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
209854fa9ecdSOlivier Girouxvoid atomic_wait_explicit(const atomic<_Tp>* __o,
209954fa9ecdSOlivier Giroux                          typename atomic<_Tp>::value_type __v,
210054fa9ecdSOlivier Giroux                          memory_order __m) _NOEXCEPT
210154fa9ecdSOlivier Giroux  _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
210254fa9ecdSOlivier Giroux{
210354fa9ecdSOlivier Giroux    return __o->wait(__v, __m);
210454fa9ecdSOlivier Giroux}
210554fa9ecdSOlivier Giroux
210654fa9ecdSOlivier Giroux// atomic_notify_one
210754fa9ecdSOlivier Giroux
210854fa9ecdSOlivier Girouxtemplate <class _Tp>
210946c38761SLouis Dionne_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
211054fa9ecdSOlivier Girouxvoid atomic_notify_one(volatile atomic<_Tp>* __o) _NOEXCEPT
211154fa9ecdSOlivier Giroux{
211254fa9ecdSOlivier Giroux    __o->notify_one();
211354fa9ecdSOlivier Giroux}
211454fa9ecdSOlivier Girouxtemplate <class _Tp>
211546c38761SLouis Dionne_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
211654fa9ecdSOlivier Girouxvoid atomic_notify_one(atomic<_Tp>* __o) _NOEXCEPT
211754fa9ecdSOlivier Giroux{
211854fa9ecdSOlivier Giroux    __o->notify_one();
211954fa9ecdSOlivier Giroux}
212054fa9ecdSOlivier Giroux
212154fa9ecdSOlivier Giroux// atomic_notify_one
212254fa9ecdSOlivier Giroux
212354fa9ecdSOlivier Girouxtemplate <class _Tp>
212446c38761SLouis Dionne_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
212554fa9ecdSOlivier Girouxvoid atomic_notify_all(volatile atomic<_Tp>* __o) _NOEXCEPT
212654fa9ecdSOlivier Giroux{
212754fa9ecdSOlivier Giroux    __o->notify_all();
212854fa9ecdSOlivier Giroux}
212954fa9ecdSOlivier Girouxtemplate <class _Tp>
213046c38761SLouis Dionne_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
213154fa9ecdSOlivier Girouxvoid atomic_notify_all(atomic<_Tp>* __o) _NOEXCEPT
213254fa9ecdSOlivier Giroux{
213354fa9ecdSOlivier Giroux    __o->notify_all();
213454fa9ecdSOlivier Giroux}
213554fa9ecdSOlivier Giroux
2136c772a620SHoward Hinnant// atomic_fetch_add
21379847abacSHoward Hinnant
21389847abacSHoward Hinnanttemplate <class _Tp>
21396de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
2140c772a620SHoward Hinnant_Tp
2141fc4bff0cSOlivier Girouxatomic_fetch_add(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT
21429847abacSHoward Hinnant{
2143c772a620SHoward Hinnant    return __o->fetch_add(__op);
2144c772a620SHoward Hinnant}
21459847abacSHoward Hinnant
2146c772a620SHoward Hinnanttemplate <class _Tp>
21476de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
2148c772a620SHoward Hinnant_Tp
2149fc4bff0cSOlivier Girouxatomic_fetch_add(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT
2150c772a620SHoward Hinnant{
2151c772a620SHoward Hinnant    return __o->fetch_add(__op);
2152c772a620SHoward Hinnant}
2153c772a620SHoward Hinnant
2154c772a620SHoward Hinnant// atomic_fetch_add_explicit
2155c772a620SHoward Hinnant
2156c772a620SHoward Hinnanttemplate <class _Tp>
21576de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
2158aac5b84dSMark de Wever_Tp atomic_fetch_add_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT
2159c772a620SHoward Hinnant{
2160c772a620SHoward Hinnant    return __o->fetch_add(__op, __m);
2161c772a620SHoward Hinnant}
2162c772a620SHoward Hinnant
2163c772a620SHoward Hinnanttemplate <class _Tp>
21646de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
2165aac5b84dSMark de Wever_Tp atomic_fetch_add_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT
216659fc8677SOlivier Giroux{
216759fc8677SOlivier Giroux    return __o->fetch_add(__op, __m);
216859fc8677SOlivier Giroux}
216959fc8677SOlivier Giroux
2170c772a620SHoward Hinnant// atomic_fetch_sub
2171c772a620SHoward Hinnant
2172c772a620SHoward Hinnanttemplate <class _Tp>
21736de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
2174aac5b84dSMark de Wever_Tp atomic_fetch_sub(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT
2175c772a620SHoward Hinnant{
2176c772a620SHoward Hinnant    return __o->fetch_sub(__op);
2177c772a620SHoward Hinnant}
2178c772a620SHoward Hinnant
2179c772a620SHoward Hinnanttemplate <class _Tp>
21806de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
2181aac5b84dSMark de Wever_Tp atomic_fetch_sub(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT
218259fc8677SOlivier Giroux{
218359fc8677SOlivier Giroux    return __o->fetch_sub(__op);
218459fc8677SOlivier Giroux}
218559fc8677SOlivier Giroux
2186c772a620SHoward Hinnant// atomic_fetch_sub_explicit
2187c772a620SHoward Hinnant
2188c772a620SHoward Hinnanttemplate <class _Tp>
21896de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
2190aac5b84dSMark de Wever_Tp atomic_fetch_sub_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT
2191c772a620SHoward Hinnant{
2192c772a620SHoward Hinnant    return __o->fetch_sub(__op, __m);
2193c772a620SHoward Hinnant}
2194c772a620SHoward Hinnant
2195c772a620SHoward Hinnanttemplate <class _Tp>
21966de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
2197aac5b84dSMark de Wever_Tp atomic_fetch_sub_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT
219859fc8677SOlivier Giroux{
219959fc8677SOlivier Giroux    return __o->fetch_sub(__op, __m);
220059fc8677SOlivier Giroux}
220159fc8677SOlivier Giroux
2202c772a620SHoward Hinnant// atomic_fetch_and
2203c772a620SHoward Hinnant
2204c772a620SHoward Hinnanttemplate <class _Tp>
22056de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
2206c772a620SHoward Hinnanttypename enable_if
2207c772a620SHoward Hinnant<
2208c772a620SHoward Hinnant    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2209c772a620SHoward Hinnant    _Tp
2210c772a620SHoward Hinnant>::type
2211fc4bff0cSOlivier Girouxatomic_fetch_and(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
2212c772a620SHoward Hinnant{
2213c772a620SHoward Hinnant    return __o->fetch_and(__op);
2214c772a620SHoward Hinnant}
2215c772a620SHoward Hinnant
2216c772a620SHoward Hinnanttemplate <class _Tp>
22176de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
2218c772a620SHoward Hinnanttypename enable_if
2219c772a620SHoward Hinnant<
2220c772a620SHoward Hinnant    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2221c772a620SHoward Hinnant    _Tp
2222c772a620SHoward Hinnant>::type
2223fc4bff0cSOlivier Girouxatomic_fetch_and(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
2224c772a620SHoward Hinnant{
2225c772a620SHoward Hinnant    return __o->fetch_and(__op);
2226c772a620SHoward Hinnant}
2227c772a620SHoward Hinnant
2228c772a620SHoward Hinnant// atomic_fetch_and_explicit
2229c772a620SHoward Hinnant
2230c772a620SHoward Hinnanttemplate <class _Tp>
22316de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
2232c772a620SHoward Hinnanttypename enable_if
2233c772a620SHoward Hinnant<
2234c772a620SHoward Hinnant    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2235c772a620SHoward Hinnant    _Tp
2236c772a620SHoward Hinnant>::type
2237fc4bff0cSOlivier Girouxatomic_fetch_and_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
2238c772a620SHoward Hinnant{
2239c772a620SHoward Hinnant    return __o->fetch_and(__op, __m);
2240c772a620SHoward Hinnant}
2241c772a620SHoward Hinnant
2242c772a620SHoward Hinnanttemplate <class _Tp>
22436de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
2244c772a620SHoward Hinnanttypename enable_if
2245c772a620SHoward Hinnant<
2246c772a620SHoward Hinnant    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2247c772a620SHoward Hinnant    _Tp
2248c772a620SHoward Hinnant>::type
2249fc4bff0cSOlivier Girouxatomic_fetch_and_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
2250c772a620SHoward Hinnant{
2251c772a620SHoward Hinnant    return __o->fetch_and(__op, __m);
2252c772a620SHoward Hinnant}
2253c772a620SHoward Hinnant
2254c772a620SHoward Hinnant// atomic_fetch_or
2255c772a620SHoward Hinnant
2256c772a620SHoward Hinnanttemplate <class _Tp>
22576de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
2258c772a620SHoward Hinnanttypename enable_if
2259c772a620SHoward Hinnant<
2260c772a620SHoward Hinnant    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2261c772a620SHoward Hinnant    _Tp
2262c772a620SHoward Hinnant>::type
2263fc4bff0cSOlivier Girouxatomic_fetch_or(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
2264c772a620SHoward Hinnant{
2265c772a620SHoward Hinnant    return __o->fetch_or(__op);
2266c772a620SHoward Hinnant}
2267c772a620SHoward Hinnant
2268c772a620SHoward Hinnanttemplate <class _Tp>
22696de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
2270c772a620SHoward Hinnanttypename enable_if
2271c772a620SHoward Hinnant<
2272c772a620SHoward Hinnant    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2273c772a620SHoward Hinnant    _Tp
2274c772a620SHoward Hinnant>::type
2275fc4bff0cSOlivier Girouxatomic_fetch_or(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
2276c772a620SHoward Hinnant{
2277c772a620SHoward Hinnant    return __o->fetch_or(__op);
2278c772a620SHoward Hinnant}
2279c772a620SHoward Hinnant
2280c772a620SHoward Hinnant// atomic_fetch_or_explicit
2281c772a620SHoward Hinnant
2282c772a620SHoward Hinnanttemplate <class _Tp>
22836de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
2284c772a620SHoward Hinnanttypename enable_if
2285c772a620SHoward Hinnant<
2286c772a620SHoward Hinnant    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2287c772a620SHoward Hinnant    _Tp
2288c772a620SHoward Hinnant>::type
2289fc4bff0cSOlivier Girouxatomic_fetch_or_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
2290c772a620SHoward Hinnant{
2291c772a620SHoward Hinnant    return __o->fetch_or(__op, __m);
2292c772a620SHoward Hinnant}
2293c772a620SHoward Hinnant
2294c772a620SHoward Hinnanttemplate <class _Tp>
22956de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
2296c772a620SHoward Hinnanttypename enable_if
2297c772a620SHoward Hinnant<
2298c772a620SHoward Hinnant    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2299c772a620SHoward Hinnant    _Tp
2300c772a620SHoward Hinnant>::type
2301fc4bff0cSOlivier Girouxatomic_fetch_or_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
2302c772a620SHoward Hinnant{
2303c772a620SHoward Hinnant    return __o->fetch_or(__op, __m);
2304c772a620SHoward Hinnant}
2305c772a620SHoward Hinnant
2306c772a620SHoward Hinnant// atomic_fetch_xor
2307c772a620SHoward Hinnant
2308c772a620SHoward Hinnanttemplate <class _Tp>
23096de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
2310c772a620SHoward Hinnanttypename enable_if
2311c772a620SHoward Hinnant<
2312c772a620SHoward Hinnant    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2313c772a620SHoward Hinnant    _Tp
2314c772a620SHoward Hinnant>::type
2315fc4bff0cSOlivier Girouxatomic_fetch_xor(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
2316c772a620SHoward Hinnant{
2317c772a620SHoward Hinnant    return __o->fetch_xor(__op);
2318c772a620SHoward Hinnant}
2319c772a620SHoward Hinnant
2320c772a620SHoward Hinnanttemplate <class _Tp>
23216de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
2322c772a620SHoward Hinnanttypename enable_if
2323c772a620SHoward Hinnant<
2324c772a620SHoward Hinnant    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2325c772a620SHoward Hinnant    _Tp
2326c772a620SHoward Hinnant>::type
2327fc4bff0cSOlivier Girouxatomic_fetch_xor(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
2328c772a620SHoward Hinnant{
2329c772a620SHoward Hinnant    return __o->fetch_xor(__op);
2330c772a620SHoward Hinnant}
2331c772a620SHoward Hinnant
2332c772a620SHoward Hinnant// atomic_fetch_xor_explicit
2333c772a620SHoward Hinnant
2334c772a620SHoward Hinnanttemplate <class _Tp>
23356de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
2336c772a620SHoward Hinnanttypename enable_if
2337c772a620SHoward Hinnant<
2338c772a620SHoward Hinnant    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2339c772a620SHoward Hinnant    _Tp
2340c772a620SHoward Hinnant>::type
2341fc4bff0cSOlivier Girouxatomic_fetch_xor_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
2342c772a620SHoward Hinnant{
2343c772a620SHoward Hinnant    return __o->fetch_xor(__op, __m);
2344c772a620SHoward Hinnant}
2345c772a620SHoward Hinnant
2346c772a620SHoward Hinnanttemplate <class _Tp>
23476de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
2348c772a620SHoward Hinnanttypename enable_if
2349c772a620SHoward Hinnant<
2350c772a620SHoward Hinnant    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2351c772a620SHoward Hinnant    _Tp
2352c772a620SHoward Hinnant>::type
2353fc4bff0cSOlivier Girouxatomic_fetch_xor_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
2354c772a620SHoward Hinnant{
2355c772a620SHoward Hinnant    return __o->fetch_xor(__op, __m);
2356c772a620SHoward Hinnant}
23579847abacSHoward Hinnant
2358b5452b3dSHoward Hinnant// flag type and operations
2359b5452b3dSHoward Hinnant
2360b5452b3dSHoward Hinnanttypedef struct atomic_flag
2361b5452b3dSHoward Hinnant{
23626de760acSDavide Italiano    __cxx_atomic_impl<_LIBCPP_ATOMIC_FLAG_TYPE> __a_;
2363b5452b3dSHoward Hinnant
2364b5452b3dSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
236554fa9ecdSOlivier Giroux    bool test(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
236654fa9ecdSOlivier Giroux        {return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m);}
236754fa9ecdSOlivier Giroux    _LIBCPP_INLINE_VISIBILITY
236854fa9ecdSOlivier Giroux    bool test(memory_order __m = memory_order_seq_cst) const _NOEXCEPT
236954fa9ecdSOlivier Giroux        {return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m);}
237054fa9ecdSOlivier Giroux
237154fa9ecdSOlivier Giroux    _LIBCPP_INLINE_VISIBILITY
2372d01320c2SHoward Hinnant    bool test_and_set(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
23736de760acSDavide Italiano        {return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);}
2374b5452b3dSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
2375d01320c2SHoward Hinnant    bool test_and_set(memory_order __m = memory_order_seq_cst) _NOEXCEPT
23766de760acSDavide Italiano        {return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);}
2377b5452b3dSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
2378d01320c2SHoward Hinnant    void clear(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
23796de760acSDavide Italiano        {__cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);}
2380b5452b3dSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
2381d01320c2SHoward Hinnant    void clear(memory_order __m = memory_order_seq_cst) _NOEXCEPT
23826de760acSDavide Italiano        {__cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);}
2383b5452b3dSHoward Hinnant
238446c38761SLouis Dionne    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
238554fa9ecdSOlivier Giroux    void wait(bool __v, memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
238654fa9ecdSOlivier Giroux        {__cxx_atomic_wait(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);}
238746c38761SLouis Dionne    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
238854fa9ecdSOlivier Giroux    void wait(bool __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT
238954fa9ecdSOlivier Giroux        {__cxx_atomic_wait(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);}
239046c38761SLouis Dionne    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
239154fa9ecdSOlivier Giroux    void notify_one() volatile _NOEXCEPT
239254fa9ecdSOlivier Giroux        {__cxx_atomic_notify_one(&__a_);}
239346c38761SLouis Dionne    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
239454fa9ecdSOlivier Giroux    void notify_one() _NOEXCEPT
239554fa9ecdSOlivier Giroux        {__cxx_atomic_notify_one(&__a_);}
239646c38761SLouis Dionne    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
239754fa9ecdSOlivier Giroux    void notify_all() volatile _NOEXCEPT
239854fa9ecdSOlivier Giroux        {__cxx_atomic_notify_all(&__a_);}
239946c38761SLouis Dionne    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
240054fa9ecdSOlivier Giroux    void notify_all() _NOEXCEPT
240154fa9ecdSOlivier Giroux        {__cxx_atomic_notify_all(&__a_);}
240254fa9ecdSOlivier Giroux
240356aac567SRaul Tambre#if _LIBCPP_STD_VER > 17
240456aac567SRaul Tambre    _LIBCPP_INLINE_VISIBILITY constexpr
240556aac567SRaul Tambre    atomic_flag() _NOEXCEPT : __a_(false) {}
240656aac567SRaul Tambre#else
240754fa9ecdSOlivier Giroux    _LIBCPP_INLINE_VISIBILITY
24084955095fSNikolas Klauser    atomic_flag() _NOEXCEPT = default;
240956aac567SRaul Tambre#endif
2410da9ca0b4SHoward Hinnant
24113df56fddSMarshall Clow    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
241215a29721SEric Fiselier    atomic_flag(bool __b) _NOEXCEPT : __a_(__b) {} // EXTENSION
2413b5452b3dSHoward Hinnant
2414b5452b3dSHoward Hinnant    atomic_flag(const atomic_flag&) = delete;
2415b5452b3dSHoward Hinnant    atomic_flag& operator=(const atomic_flag&) = delete;
2416b5452b3dSHoward Hinnant    atomic_flag& operator=(const atomic_flag&) volatile = delete;
2417318507edSNikolas Klauser
2418b5452b3dSHoward Hinnant} atomic_flag;
2419b5452b3dSHoward Hinnant
242054fa9ecdSOlivier Giroux
242154fa9ecdSOlivier Girouxinline _LIBCPP_INLINE_VISIBILITY
242254fa9ecdSOlivier Girouxbool
242354fa9ecdSOlivier Girouxatomic_flag_test(const volatile atomic_flag* __o) _NOEXCEPT
242454fa9ecdSOlivier Giroux{
242554fa9ecdSOlivier Giroux    return __o->test();
242654fa9ecdSOlivier Giroux}
242754fa9ecdSOlivier Giroux
242854fa9ecdSOlivier Girouxinline _LIBCPP_INLINE_VISIBILITY
242954fa9ecdSOlivier Girouxbool
243054fa9ecdSOlivier Girouxatomic_flag_test(const atomic_flag* __o) _NOEXCEPT
243154fa9ecdSOlivier Giroux{
243254fa9ecdSOlivier Giroux    return __o->test();
243354fa9ecdSOlivier Giroux}
243454fa9ecdSOlivier Giroux
243554fa9ecdSOlivier Girouxinline _LIBCPP_INLINE_VISIBILITY
243654fa9ecdSOlivier Girouxbool
243754fa9ecdSOlivier Girouxatomic_flag_test_explicit(const volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
243854fa9ecdSOlivier Giroux{
243954fa9ecdSOlivier Giroux    return __o->test(__m);
244054fa9ecdSOlivier Giroux}
244154fa9ecdSOlivier Giroux
244254fa9ecdSOlivier Girouxinline _LIBCPP_INLINE_VISIBILITY
244354fa9ecdSOlivier Girouxbool
244454fa9ecdSOlivier Girouxatomic_flag_test_explicit(const atomic_flag* __o, memory_order __m) _NOEXCEPT
244554fa9ecdSOlivier Giroux{
244654fa9ecdSOlivier Giroux    return __o->test(__m);
244754fa9ecdSOlivier Giroux}
244854fa9ecdSOlivier Giroux
2449b5452b3dSHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
2450b5452b3dSHoward Hinnantbool
2451d01320c2SHoward Hinnantatomic_flag_test_and_set(volatile atomic_flag* __o) _NOEXCEPT
2452b5452b3dSHoward Hinnant{
2453b5452b3dSHoward Hinnant    return __o->test_and_set();
2454b5452b3dSHoward Hinnant}
2455b5452b3dSHoward Hinnant
2456b5452b3dSHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
2457b5452b3dSHoward Hinnantbool
2458d01320c2SHoward Hinnantatomic_flag_test_and_set(atomic_flag* __o) _NOEXCEPT
2459b5452b3dSHoward Hinnant{
2460b5452b3dSHoward Hinnant    return __o->test_and_set();
2461b5452b3dSHoward Hinnant}
2462b5452b3dSHoward Hinnant
2463b5452b3dSHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
2464b5452b3dSHoward Hinnantbool
2465d01320c2SHoward Hinnantatomic_flag_test_and_set_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
2466b5452b3dSHoward Hinnant{
2467b5452b3dSHoward Hinnant    return __o->test_and_set(__m);
2468b5452b3dSHoward Hinnant}
2469b5452b3dSHoward Hinnant
2470b5452b3dSHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
2471b5452b3dSHoward Hinnantbool
2472d01320c2SHoward Hinnantatomic_flag_test_and_set_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT
2473b5452b3dSHoward Hinnant{
2474b5452b3dSHoward Hinnant    return __o->test_and_set(__m);
2475b5452b3dSHoward Hinnant}
2476b5452b3dSHoward Hinnant
2477b5452b3dSHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
2478b5452b3dSHoward Hinnantvoid
2479d01320c2SHoward Hinnantatomic_flag_clear(volatile atomic_flag* __o) _NOEXCEPT
2480b5452b3dSHoward Hinnant{
2481b5452b3dSHoward Hinnant    __o->clear();
2482b5452b3dSHoward Hinnant}
2483b5452b3dSHoward Hinnant
2484b5452b3dSHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
2485b5452b3dSHoward Hinnantvoid
2486d01320c2SHoward Hinnantatomic_flag_clear(atomic_flag* __o) _NOEXCEPT
2487b5452b3dSHoward Hinnant{
2488b5452b3dSHoward Hinnant    __o->clear();
2489b5452b3dSHoward Hinnant}
2490b5452b3dSHoward Hinnant
2491b5452b3dSHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
2492b5452b3dSHoward Hinnantvoid
2493d01320c2SHoward Hinnantatomic_flag_clear_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
2494b5452b3dSHoward Hinnant{
2495b5452b3dSHoward Hinnant    __o->clear(__m);
2496b5452b3dSHoward Hinnant}
2497b5452b3dSHoward Hinnant
2498b5452b3dSHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
2499b5452b3dSHoward Hinnantvoid
2500d01320c2SHoward Hinnantatomic_flag_clear_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT
2501b5452b3dSHoward Hinnant{
2502b5452b3dSHoward Hinnant    __o->clear(__m);
2503b5452b3dSHoward Hinnant}
2504b5452b3dSHoward Hinnant
250546c38761SLouis Dionneinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
250654fa9ecdSOlivier Girouxvoid
250754fa9ecdSOlivier Girouxatomic_flag_wait(const volatile atomic_flag* __o, bool __v) _NOEXCEPT
250854fa9ecdSOlivier Giroux{
250954fa9ecdSOlivier Giroux    __o->wait(__v);
251054fa9ecdSOlivier Giroux}
251154fa9ecdSOlivier Giroux
251246c38761SLouis Dionneinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
251354fa9ecdSOlivier Girouxvoid
251454fa9ecdSOlivier Girouxatomic_flag_wait(const atomic_flag* __o, bool __v) _NOEXCEPT
251554fa9ecdSOlivier Giroux{
251654fa9ecdSOlivier Giroux    __o->wait(__v);
251754fa9ecdSOlivier Giroux}
251854fa9ecdSOlivier Giroux
251946c38761SLouis Dionneinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
252054fa9ecdSOlivier Girouxvoid
252154fa9ecdSOlivier Girouxatomic_flag_wait_explicit(const volatile atomic_flag* __o,
252254fa9ecdSOlivier Giroux                          bool __v, memory_order __m) _NOEXCEPT
252354fa9ecdSOlivier Giroux{
252454fa9ecdSOlivier Giroux    __o->wait(__v, __m);
252554fa9ecdSOlivier Giroux}
252654fa9ecdSOlivier Giroux
252746c38761SLouis Dionneinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
252854fa9ecdSOlivier Girouxvoid
252954fa9ecdSOlivier Girouxatomic_flag_wait_explicit(const atomic_flag* __o,
253054fa9ecdSOlivier Giroux                          bool __v, memory_order __m) _NOEXCEPT
253154fa9ecdSOlivier Giroux{
253254fa9ecdSOlivier Giroux    __o->wait(__v, __m);
253354fa9ecdSOlivier Giroux}
253454fa9ecdSOlivier Giroux
253546c38761SLouis Dionneinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
253654fa9ecdSOlivier Girouxvoid
253754fa9ecdSOlivier Girouxatomic_flag_notify_one(volatile atomic_flag* __o) _NOEXCEPT
253854fa9ecdSOlivier Giroux{
253954fa9ecdSOlivier Giroux    __o->notify_one();
254054fa9ecdSOlivier Giroux}
254154fa9ecdSOlivier Giroux
254246c38761SLouis Dionneinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
254354fa9ecdSOlivier Girouxvoid
254454fa9ecdSOlivier Girouxatomic_flag_notify_one(atomic_flag* __o) _NOEXCEPT
254554fa9ecdSOlivier Giroux{
254654fa9ecdSOlivier Giroux    __o->notify_one();
254754fa9ecdSOlivier Giroux}
254854fa9ecdSOlivier Giroux
254946c38761SLouis Dionneinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
255054fa9ecdSOlivier Girouxvoid
255154fa9ecdSOlivier Girouxatomic_flag_notify_all(volatile atomic_flag* __o) _NOEXCEPT
255254fa9ecdSOlivier Giroux{
255354fa9ecdSOlivier Giroux    __o->notify_all();
255454fa9ecdSOlivier Giroux}
255554fa9ecdSOlivier Giroux
255646c38761SLouis Dionneinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
255754fa9ecdSOlivier Girouxvoid
255854fa9ecdSOlivier Girouxatomic_flag_notify_all(atomic_flag* __o) _NOEXCEPT
255954fa9ecdSOlivier Giroux{
256054fa9ecdSOlivier Giroux    __o->notify_all();
256154fa9ecdSOlivier Giroux}
256254fa9ecdSOlivier Giroux
2563b5452b3dSHoward Hinnant// fences
2564b5452b3dSHoward Hinnant
2565b5452b3dSHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
2566b5452b3dSHoward Hinnantvoid
2567d01320c2SHoward Hinnantatomic_thread_fence(memory_order __m) _NOEXCEPT
2568b5452b3dSHoward Hinnant{
25696de760acSDavide Italiano    __cxx_atomic_thread_fence(__m);
2570b5452b3dSHoward Hinnant}
2571b5452b3dSHoward Hinnant
2572b5452b3dSHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
2573b5452b3dSHoward Hinnantvoid
2574d01320c2SHoward Hinnantatomic_signal_fence(memory_order __m) _NOEXCEPT
2575b5452b3dSHoward Hinnant{
25766de760acSDavide Italiano    __cxx_atomic_signal_fence(__m);
2577b5452b3dSHoward Hinnant}
2578b5452b3dSHoward Hinnant
2579c5f5f0a1SHoward Hinnant// Atomics for standard typedef types
2580c5f5f0a1SHoward Hinnant
258111467662SHoward Hinnanttypedef atomic<bool>               atomic_bool;
2582c5f5f0a1SHoward Hinnanttypedef atomic<char>               atomic_char;
2583c5f5f0a1SHoward Hinnanttypedef atomic<signed char>        atomic_schar;
2584c5f5f0a1SHoward Hinnanttypedef atomic<unsigned char>      atomic_uchar;
2585c5f5f0a1SHoward Hinnanttypedef atomic<short>              atomic_short;
2586c5f5f0a1SHoward Hinnanttypedef atomic<unsigned short>     atomic_ushort;
2587c5f5f0a1SHoward Hinnanttypedef atomic<int>                atomic_int;
2588c5f5f0a1SHoward Hinnanttypedef atomic<unsigned int>       atomic_uint;
2589c5f5f0a1SHoward Hinnanttypedef atomic<long>               atomic_long;
2590c5f5f0a1SHoward Hinnanttypedef atomic<unsigned long>      atomic_ulong;
2591c5f5f0a1SHoward Hinnanttypedef atomic<long long>          atomic_llong;
2592c5f5f0a1SHoward Hinnanttypedef atomic<unsigned long long> atomic_ullong;
25935c40c994SArthur O'Dwyer#ifndef _LIBCPP_HAS_NO_CHAR8_T
25949c97e4efSMarek Kurdejtypedef atomic<char8_t>            atomic_char8_t;
25959c97e4efSMarek Kurdej#endif
2596c5f5f0a1SHoward Hinnanttypedef atomic<char16_t>           atomic_char16_t;
2597c5f5f0a1SHoward Hinnanttypedef atomic<char32_t>           atomic_char32_t;
2598f4c1258dSLouis Dionne#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
2599c5f5f0a1SHoward Hinnanttypedef atomic<wchar_t>            atomic_wchar_t;
2600f4c1258dSLouis Dionne#endif
2601c5f5f0a1SHoward Hinnant
2602c5f5f0a1SHoward Hinnanttypedef atomic<int_least8_t>   atomic_int_least8_t;
2603c5f5f0a1SHoward Hinnanttypedef atomic<uint_least8_t>  atomic_uint_least8_t;
2604c5f5f0a1SHoward Hinnanttypedef atomic<int_least16_t>  atomic_int_least16_t;
2605c5f5f0a1SHoward Hinnanttypedef atomic<uint_least16_t> atomic_uint_least16_t;
2606c5f5f0a1SHoward Hinnanttypedef atomic<int_least32_t>  atomic_int_least32_t;
2607c5f5f0a1SHoward Hinnanttypedef atomic<uint_least32_t> atomic_uint_least32_t;
2608c5f5f0a1SHoward Hinnanttypedef atomic<int_least64_t>  atomic_int_least64_t;
2609c5f5f0a1SHoward Hinnanttypedef atomic<uint_least64_t> atomic_uint_least64_t;
2610c5f5f0a1SHoward Hinnant
2611c5f5f0a1SHoward Hinnanttypedef atomic<int_fast8_t>   atomic_int_fast8_t;
2612c5f5f0a1SHoward Hinnanttypedef atomic<uint_fast8_t>  atomic_uint_fast8_t;
2613c5f5f0a1SHoward Hinnanttypedef atomic<int_fast16_t>  atomic_int_fast16_t;
2614c5f5f0a1SHoward Hinnanttypedef atomic<uint_fast16_t> atomic_uint_fast16_t;
2615c5f5f0a1SHoward Hinnanttypedef atomic<int_fast32_t>  atomic_int_fast32_t;
2616c5f5f0a1SHoward Hinnanttypedef atomic<uint_fast32_t> atomic_uint_fast32_t;
2617c5f5f0a1SHoward Hinnanttypedef atomic<int_fast64_t>  atomic_int_fast64_t;
2618c5f5f0a1SHoward Hinnanttypedef atomic<uint_fast64_t> atomic_uint_fast64_t;
2619c5f5f0a1SHoward Hinnant
2620e766a87bSMarshall Clowtypedef atomic< int8_t>  atomic_int8_t;
2621e766a87bSMarshall Clowtypedef atomic<uint8_t>  atomic_uint8_t;
2622e766a87bSMarshall Clowtypedef atomic< int16_t> atomic_int16_t;
2623e766a87bSMarshall Clowtypedef atomic<uint16_t> atomic_uint16_t;
2624e766a87bSMarshall Clowtypedef atomic< int32_t> atomic_int32_t;
2625e766a87bSMarshall Clowtypedef atomic<uint32_t> atomic_uint32_t;
2626e766a87bSMarshall Clowtypedef atomic< int64_t> atomic_int64_t;
2627e766a87bSMarshall Clowtypedef atomic<uint64_t> atomic_uint64_t;
2628e766a87bSMarshall Clow
2629c5f5f0a1SHoward Hinnanttypedef atomic<intptr_t>  atomic_intptr_t;
2630c5f5f0a1SHoward Hinnanttypedef atomic<uintptr_t> atomic_uintptr_t;
2631c5f5f0a1SHoward Hinnanttypedef atomic<size_t>    atomic_size_t;
2632c5f5f0a1SHoward Hinnanttypedef atomic<ptrdiff_t> atomic_ptrdiff_t;
2633c5f5f0a1SHoward Hinnanttypedef atomic<intmax_t>  atomic_intmax_t;
2634c5f5f0a1SHoward Hinnanttypedef atomic<uintmax_t> atomic_uintmax_t;
2635c5f5f0a1SHoward Hinnant
263654fa9ecdSOlivier Giroux// atomic_*_lock_free : prefer the contention type most highly, then the largest lock-free type
263754fa9ecdSOlivier Giroux
263854fa9ecdSOlivier Giroux#ifdef __cpp_lib_atomic_is_always_lock_free
2639*d64394b8SLouis Dionne# define _LIBCPP_CONTENTION_LOCK_FREE ::std::__libcpp_is_always_lock_free<__cxx_contention_t>::__value
264054fa9ecdSOlivier Giroux#else
264154fa9ecdSOlivier Giroux# define _LIBCPP_CONTENTION_LOCK_FREE false
264254fa9ecdSOlivier Giroux#endif
264354fa9ecdSOlivier Giroux
264454fa9ecdSOlivier Giroux#if ATOMIC_LLONG_LOCK_FREE == 2
264554fa9ecdSOlivier Girouxtypedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, long long>::type          __libcpp_signed_lock_free;
264654fa9ecdSOlivier Girouxtypedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned long long>::type __libcpp_unsigned_lock_free;
264754fa9ecdSOlivier Giroux#elif ATOMIC_INT_LOCK_FREE == 2
264854fa9ecdSOlivier Girouxtypedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, int>::type                __libcpp_signed_lock_free;
264954fa9ecdSOlivier Girouxtypedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned int>::type       __libcpp_unsigned_lock_free;
265054fa9ecdSOlivier Giroux#elif ATOMIC_SHORT_LOCK_FREE == 2
265154fa9ecdSOlivier Girouxtypedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, short>::type              __libcpp_signed_lock_free;
265254fa9ecdSOlivier Girouxtypedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned short>::type     __libcpp_unsigned_lock_free;
265354fa9ecdSOlivier Giroux#elif ATOMIC_CHAR_LOCK_FREE == 2
265454fa9ecdSOlivier Girouxtypedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, char>::type               __libcpp_signed_lock_free;
265554fa9ecdSOlivier Girouxtypedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned char>::type      __libcpp_unsigned_lock_free;
265654fa9ecdSOlivier Giroux#else
265754fa9ecdSOlivier Giroux    // No signed/unsigned lock-free types
2658d5ab243cSBrian Cain#define _LIBCPP_NO_LOCK_FREE_TYPES
265954fa9ecdSOlivier Giroux#endif
266054fa9ecdSOlivier Giroux
2661d5ab243cSBrian Cain#if !defined(_LIBCPP_NO_LOCK_FREE_TYPES)
266254fa9ecdSOlivier Girouxtypedef atomic<__libcpp_signed_lock_free> atomic_signed_lock_free;
266354fa9ecdSOlivier Girouxtypedef atomic<__libcpp_unsigned_lock_free> atomic_unsigned_lock_free;
2664d5ab243cSBrian Cain#endif
266554fa9ecdSOlivier Giroux
266688efc1c7SHoward Hinnant#define ATOMIC_FLAG_INIT {false}
26672b672e24SHoward Hinnant#define ATOMIC_VAR_INIT(__v) {__v}
26682b672e24SHoward Hinnant
26694e730aebSRaul Tambre#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_DISABLE_DEPRECATION_WARNINGS)
26704e730aebSRaul Tambre# if defined(_LIBCPP_CLANG_VER) && _LIBCPP_CLANG_VER >= 1400
26714e730aebSRaul Tambre#  pragma clang deprecated(ATOMIC_VAR_INIT)
26724e730aebSRaul Tambre# endif
26734e730aebSRaul Tambre#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_DISABLE_DEPRECATION_WARNINGS)
26744e730aebSRaul Tambre
2675cd39d413SHoward Hinnant_LIBCPP_END_NAMESPACE_STD
2676cd39d413SHoward Hinnant
2677cd39d413SHoward Hinnant#endif // _LIBCPP_ATOMIC
2678