xref: /llvm-project-15.0.7/libcxx/include/atomic (revision 4e730aeb)
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
5212eadbc86SLouis Dionne#include <__availability>
522bfbd73f8SArthur O'Dwyer#include <__config>
52392832e48SLouis Dionne#include <__thread/poll_with_backoff.h>
5249847abacSHoward Hinnant#include <cstddef>
5259847abacSHoward Hinnant#include <cstdint>
52654fa9ecdSOlivier Giroux#include <cstring>
5279847abacSHoward Hinnant#include <type_traits>
528f56972e2SMarshall Clow#include <version>
529cd39d413SHoward Hinnant
53092832e48SLouis Dionne#ifndef _LIBCPP_HAS_NO_THREADS
53192832e48SLouis Dionne# include <__threading_support>
53292832e48SLouis Dionne#endif
53392832e48SLouis Dionne
534073458b1SHoward Hinnant#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
535cd39d413SHoward Hinnant#pragma GCC system_header
536073458b1SHoward Hinnant#endif
537cd39d413SHoward Hinnant
5386de760acSDavide Italiano#ifdef _LIBCPP_HAS_NO_ATOMIC_HEADER
539749adebaSEric Fiselier# error <atomic> is not implemented
540749adebaSEric Fiselier#endif
54185d3a702SVolodymyr Sapsai#ifdef kill_dependency
54285d3a702SVolodymyr Sapsai# error C++ standard library is incompatible with <stdatomic.h>
54385d3a702SVolodymyr Sapsai#endif
544b3fcc67fSJonathan Roelofs
545faf2a813SEric Fiselier#define _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) \
546faf2a813SEric Fiselier  _LIBCPP_DIAGNOSE_WARNING(__m == memory_order_consume || \
547faf2a813SEric Fiselier                           __m == memory_order_acquire || \
548faf2a813SEric Fiselier                           __m == memory_order_acq_rel,   \
549faf2a813SEric Fiselier                        "memory order argument to atomic operation is invalid")
550faf2a813SEric Fiselier
551faf2a813SEric Fiselier#define _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) \
552faf2a813SEric Fiselier  _LIBCPP_DIAGNOSE_WARNING(__m == memory_order_release || \
553faf2a813SEric Fiselier                           __m == memory_order_acq_rel,   \
554faf2a813SEric Fiselier                        "memory order argument to atomic operation is invalid")
555faf2a813SEric Fiselier
556faf2a813SEric Fiselier#define _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__m, __f) \
557faf2a813SEric Fiselier  _LIBCPP_DIAGNOSE_WARNING(__f == memory_order_release || \
558faf2a813SEric Fiselier                           __f == memory_order_acq_rel,   \
559faf2a813SEric Fiselier                        "memory order argument to atomic operation is invalid")
560faf2a813SEric Fiselier
561cd39d413SHoward Hinnant_LIBCPP_BEGIN_NAMESPACE_STD
562cd39d413SHoward Hinnant
5630e1586c4SEric Fiselier// Figure out what the underlying type for `memory_order` would be if it were
5640e1586c4SEric Fiselier// declared as an unscoped enum (accounting for -fshort-enums). Use this result
5650e1586c4SEric Fiselier// to pin the underlying type in C++20.
5660e1586c4SEric Fiselierenum __legacy_memory_order {
5670e1586c4SEric Fiselier    __mo_relaxed,
5680e1586c4SEric Fiselier    __mo_consume,
5690e1586c4SEric Fiselier    __mo_acquire,
5700e1586c4SEric Fiselier    __mo_release,
5710e1586c4SEric Fiselier    __mo_acq_rel,
5720e1586c4SEric Fiselier    __mo_seq_cst
5730e1586c4SEric Fiselier};
5740e1586c4SEric Fiselier
5750e1586c4SEric Fiseliertypedef underlying_type<__legacy_memory_order>::type __memory_order_underlying_t;
5760e1586c4SEric Fiselier
5776de760acSDavide Italiano#if _LIBCPP_STD_VER > 17
5786de760acSDavide Italiano
5790e1586c4SEric Fiselierenum class memory_order : __memory_order_underlying_t {
5800e1586c4SEric Fiselier  relaxed = __mo_relaxed,
5810e1586c4SEric Fiselier  consume = __mo_consume,
5820e1586c4SEric Fiselier  acquire = __mo_acquire,
5830e1586c4SEric Fiselier  release = __mo_release,
5840e1586c4SEric Fiselier  acq_rel = __mo_acq_rel,
5850e1586c4SEric Fiselier  seq_cst = __mo_seq_cst
5866de760acSDavide Italiano};
5876de760acSDavide Italiano
5886de760acSDavide Italianoinline constexpr auto memory_order_relaxed = memory_order::relaxed;
5896de760acSDavide Italianoinline constexpr auto memory_order_consume = memory_order::consume;
5906de760acSDavide Italianoinline constexpr auto memory_order_acquire = memory_order::acquire;
5916de760acSDavide Italianoinline constexpr auto memory_order_release = memory_order::release;
5926de760acSDavide Italianoinline constexpr auto memory_order_acq_rel = memory_order::acq_rel;
5936de760acSDavide Italianoinline constexpr auto memory_order_seq_cst = memory_order::seq_cst;
5946de760acSDavide Italiano
5956de760acSDavide Italiano#else
5966de760acSDavide Italiano
5976de760acSDavide Italianotypedef enum memory_order {
5980e1586c4SEric Fiselier  memory_order_relaxed = __mo_relaxed,
5990e1586c4SEric Fiselier  memory_order_consume = __mo_consume,
6000e1586c4SEric Fiselier  memory_order_acquire = __mo_acquire,
6010e1586c4SEric Fiselier  memory_order_release = __mo_release,
6020e1586c4SEric Fiselier  memory_order_acq_rel = __mo_acq_rel,
6030e1586c4SEric Fiselier  memory_order_seq_cst = __mo_seq_cst,
604cfe0b0a1SHoward Hinnant} memory_order;
605cfe0b0a1SHoward Hinnant
6066de760acSDavide Italiano#endif // _LIBCPP_STD_VER > 17
6076de760acSDavide Italiano
60854fa9ecdSOlivier Girouxtemplate <typename _Tp> _LIBCPP_INLINE_VISIBILITY
60954fa9ecdSOlivier Girouxbool __cxx_nonatomic_compare_equal(_Tp const& __lhs, _Tp const& __rhs) {
6103696227cSArthur O'Dwyer    return _VSTD::memcmp(&__lhs, &__rhs, sizeof(_Tp)) == 0;
61154fa9ecdSOlivier Giroux}
61254fa9ecdSOlivier Giroux
6133e3d6c90SEric Fiselierstatic_assert((is_same<underlying_type<memory_order>::type, __memory_order_underlying_t>::value),
6140e1586c4SEric Fiselier  "unexpected underlying type for std::memory_order");
6156de760acSDavide Italiano
6166de760acSDavide Italiano#if defined(_LIBCPP_HAS_GCC_ATOMIC_IMP) || \
6176de760acSDavide Italiano    defined(_LIBCPP_ATOMIC_ONLY_USE_BUILTINS)
6186de760acSDavide Italiano
6196de760acSDavide Italiano// [atomics.types.generic]p1 guarantees _Tp is trivially copyable. Because
6206de760acSDavide Italiano// the default operator= in an object is not volatile, a byte-by-byte copy
6216de760acSDavide Italiano// is required.
6226de760acSDavide Italianotemplate <typename _Tp, typename _Tv> _LIBCPP_INLINE_VISIBILITY
6236de760acSDavide Italianotypename enable_if<is_assignable<_Tp&, _Tv>::value>::type
6246de760acSDavide Italiano__cxx_atomic_assign_volatile(_Tp& __a_value, _Tv const& __val) {
6256de760acSDavide Italiano  __a_value = __val;
6266de760acSDavide Italiano}
6276de760acSDavide Italianotemplate <typename _Tp, typename _Tv> _LIBCPP_INLINE_VISIBILITY
6286de760acSDavide Italianotypename enable_if<is_assignable<_Tp&, _Tv>::value>::type
6296de760acSDavide Italiano__cxx_atomic_assign_volatile(_Tp volatile& __a_value, _Tv volatile const& __val) {
6306de760acSDavide Italiano  volatile char* __to = reinterpret_cast<volatile char*>(&__a_value);
6316de760acSDavide Italiano  volatile char* __end = __to + sizeof(_Tp);
6326de760acSDavide Italiano  volatile const char* __from = reinterpret_cast<volatile const char*>(&__val);
6336de760acSDavide Italiano  while (__to != __end)
6346de760acSDavide Italiano    *__to++ = *__from++;
6356de760acSDavide Italiano}
6366de760acSDavide Italiano
6371061cb6aSDavide Italiano#endif
63821450545SLouis Dionne
6396de760acSDavide Italiano#if defined(_LIBCPP_HAS_GCC_ATOMIC_IMP)
6406de760acSDavide Italiano
6416de760acSDavide Italianotemplate <typename _Tp>
6426de760acSDavide Italianostruct __cxx_atomic_base_impl {
6436de760acSDavide Italiano
644d97b084bSEric Fiselier  _LIBCPP_INLINE_VISIBILITY
645f9980200SEric Fiselier#ifndef _LIBCPP_CXX03_LANG
6466de760acSDavide Italiano    __cxx_atomic_base_impl() _NOEXCEPT = default;
647d97b084bSEric Fiselier#else
6486de760acSDavide Italiano    __cxx_atomic_base_impl() _NOEXCEPT : __a_value() {}
649f9980200SEric Fiselier#endif // _LIBCPP_CXX03_LANG
6506de760acSDavide Italiano  _LIBCPP_CONSTEXPR explicit __cxx_atomic_base_impl(_Tp value) _NOEXCEPT
651092c475eSEric Fiselier    : __a_value(value) {}
65293179005SMarshall Clow  _Tp __a_value;
653502dca7bSDan Albert};
654502dca7bSDan Albert
6556de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY inline _LIBCPP_CONSTEXPR int __to_gcc_order(memory_order __order) {
656502dca7bSDan Albert  // Avoid switch statement to make this a constexpr.
657502dca7bSDan Albert  return __order == memory_order_relaxed ? __ATOMIC_RELAXED:
658502dca7bSDan Albert         (__order == memory_order_acquire ? __ATOMIC_ACQUIRE:
659502dca7bSDan Albert          (__order == memory_order_release ? __ATOMIC_RELEASE:
660502dca7bSDan Albert           (__order == memory_order_seq_cst ? __ATOMIC_SEQ_CST:
661502dca7bSDan Albert            (__order == memory_order_acq_rel ? __ATOMIC_ACQ_REL:
662502dca7bSDan Albert              __ATOMIC_CONSUME))));
663502dca7bSDan Albert}
664502dca7bSDan Albert
6656de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY inline _LIBCPP_CONSTEXPR int __to_gcc_failure_order(memory_order __order) {
666872bad5aSDan Albert  // Avoid switch statement to make this a constexpr.
667872bad5aSDan Albert  return __order == memory_order_relaxed ? __ATOMIC_RELAXED:
668872bad5aSDan Albert         (__order == memory_order_acquire ? __ATOMIC_ACQUIRE:
669872bad5aSDan Albert          (__order == memory_order_release ? __ATOMIC_RELAXED:
670872bad5aSDan Albert           (__order == memory_order_seq_cst ? __ATOMIC_SEQ_CST:
671872bad5aSDan Albert            (__order == memory_order_acq_rel ? __ATOMIC_ACQUIRE:
672872bad5aSDan Albert              __ATOMIC_CONSUME))));
673872bad5aSDan Albert}
674872bad5aSDan Albert
6756de760acSDavide Italianotemplate <typename _Tp>
6766de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
6776de760acSDavide Italianovoid __cxx_atomic_init(volatile __cxx_atomic_base_impl<_Tp>* __a,  _Tp __val) {
6786de760acSDavide Italiano  __cxx_atomic_assign_volatile(__a->__a_value, __val);
6796de760acSDavide Italiano}
680502dca7bSDan Albert
681502dca7bSDan Alberttemplate <typename _Tp>
6826de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
6836de760acSDavide Italianovoid __cxx_atomic_init(__cxx_atomic_base_impl<_Tp>* __a,  _Tp __val) {
684502dca7bSDan Albert  __a->__a_value = __val;
685502dca7bSDan Albert}
686502dca7bSDan Albert
6876de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY inline
6886de760acSDavide Italianovoid __cxx_atomic_thread_fence(memory_order __order) {
6896de760acSDavide Italiano  __atomic_thread_fence(__to_gcc_order(__order));
690502dca7bSDan Albert}
6916de760acSDavide Italiano
6926de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY inline
6936de760acSDavide Italianovoid __cxx_atomic_signal_fence(memory_order __order) {
6946de760acSDavide Italiano  __atomic_signal_fence(__to_gcc_order(__order));
695502dca7bSDan Albert}
696502dca7bSDan Albert
697502dca7bSDan Alberttemplate <typename _Tp>
6986de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
6996de760acSDavide Italianovoid __cxx_atomic_store(volatile __cxx_atomic_base_impl<_Tp>* __a,  _Tp __val,
700f764dbd0SJF Bastien                        memory_order __order) {
701872bad5aSDan Albert  __atomic_store(&__a->__a_value, &__val,
7026de760acSDavide Italiano                 __to_gcc_order(__order));
703502dca7bSDan Albert}
704502dca7bSDan Albert
705502dca7bSDan Alberttemplate <typename _Tp>
7066de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
7076de760acSDavide Italianovoid __cxx_atomic_store(__cxx_atomic_base_impl<_Tp>* __a,  _Tp __val,
7086de760acSDavide Italiano                        memory_order __order) {
7096de760acSDavide Italiano  __atomic_store(&__a->__a_value, &__val,
7106de760acSDavide Italiano                 __to_gcc_order(__order));
7116de760acSDavide Italiano}
7126de760acSDavide Italiano
7136de760acSDavide Italianotemplate <typename _Tp>
7146de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
7156de760acSDavide Italiano_Tp __cxx_atomic_load(const volatile __cxx_atomic_base_impl<_Tp>* __a,
716f764dbd0SJF Bastien                      memory_order __order) {
717502dca7bSDan Albert  _Tp __ret;
718502dca7bSDan Albert  __atomic_load(&__a->__a_value, &__ret,
7196de760acSDavide Italiano                __to_gcc_order(__order));
720502dca7bSDan Albert  return __ret;
721502dca7bSDan Albert}
722502dca7bSDan Albert
723502dca7bSDan Alberttemplate <typename _Tp>
7246de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
7256de760acSDavide Italiano_Tp __cxx_atomic_load(const __cxx_atomic_base_impl<_Tp>* __a, memory_order __order) {
726502dca7bSDan Albert  _Tp __ret;
727502dca7bSDan Albert  __atomic_load(&__a->__a_value, &__ret,
7286de760acSDavide Italiano                __to_gcc_order(__order));
729502dca7bSDan Albert  return __ret;
730502dca7bSDan Albert}
731502dca7bSDan Albert
732502dca7bSDan Alberttemplate <typename _Tp>
7336de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
7346de760acSDavide Italiano_Tp __cxx_atomic_exchange(volatile __cxx_atomic_base_impl<_Tp>* __a,
735f764dbd0SJF Bastien                          _Tp __value, memory_order __order) {
736502dca7bSDan Albert  _Tp __ret;
737502dca7bSDan Albert  __atomic_exchange(&__a->__a_value, &__value, &__ret,
7386de760acSDavide Italiano                    __to_gcc_order(__order));
739502dca7bSDan Albert  return __ret;
740502dca7bSDan Albert}
741502dca7bSDan Albert
742502dca7bSDan Alberttemplate <typename _Tp>
7436de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
7446de760acSDavide Italiano_Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp>* __a, _Tp __value,
745f764dbd0SJF Bastien                          memory_order __order) {
746502dca7bSDan Albert  _Tp __ret;
747502dca7bSDan Albert  __atomic_exchange(&__a->__a_value, &__value, &__ret,
7486de760acSDavide Italiano                    __to_gcc_order(__order));
749502dca7bSDan Albert  return __ret;
750502dca7bSDan Albert}
751502dca7bSDan Albert
752502dca7bSDan Alberttemplate <typename _Tp>
7536de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
7546de760acSDavide Italianobool __cxx_atomic_compare_exchange_strong(
7556de760acSDavide Italiano    volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value,
756f764dbd0SJF Bastien    memory_order __success, memory_order __failure) {
757502dca7bSDan Albert  return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
758502dca7bSDan Albert                                   false,
7596de760acSDavide Italiano                                   __to_gcc_order(__success),
7606de760acSDavide Italiano                                   __to_gcc_failure_order(__failure));
761502dca7bSDan Albert}
762502dca7bSDan Albert
763502dca7bSDan Alberttemplate <typename _Tp>
7646de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
7656de760acSDavide Italianobool __cxx_atomic_compare_exchange_strong(
7666de760acSDavide Italiano    __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success,
767f764dbd0SJF Bastien    memory_order __failure) {
768502dca7bSDan Albert  return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
769502dca7bSDan Albert                                   false,
7706de760acSDavide Italiano                                   __to_gcc_order(__success),
7716de760acSDavide Italiano                                   __to_gcc_failure_order(__failure));
772502dca7bSDan Albert}
773502dca7bSDan Albert
774502dca7bSDan Alberttemplate <typename _Tp>
7756de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
7766de760acSDavide Italianobool __cxx_atomic_compare_exchange_weak(
7776de760acSDavide Italiano    volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value,
778f764dbd0SJF Bastien    memory_order __success, memory_order __failure) {
779502dca7bSDan Albert  return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
780502dca7bSDan Albert                                   true,
7816de760acSDavide Italiano                                   __to_gcc_order(__success),
7826de760acSDavide Italiano                                   __to_gcc_failure_order(__failure));
783502dca7bSDan Albert}
784502dca7bSDan Albert
785502dca7bSDan Alberttemplate <typename _Tp>
7866de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
7876de760acSDavide Italianobool __cxx_atomic_compare_exchange_weak(
7886de760acSDavide Italiano    __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success,
789f764dbd0SJF Bastien    memory_order __failure) {
790502dca7bSDan Albert  return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
791502dca7bSDan Albert                                   true,
7926de760acSDavide Italiano                                   __to_gcc_order(__success),
7936de760acSDavide Italiano                                   __to_gcc_failure_order(__failure));
794502dca7bSDan Albert}
795502dca7bSDan Albert
796502dca7bSDan Alberttemplate <typename _Tp>
797502dca7bSDan Albertstruct __skip_amt { enum {value = 1}; };
798502dca7bSDan Albert
799502dca7bSDan Alberttemplate <typename _Tp>
800502dca7bSDan Albertstruct __skip_amt<_Tp*> { enum {value = sizeof(_Tp)}; };
801502dca7bSDan Albert
802502dca7bSDan Albert// FIXME: Haven't figured out what the spec says about using arrays with
803502dca7bSDan Albert// atomic_fetch_add. Force a failure rather than creating bad behavior.
804502dca7bSDan Alberttemplate <typename _Tp>
805502dca7bSDan Albertstruct __skip_amt<_Tp[]> { };
806502dca7bSDan Alberttemplate <typename _Tp, int n>
807502dca7bSDan Albertstruct __skip_amt<_Tp[n]> { };
808502dca7bSDan Albert
809502dca7bSDan Alberttemplate <typename _Tp, typename _Td>
8106de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
8116de760acSDavide Italiano_Tp __cxx_atomic_fetch_add(volatile __cxx_atomic_base_impl<_Tp>* __a,
812f764dbd0SJF Bastien                           _Td __delta, memory_order __order) {
813502dca7bSDan Albert  return __atomic_fetch_add(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
8146de760acSDavide Italiano                            __to_gcc_order(__order));
815502dca7bSDan Albert}
816502dca7bSDan Albert
817502dca7bSDan Alberttemplate <typename _Tp, typename _Td>
8186de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
8196de760acSDavide Italiano_Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp>* __a, _Td __delta,
820f764dbd0SJF Bastien                           memory_order __order) {
821502dca7bSDan Albert  return __atomic_fetch_add(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
8226de760acSDavide Italiano                            __to_gcc_order(__order));
823502dca7bSDan Albert}
824502dca7bSDan Albert
825502dca7bSDan Alberttemplate <typename _Tp, typename _Td>
8266de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
8276de760acSDavide Italiano_Tp __cxx_atomic_fetch_sub(volatile __cxx_atomic_base_impl<_Tp>* __a,
828f764dbd0SJF Bastien                           _Td __delta, memory_order __order) {
829502dca7bSDan Albert  return __atomic_fetch_sub(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
8306de760acSDavide Italiano                            __to_gcc_order(__order));
831502dca7bSDan Albert}
832502dca7bSDan Albert
833502dca7bSDan Alberttemplate <typename _Tp, typename _Td>
8346de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
8356de760acSDavide Italiano_Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp>* __a, _Td __delta,
836f764dbd0SJF Bastien                           memory_order __order) {
837502dca7bSDan Albert  return __atomic_fetch_sub(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
8386de760acSDavide Italiano                            __to_gcc_order(__order));
839502dca7bSDan Albert}
840502dca7bSDan Albert
841502dca7bSDan Alberttemplate <typename _Tp>
8426de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
8436de760acSDavide Italiano_Tp __cxx_atomic_fetch_and(volatile __cxx_atomic_base_impl<_Tp>* __a,
844f764dbd0SJF Bastien                           _Tp __pattern, memory_order __order) {
845502dca7bSDan Albert  return __atomic_fetch_and(&__a->__a_value, __pattern,
8466de760acSDavide Italiano                            __to_gcc_order(__order));
847502dca7bSDan Albert}
848502dca7bSDan Albert
849502dca7bSDan Alberttemplate <typename _Tp>
8506de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
8516de760acSDavide Italiano_Tp __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp>* __a,
852f764dbd0SJF Bastien                           _Tp __pattern, memory_order __order) {
853502dca7bSDan Albert  return __atomic_fetch_and(&__a->__a_value, __pattern,
8546de760acSDavide Italiano                            __to_gcc_order(__order));
855502dca7bSDan Albert}
856502dca7bSDan Albert
857502dca7bSDan Alberttemplate <typename _Tp>
8586de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
8596de760acSDavide Italiano_Tp __cxx_atomic_fetch_or(volatile __cxx_atomic_base_impl<_Tp>* __a,
860f764dbd0SJF Bastien                          _Tp __pattern, memory_order __order) {
861502dca7bSDan Albert  return __atomic_fetch_or(&__a->__a_value, __pattern,
8626de760acSDavide Italiano                           __to_gcc_order(__order));
863502dca7bSDan Albert}
864502dca7bSDan Albert
865502dca7bSDan Alberttemplate <typename _Tp>
8666de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
8676de760acSDavide Italiano_Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern,
868f764dbd0SJF Bastien                          memory_order __order) {
869502dca7bSDan Albert  return __atomic_fetch_or(&__a->__a_value, __pattern,
8706de760acSDavide Italiano                           __to_gcc_order(__order));
871502dca7bSDan Albert}
872502dca7bSDan Albert
873502dca7bSDan Alberttemplate <typename _Tp>
8746de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
8756de760acSDavide Italiano_Tp __cxx_atomic_fetch_xor(volatile __cxx_atomic_base_impl<_Tp>* __a,
876f764dbd0SJF Bastien                           _Tp __pattern, memory_order __order) {
877502dca7bSDan Albert  return __atomic_fetch_xor(&__a->__a_value, __pattern,
8786de760acSDavide Italiano                            __to_gcc_order(__order));
879502dca7bSDan Albert}
880502dca7bSDan Albert
881502dca7bSDan Alberttemplate <typename _Tp>
8826de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
8836de760acSDavide Italiano_Tp __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern,
884f764dbd0SJF Bastien                           memory_order __order) {
885502dca7bSDan Albert  return __atomic_fetch_xor(&__a->__a_value, __pattern,
8866de760acSDavide Italiano                            __to_gcc_order(__order));
887502dca7bSDan Albert}
8886de760acSDavide Italiano
8896de760acSDavide Italiano#define __cxx_atomic_is_lock_free(__s) __atomic_is_lock_free(__s, 0)
8906de760acSDavide Italiano
8916de760acSDavide Italiano#elif defined(_LIBCPP_HAS_C_ATOMIC_IMP)
8926de760acSDavide Italiano
8936de760acSDavide Italianotemplate <typename _Tp>
8946de760acSDavide Italianostruct __cxx_atomic_base_impl {
8956de760acSDavide Italiano
8966de760acSDavide Italiano  _LIBCPP_INLINE_VISIBILITY
8976de760acSDavide Italiano#ifndef _LIBCPP_CXX03_LANG
8986de760acSDavide Italiano    __cxx_atomic_base_impl() _NOEXCEPT = default;
8996de760acSDavide Italiano#else
9006de760acSDavide Italiano    __cxx_atomic_base_impl() _NOEXCEPT : __a_value() {}
9016de760acSDavide Italiano#endif // _LIBCPP_CXX03_LANG
9026de760acSDavide Italiano  _LIBCPP_CONSTEXPR explicit __cxx_atomic_base_impl(_Tp value) _NOEXCEPT
9036de760acSDavide Italiano    : __a_value(value) {}
904801f6a49SLouis Dionne  _LIBCPP_DISABLE_EXTENSION_WARNING _Atomic(_Tp) __a_value;
9056de760acSDavide Italiano};
9066de760acSDavide Italiano
9076de760acSDavide Italiano#define __cxx_atomic_is_lock_free(__s) __c11_atomic_is_lock_free(__s)
9086de760acSDavide Italiano
9096de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY inline
910cf92a1f6SEric Fiseliervoid __cxx_atomic_thread_fence(memory_order __order) _NOEXCEPT {
9116de760acSDavide Italiano    __c11_atomic_thread_fence(static_cast<__memory_order_underlying_t>(__order));
9126de760acSDavide Italiano}
9136de760acSDavide Italiano
9146de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY inline
915cf92a1f6SEric Fiseliervoid __cxx_atomic_signal_fence(memory_order __order) _NOEXCEPT {
9166de760acSDavide Italiano    __c11_atomic_signal_fence(static_cast<__memory_order_underlying_t>(__order));
9176de760acSDavide Italiano}
918502dca7bSDan Albert
919cfe0b0a1SHoward Hinnanttemplate<class _Tp>
9206de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
921cf92a1f6SEric Fiseliervoid __cxx_atomic_init(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __val) _NOEXCEPT {
9226de760acSDavide Italiano    __c11_atomic_init(&__a->__a_value, __val);
9236de760acSDavide Italiano}
9246de760acSDavide Italianotemplate<class _Tp>
9256de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
926cf92a1f6SEric Fiseliervoid __cxx_atomic_init(__cxx_atomic_base_impl<_Tp> * __a, _Tp __val) _NOEXCEPT {
9276de760acSDavide Italiano    __c11_atomic_init(&__a->__a_value, __val);
9286de760acSDavide Italiano}
9296de760acSDavide Italiano
9306de760acSDavide Italianotemplate<class _Tp>
9316de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
932cf92a1f6SEric Fiseliervoid __cxx_atomic_store(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __val, memory_order __order) _NOEXCEPT {
9336de760acSDavide Italiano    __c11_atomic_store(&__a->__a_value, __val, static_cast<__memory_order_underlying_t>(__order));
9346de760acSDavide Italiano}
9356de760acSDavide Italianotemplate<class _Tp>
9366de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
937cf92a1f6SEric Fiseliervoid __cxx_atomic_store(__cxx_atomic_base_impl<_Tp> * __a, _Tp __val, memory_order __order) _NOEXCEPT {
9386de760acSDavide Italiano    __c11_atomic_store(&__a->__a_value, __val, static_cast<__memory_order_underlying_t>(__order));
9396de760acSDavide Italiano}
9406de760acSDavide Italiano
9416de760acSDavide Italianotemplate<class _Tp>
9426de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
943cf92a1f6SEric Fiselier_Tp __cxx_atomic_load(__cxx_atomic_base_impl<_Tp> const volatile* __a, memory_order __order) _NOEXCEPT {
9446de760acSDavide Italiano    using __ptr_type = typename remove_const<decltype(__a->__a_value)>::type*;
9456de760acSDavide Italiano    return __c11_atomic_load(const_cast<__ptr_type>(&__a->__a_value), static_cast<__memory_order_underlying_t>(__order));
9466de760acSDavide Italiano}
9476de760acSDavide Italianotemplate<class _Tp>
9486de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
949cf92a1f6SEric Fiselier_Tp __cxx_atomic_load(__cxx_atomic_base_impl<_Tp> const* __a, memory_order __order) _NOEXCEPT {
9506de760acSDavide Italiano    using __ptr_type = typename remove_const<decltype(__a->__a_value)>::type*;
9516de760acSDavide Italiano    return __c11_atomic_load(const_cast<__ptr_type>(&__a->__a_value), static_cast<__memory_order_underlying_t>(__order));
9526de760acSDavide Italiano}
9536de760acSDavide Italiano
9546de760acSDavide Italianotemplate<class _Tp>
9556de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
956cf92a1f6SEric Fiselier_Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __value, memory_order __order) _NOEXCEPT {
9576de760acSDavide Italiano    return __c11_atomic_exchange(&__a->__a_value, __value, static_cast<__memory_order_underlying_t>(__order));
9586de760acSDavide Italiano}
9596de760acSDavide Italianotemplate<class _Tp>
9606de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
961cf92a1f6SEric Fiselier_Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp> * __a, _Tp __value, memory_order __order) _NOEXCEPT {
9626de760acSDavide Italiano    return __c11_atomic_exchange(&__a->__a_value, __value, static_cast<__memory_order_underlying_t>(__order));
9636de760acSDavide Italiano}
9646de760acSDavide Italiano
9656d33362dSJordan Rupprecht_LIBCPP_INLINE_VISIBILITY inline _LIBCPP_CONSTEXPR memory_order __to_failure_order(memory_order __order) {
9666d33362dSJordan Rupprecht  // Avoid switch statement to make this a constexpr.
9676d33362dSJordan Rupprecht  return __order == memory_order_release ? memory_order_relaxed:
9686d33362dSJordan Rupprecht         (__order == memory_order_acq_rel ? memory_order_acquire:
9696d33362dSJordan Rupprecht             __order);
9706d33362dSJordan Rupprecht}
9716d33362dSJordan Rupprecht
9726de760acSDavide Italianotemplate<class _Tp>
9736de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
974cf92a1f6SEric Fiselierbool __cxx_atomic_compare_exchange_strong(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT {
9756d33362dSJordan 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)));
9766de760acSDavide Italiano}
9776de760acSDavide Italianotemplate<class _Tp>
9786de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
979cf92a1f6SEric Fiselierbool __cxx_atomic_compare_exchange_strong(__cxx_atomic_base_impl<_Tp> * __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT {
9806d33362dSJordan 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)));
9816de760acSDavide Italiano}
9826de760acSDavide Italiano
9836de760acSDavide Italianotemplate<class _Tp>
9846de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
985cf92a1f6SEric Fiselierbool __cxx_atomic_compare_exchange_weak(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT {
9866d33362dSJordan 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)));
9876de760acSDavide Italiano}
9886de760acSDavide Italianotemplate<class _Tp>
9896de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
990cf92a1f6SEric Fiselierbool __cxx_atomic_compare_exchange_weak(__cxx_atomic_base_impl<_Tp> * __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT {
9916d33362dSJordan 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)));
9926de760acSDavide Italiano}
9936de760acSDavide Italiano
9946de760acSDavide Italianotemplate<class _Tp>
9956de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
996cf92a1f6SEric Fiselier_Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __delta, memory_order __order) _NOEXCEPT {
9976de760acSDavide Italiano    return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
9986de760acSDavide Italiano}
9996de760acSDavide Italianotemplate<class _Tp>
10006de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
1001cf92a1f6SEric Fiselier_Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp> * __a, _Tp __delta, memory_order __order) _NOEXCEPT {
10026de760acSDavide Italiano    return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
10036de760acSDavide Italiano}
10046de760acSDavide Italiano
10056de760acSDavide Italianotemplate<class _Tp>
10066de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
1007cf92a1f6SEric Fiselier_Tp* __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp*> volatile* __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT {
10086de760acSDavide Italiano    return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
10096de760acSDavide Italiano}
10106de760acSDavide Italianotemplate<class _Tp>
10116de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
1012cf92a1f6SEric Fiselier_Tp* __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp*> * __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT {
10136de760acSDavide Italiano    return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
10146de760acSDavide Italiano}
10156de760acSDavide Italiano
10166de760acSDavide Italianotemplate<class _Tp>
10176de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
1018cf92a1f6SEric Fiselier_Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __delta, memory_order __order) _NOEXCEPT {
10196de760acSDavide Italiano    return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
10206de760acSDavide Italiano}
10216de760acSDavide Italianotemplate<class _Tp>
10226de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
1023cf92a1f6SEric Fiselier_Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp> * __a, _Tp __delta, memory_order __order) _NOEXCEPT {
10246de760acSDavide Italiano    return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
10256de760acSDavide Italiano}
10266de760acSDavide Italianotemplate<class _Tp>
10276de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
1028cf92a1f6SEric Fiselier_Tp* __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp*> volatile* __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT {
10296de760acSDavide Italiano    return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
10306de760acSDavide Italiano}
10316de760acSDavide Italianotemplate<class _Tp>
10326de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
1033cf92a1f6SEric Fiselier_Tp* __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp*> * __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT {
10346de760acSDavide Italiano    return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
10356de760acSDavide Italiano}
10366de760acSDavide Italiano
10376de760acSDavide Italianotemplate<class _Tp>
10386de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
1039cf92a1f6SEric Fiselier_Tp __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
10406de760acSDavide Italiano    return __c11_atomic_fetch_and(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
10416de760acSDavide Italiano}
10426de760acSDavide Italianotemplate<class _Tp>
10436de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
1044cf92a1f6SEric Fiselier_Tp __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
10456de760acSDavide Italiano    return __c11_atomic_fetch_and(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
10466de760acSDavide Italiano}
10476de760acSDavide Italiano
10486de760acSDavide Italianotemplate<class _Tp>
10496de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
1050cf92a1f6SEric Fiselier_Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
10516de760acSDavide Italiano    return __c11_atomic_fetch_or(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
10526de760acSDavide Italiano}
10536de760acSDavide Italianotemplate<class _Tp>
10546de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
1055cf92a1f6SEric Fiselier_Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
10566de760acSDavide Italiano    return __c11_atomic_fetch_or(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
10576de760acSDavide Italiano}
10586de760acSDavide Italiano
10596de760acSDavide Italianotemplate<class _Tp>
10606de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
1061cf92a1f6SEric Fiselier_Tp __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
10626de760acSDavide Italiano    return __c11_atomic_fetch_xor(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
10636de760acSDavide Italiano}
10646de760acSDavide Italianotemplate<class _Tp>
10656de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
1066cf92a1f6SEric Fiselier_Tp __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
10676de760acSDavide Italiano    return __c11_atomic_fetch_xor(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
10686de760acSDavide Italiano}
10696de760acSDavide Italiano
10706de760acSDavide Italiano#endif // _LIBCPP_HAS_GCC_ATOMIC_IMP, _LIBCPP_HAS_C_ATOMIC_IMP
10716de760acSDavide Italiano
10726de760acSDavide Italianotemplate <class _Tp>
10736de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
10746de760acSDavide Italiano_Tp kill_dependency(_Tp __y) _NOEXCEPT
1075cfe0b0a1SHoward Hinnant{
1076cfe0b0a1SHoward Hinnant    return __y;
1077cfe0b0a1SHoward Hinnant}
1078cd39d413SHoward Hinnant
1079c4112254SEric Fiselier#if defined(__CLANG_ATOMIC_BOOL_LOCK_FREE)
1080c4112254SEric Fiselier# define ATOMIC_BOOL_LOCK_FREE      __CLANG_ATOMIC_BOOL_LOCK_FREE
1081c4112254SEric Fiselier# define ATOMIC_CHAR_LOCK_FREE      __CLANG_ATOMIC_CHAR_LOCK_FREE
10825c40c994SArthur O'Dwyer#ifndef _LIBCPP_HAS_NO_CHAR8_T
10839c97e4efSMarek Kurdej# define ATOMIC_CHAR8_T_LOCK_FREE   __CLANG_ATOMIC_CHAR8_T_LOCK_FREE
10849c97e4efSMarek Kurdej#endif
1085c4112254SEric Fiselier# define ATOMIC_CHAR16_T_LOCK_FREE  __CLANG_ATOMIC_CHAR16_T_LOCK_FREE
1086c4112254SEric Fiselier# define ATOMIC_CHAR32_T_LOCK_FREE  __CLANG_ATOMIC_CHAR32_T_LOCK_FREE
1087c4112254SEric Fiselier# define ATOMIC_WCHAR_T_LOCK_FREE   __CLANG_ATOMIC_WCHAR_T_LOCK_FREE
1088c4112254SEric Fiselier# define ATOMIC_SHORT_LOCK_FREE     __CLANG_ATOMIC_SHORT_LOCK_FREE
1089c4112254SEric Fiselier# define ATOMIC_INT_LOCK_FREE       __CLANG_ATOMIC_INT_LOCK_FREE
1090c4112254SEric Fiselier# define ATOMIC_LONG_LOCK_FREE      __CLANG_ATOMIC_LONG_LOCK_FREE
1091c4112254SEric Fiselier# define ATOMIC_LLONG_LOCK_FREE     __CLANG_ATOMIC_LLONG_LOCK_FREE
1092c4112254SEric Fiselier# define ATOMIC_POINTER_LOCK_FREE   __CLANG_ATOMIC_POINTER_LOCK_FREE
10936de760acSDavide Italiano#elif defined(__GCC_ATOMIC_BOOL_LOCK_FREE)
1094b95ee819SJF Bastien# define ATOMIC_BOOL_LOCK_FREE      __GCC_ATOMIC_BOOL_LOCK_FREE
1095b95ee819SJF Bastien# define ATOMIC_CHAR_LOCK_FREE      __GCC_ATOMIC_CHAR_LOCK_FREE
10965c40c994SArthur O'Dwyer#ifndef _LIBCPP_HAS_NO_CHAR8_T
10979c97e4efSMarek Kurdej# define ATOMIC_CHAR8_T_LOCK_FREE   __GCC_ATOMIC_CHAR8_T_LOCK_FREE
10989c97e4efSMarek Kurdej#endif
1099b95ee819SJF Bastien# define ATOMIC_CHAR16_T_LOCK_FREE  __GCC_ATOMIC_CHAR16_T_LOCK_FREE
1100b95ee819SJF Bastien# define ATOMIC_CHAR32_T_LOCK_FREE  __GCC_ATOMIC_CHAR32_T_LOCK_FREE
1101b95ee819SJF Bastien# define ATOMIC_WCHAR_T_LOCK_FREE   __GCC_ATOMIC_WCHAR_T_LOCK_FREE
1102b95ee819SJF Bastien# define ATOMIC_SHORT_LOCK_FREE     __GCC_ATOMIC_SHORT_LOCK_FREE
1103b95ee819SJF Bastien# define ATOMIC_INT_LOCK_FREE       __GCC_ATOMIC_INT_LOCK_FREE
1104b95ee819SJF Bastien# define ATOMIC_LONG_LOCK_FREE      __GCC_ATOMIC_LONG_LOCK_FREE
1105b95ee819SJF Bastien# define ATOMIC_LLONG_LOCK_FREE     __GCC_ATOMIC_LLONG_LOCK_FREE
1106b95ee819SJF Bastien# define ATOMIC_POINTER_LOCK_FREE   __GCC_ATOMIC_POINTER_LOCK_FREE
1107c4112254SEric Fiselier#endif
1108b95ee819SJF Bastien
11096de760acSDavide Italiano#ifdef _LIBCPP_ATOMIC_ONLY_USE_BUILTINS
11106de760acSDavide Italiano
11116de760acSDavide Italianotemplate<typename _Tp>
11126de760acSDavide Italianostruct __cxx_atomic_lock_impl {
11136de760acSDavide Italiano
11146de760acSDavide Italiano  _LIBCPP_INLINE_VISIBILITY
11156de760acSDavide Italiano  __cxx_atomic_lock_impl() _NOEXCEPT
11166de760acSDavide Italiano    : __a_value(), __a_lock(0) {}
11176de760acSDavide Italiano  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR explicit
11186de760acSDavide Italiano  __cxx_atomic_lock_impl(_Tp value) _NOEXCEPT
11196de760acSDavide Italiano    : __a_value(value), __a_lock(0) {}
11206de760acSDavide Italiano
11216de760acSDavide Italiano  _Tp __a_value;
11226de760acSDavide Italiano  mutable __cxx_atomic_base_impl<_LIBCPP_ATOMIC_FLAG_TYPE> __a_lock;
11236de760acSDavide Italiano
11246de760acSDavide Italiano  _LIBCPP_INLINE_VISIBILITY void __lock() const volatile {
11256de760acSDavide Italiano    while(1 == __cxx_atomic_exchange(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(true), memory_order_acquire))
11266de760acSDavide Italiano        /*spin*/;
11276de760acSDavide Italiano  }
11286de760acSDavide Italiano  _LIBCPP_INLINE_VISIBILITY void __lock() const {
11296de760acSDavide Italiano    while(1 == __cxx_atomic_exchange(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(true), memory_order_acquire))
11306de760acSDavide Italiano        /*spin*/;
11316de760acSDavide Italiano  }
11326de760acSDavide Italiano  _LIBCPP_INLINE_VISIBILITY void __unlock() const volatile {
11336de760acSDavide Italiano    __cxx_atomic_store(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(false), memory_order_release);
11346de760acSDavide Italiano  }
11356de760acSDavide Italiano  _LIBCPP_INLINE_VISIBILITY void __unlock() const {
11366de760acSDavide Italiano    __cxx_atomic_store(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(false), memory_order_release);
11376de760acSDavide Italiano  }
11386de760acSDavide Italiano  _LIBCPP_INLINE_VISIBILITY _Tp __read() const volatile {
11396de760acSDavide Italiano    __lock();
11406de760acSDavide Italiano    _Tp __old;
11416de760acSDavide Italiano    __cxx_atomic_assign_volatile(__old, __a_value);
11426de760acSDavide Italiano    __unlock();
11436de760acSDavide Italiano    return __old;
11446de760acSDavide Italiano  }
11456de760acSDavide Italiano  _LIBCPP_INLINE_VISIBILITY _Tp __read() const {
11466de760acSDavide Italiano    __lock();
11476de760acSDavide Italiano    _Tp __old = __a_value;
11486de760acSDavide Italiano    __unlock();
11496de760acSDavide Italiano    return __old;
11506de760acSDavide Italiano  }
11516de760acSDavide Italiano};
11526de760acSDavide Italiano
11536de760acSDavide Italianotemplate <typename _Tp>
11546de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
11556de760acSDavide Italianovoid __cxx_atomic_init(volatile __cxx_atomic_lock_impl<_Tp>* __a,  _Tp __val) {
11566de760acSDavide Italiano  __cxx_atomic_assign_volatile(__a->__a_value, __val);
11576de760acSDavide Italiano}
11586de760acSDavide Italianotemplate <typename _Tp>
11596de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
11606de760acSDavide Italianovoid __cxx_atomic_init(__cxx_atomic_lock_impl<_Tp>* __a,  _Tp __val) {
11616de760acSDavide Italiano  __a->__a_value = __val;
11626de760acSDavide Italiano}
11636de760acSDavide Italiano
11646de760acSDavide Italianotemplate <typename _Tp>
11656de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
11666de760acSDavide Italianovoid __cxx_atomic_store(volatile __cxx_atomic_lock_impl<_Tp>* __a,  _Tp __val, memory_order) {
11676de760acSDavide Italiano  __a->__lock();
11686de760acSDavide Italiano  __cxx_atomic_assign_volatile(__a->__a_value, __val);
11696de760acSDavide Italiano  __a->__unlock();
11706de760acSDavide Italiano}
11716de760acSDavide Italianotemplate <typename _Tp>
11726de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
11736de760acSDavide Italianovoid __cxx_atomic_store(__cxx_atomic_lock_impl<_Tp>* __a,  _Tp __val, memory_order) {
11746de760acSDavide Italiano  __a->__lock();
11756de760acSDavide Italiano  __a->__a_value = __val;
11766de760acSDavide Italiano  __a->__unlock();
11776de760acSDavide Italiano}
11786de760acSDavide Italiano
11796de760acSDavide Italianotemplate <typename _Tp>
11806de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
11816de760acSDavide Italiano_Tp __cxx_atomic_load(const volatile __cxx_atomic_lock_impl<_Tp>* __a, memory_order) {
11826de760acSDavide Italiano  return __a->__read();
11836de760acSDavide Italiano}
11846de760acSDavide Italianotemplate <typename _Tp>
11856de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
11866de760acSDavide Italiano_Tp __cxx_atomic_load(const __cxx_atomic_lock_impl<_Tp>* __a, memory_order) {
11876de760acSDavide Italiano  return __a->__read();
11886de760acSDavide Italiano}
11896de760acSDavide Italiano
11906de760acSDavide Italianotemplate <typename _Tp>
11916de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
11926de760acSDavide Italiano_Tp __cxx_atomic_exchange(volatile __cxx_atomic_lock_impl<_Tp>* __a, _Tp __value, memory_order) {
11936de760acSDavide Italiano  __a->__lock();
11946de760acSDavide Italiano  _Tp __old;
11956de760acSDavide Italiano  __cxx_atomic_assign_volatile(__old, __a->__a_value);
11966de760acSDavide Italiano  __cxx_atomic_assign_volatile(__a->__a_value, __value);
11976de760acSDavide Italiano  __a->__unlock();
11986de760acSDavide Italiano  return __old;
11996de760acSDavide Italiano}
12006de760acSDavide Italianotemplate <typename _Tp>
12016de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
12026de760acSDavide Italiano_Tp __cxx_atomic_exchange(__cxx_atomic_lock_impl<_Tp>* __a, _Tp __value, memory_order) {
12036de760acSDavide Italiano  __a->__lock();
12046de760acSDavide Italiano  _Tp __old = __a->__a_value;
12056de760acSDavide Italiano  __a->__a_value = __value;
12066de760acSDavide Italiano  __a->__unlock();
12076de760acSDavide Italiano  return __old;
12086de760acSDavide Italiano}
12096de760acSDavide Italiano
12106de760acSDavide Italianotemplate <typename _Tp>
12116de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
12126de760acSDavide Italianobool __cxx_atomic_compare_exchange_strong(volatile __cxx_atomic_lock_impl<_Tp>* __a,
12136de760acSDavide Italiano                                          _Tp* __expected, _Tp __value, memory_order, memory_order) {
121454fa9ecdSOlivier Giroux  _Tp __temp;
1215fc4bff0cSOlivier Giroux  __a->__lock();
121654fa9ecdSOlivier Giroux  __cxx_atomic_assign_volatile(__temp, __a->__a_value);
12173696227cSArthur O'Dwyer  bool __ret = (_VSTD::memcmp(&__temp, __expected, sizeof(_Tp)) == 0);
12186de760acSDavide Italiano  if(__ret)
12196de760acSDavide Italiano    __cxx_atomic_assign_volatile(__a->__a_value, __value);
12206de760acSDavide Italiano  else
12216de760acSDavide Italiano    __cxx_atomic_assign_volatile(*__expected, __a->__a_value);
12226de760acSDavide Italiano  __a->__unlock();
12236de760acSDavide Italiano  return __ret;
12246de760acSDavide Italiano}
12256de760acSDavide Italianotemplate <typename _Tp>
12266de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
12276de760acSDavide Italianobool __cxx_atomic_compare_exchange_strong(__cxx_atomic_lock_impl<_Tp>* __a,
12286de760acSDavide Italiano                                          _Tp* __expected, _Tp __value, memory_order, memory_order) {
12296de760acSDavide Italiano  __a->__lock();
12303696227cSArthur O'Dwyer  bool __ret = (_VSTD::memcmp(&__a->__a_value, __expected, sizeof(_Tp)) == 0);
12316de760acSDavide Italiano  if(__ret)
12323696227cSArthur O'Dwyer    _VSTD::memcpy(&__a->__a_value, &__value, sizeof(_Tp));
12336de760acSDavide Italiano  else
12343696227cSArthur O'Dwyer    _VSTD::memcpy(__expected, &__a->__a_value, sizeof(_Tp));
12356de760acSDavide Italiano  __a->__unlock();
12366de760acSDavide Italiano  return __ret;
12376de760acSDavide Italiano}
12386de760acSDavide Italiano
12396de760acSDavide Italianotemplate <typename _Tp>
12406de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
12416de760acSDavide Italianobool __cxx_atomic_compare_exchange_weak(volatile __cxx_atomic_lock_impl<_Tp>* __a,
12426de760acSDavide Italiano                                        _Tp* __expected, _Tp __value, memory_order, memory_order) {
124354fa9ecdSOlivier Giroux  _Tp __temp;
1244fc4bff0cSOlivier Giroux  __a->__lock();
124554fa9ecdSOlivier Giroux  __cxx_atomic_assign_volatile(__temp, __a->__a_value);
12463696227cSArthur O'Dwyer  bool __ret = (_VSTD::memcmp(&__temp, __expected, sizeof(_Tp)) == 0);
12476de760acSDavide Italiano  if(__ret)
12486de760acSDavide Italiano    __cxx_atomic_assign_volatile(__a->__a_value, __value);
12496de760acSDavide Italiano  else
12506de760acSDavide Italiano    __cxx_atomic_assign_volatile(*__expected, __a->__a_value);
12516de760acSDavide Italiano  __a->__unlock();
12526de760acSDavide Italiano  return __ret;
12536de760acSDavide Italiano}
12546de760acSDavide Italianotemplate <typename _Tp>
12556de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
12566de760acSDavide Italianobool __cxx_atomic_compare_exchange_weak(__cxx_atomic_lock_impl<_Tp>* __a,
12576de760acSDavide Italiano                                        _Tp* __expected, _Tp __value, memory_order, memory_order) {
12586de760acSDavide Italiano  __a->__lock();
12593696227cSArthur O'Dwyer  bool __ret = (_VSTD::memcmp(&__a->__a_value, __expected, sizeof(_Tp)) == 0);
12606de760acSDavide Italiano  if(__ret)
12613696227cSArthur O'Dwyer    _VSTD::memcpy(&__a->__a_value, &__value, sizeof(_Tp));
12626de760acSDavide Italiano  else
12633696227cSArthur O'Dwyer    _VSTD::memcpy(__expected, &__a->__a_value, sizeof(_Tp));
12646de760acSDavide Italiano  __a->__unlock();
12656de760acSDavide Italiano  return __ret;
12666de760acSDavide Italiano}
12676de760acSDavide Italiano
12686de760acSDavide Italianotemplate <typename _Tp, typename _Td>
12696de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
12706de760acSDavide Italiano_Tp __cxx_atomic_fetch_add(volatile __cxx_atomic_lock_impl<_Tp>* __a,
12716de760acSDavide Italiano                           _Td __delta, memory_order) {
12726de760acSDavide Italiano  __a->__lock();
12736de760acSDavide Italiano  _Tp __old;
12746de760acSDavide Italiano  __cxx_atomic_assign_volatile(__old, __a->__a_value);
12756de760acSDavide Italiano  __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old + __delta));
12766de760acSDavide Italiano  __a->__unlock();
12776de760acSDavide Italiano  return __old;
12786de760acSDavide Italiano}
12796de760acSDavide Italianotemplate <typename _Tp, typename _Td>
12806de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
12816de760acSDavide Italiano_Tp __cxx_atomic_fetch_add(__cxx_atomic_lock_impl<_Tp>* __a,
12826de760acSDavide Italiano                           _Td __delta, memory_order) {
12836de760acSDavide Italiano  __a->__lock();
12846de760acSDavide Italiano  _Tp __old = __a->__a_value;
12856de760acSDavide Italiano  __a->__a_value += __delta;
12866de760acSDavide Italiano  __a->__unlock();
12876de760acSDavide Italiano  return __old;
12886de760acSDavide Italiano}
12896de760acSDavide Italiano
12906de760acSDavide Italianotemplate <typename _Tp, typename _Td>
12916de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
12926de760acSDavide Italiano_Tp* __cxx_atomic_fetch_add(volatile __cxx_atomic_lock_impl<_Tp*>* __a,
12936de760acSDavide Italiano                           ptrdiff_t __delta, memory_order) {
12946de760acSDavide Italiano  __a->__lock();
12956de760acSDavide Italiano  _Tp* __old;
12966de760acSDavide Italiano  __cxx_atomic_assign_volatile(__old, __a->__a_value);
12976de760acSDavide Italiano  __cxx_atomic_assign_volatile(__a->__a_value, __old + __delta);
12986de760acSDavide Italiano  __a->__unlock();
12996de760acSDavide Italiano  return __old;
13006de760acSDavide Italiano}
13016de760acSDavide Italianotemplate <typename _Tp, typename _Td>
13026de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
13036de760acSDavide Italiano_Tp* __cxx_atomic_fetch_add(__cxx_atomic_lock_impl<_Tp*>* __a,
13046de760acSDavide Italiano                           ptrdiff_t __delta, memory_order) {
13056de760acSDavide Italiano  __a->__lock();
13066de760acSDavide Italiano  _Tp* __old = __a->__a_value;
13076de760acSDavide Italiano  __a->__a_value += __delta;
13086de760acSDavide Italiano  __a->__unlock();
13096de760acSDavide Italiano  return __old;
13106de760acSDavide Italiano}
13116de760acSDavide Italiano
13126de760acSDavide Italianotemplate <typename _Tp, typename _Td>
13136de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
13146de760acSDavide Italiano_Tp __cxx_atomic_fetch_sub(volatile __cxx_atomic_lock_impl<_Tp>* __a,
13156de760acSDavide Italiano                           _Td __delta, memory_order) {
13166de760acSDavide Italiano  __a->__lock();
13176de760acSDavide Italiano  _Tp __old;
13186de760acSDavide Italiano  __cxx_atomic_assign_volatile(__old, __a->__a_value);
13196de760acSDavide Italiano  __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old - __delta));
13206de760acSDavide Italiano  __a->__unlock();
13216de760acSDavide Italiano  return __old;
13226de760acSDavide Italiano}
13236de760acSDavide Italianotemplate <typename _Tp, typename _Td>
13246de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
13256de760acSDavide Italiano_Tp __cxx_atomic_fetch_sub(__cxx_atomic_lock_impl<_Tp>* __a,
13266de760acSDavide Italiano                           _Td __delta, memory_order) {
13276de760acSDavide Italiano  __a->__lock();
13286de760acSDavide Italiano  _Tp __old = __a->__a_value;
13296de760acSDavide Italiano  __a->__a_value -= __delta;
13306de760acSDavide Italiano  __a->__unlock();
13316de760acSDavide Italiano  return __old;
13326de760acSDavide Italiano}
13336de760acSDavide Italiano
13346de760acSDavide Italianotemplate <typename _Tp>
13356de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
13366de760acSDavide Italiano_Tp __cxx_atomic_fetch_and(volatile __cxx_atomic_lock_impl<_Tp>* __a,
13376de760acSDavide Italiano                           _Tp __pattern, memory_order) {
13386de760acSDavide Italiano  __a->__lock();
13396de760acSDavide Italiano  _Tp __old;
13406de760acSDavide Italiano  __cxx_atomic_assign_volatile(__old, __a->__a_value);
13416de760acSDavide Italiano  __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old & __pattern));
13426de760acSDavide Italiano  __a->__unlock();
13436de760acSDavide Italiano  return __old;
13446de760acSDavide Italiano}
13456de760acSDavide Italianotemplate <typename _Tp>
13466de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
13476de760acSDavide Italiano_Tp __cxx_atomic_fetch_and(__cxx_atomic_lock_impl<_Tp>* __a,
13486de760acSDavide Italiano                           _Tp __pattern, memory_order) {
13496de760acSDavide Italiano  __a->__lock();
13506de760acSDavide Italiano  _Tp __old = __a->__a_value;
13516de760acSDavide Italiano  __a->__a_value &= __pattern;
13526de760acSDavide Italiano  __a->__unlock();
13536de760acSDavide Italiano  return __old;
13546de760acSDavide Italiano}
13556de760acSDavide Italiano
13566de760acSDavide Italianotemplate <typename _Tp>
13576de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
13586de760acSDavide Italiano_Tp __cxx_atomic_fetch_or(volatile __cxx_atomic_lock_impl<_Tp>* __a,
13596de760acSDavide Italiano                          _Tp __pattern, memory_order) {
13606de760acSDavide Italiano  __a->__lock();
13616de760acSDavide Italiano  _Tp __old;
13626de760acSDavide Italiano  __cxx_atomic_assign_volatile(__old, __a->__a_value);
13636de760acSDavide Italiano  __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old | __pattern));
13646de760acSDavide Italiano  __a->__unlock();
13656de760acSDavide Italiano  return __old;
13666de760acSDavide Italiano}
13676de760acSDavide Italianotemplate <typename _Tp>
13686de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
13696de760acSDavide Italiano_Tp __cxx_atomic_fetch_or(__cxx_atomic_lock_impl<_Tp>* __a,
13706de760acSDavide Italiano                          _Tp __pattern, memory_order) {
13716de760acSDavide Italiano  __a->__lock();
13726de760acSDavide Italiano  _Tp __old = __a->__a_value;
13736de760acSDavide Italiano  __a->__a_value |= __pattern;
13746de760acSDavide Italiano  __a->__unlock();
13756de760acSDavide Italiano  return __old;
13766de760acSDavide Italiano}
13776de760acSDavide Italiano
13786de760acSDavide Italianotemplate <typename _Tp>
13796de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
13806de760acSDavide Italiano_Tp __cxx_atomic_fetch_xor(volatile __cxx_atomic_lock_impl<_Tp>* __a,
13816de760acSDavide Italiano                           _Tp __pattern, memory_order) {
13826de760acSDavide Italiano  __a->__lock();
13836de760acSDavide Italiano  _Tp __old;
13846de760acSDavide Italiano  __cxx_atomic_assign_volatile(__old, __a->__a_value);
13856de760acSDavide Italiano  __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old ^ __pattern));
13866de760acSDavide Italiano  __a->__unlock();
13876de760acSDavide Italiano  return __old;
13886de760acSDavide Italiano}
13896de760acSDavide Italianotemplate <typename _Tp>
13906de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
13916de760acSDavide Italiano_Tp __cxx_atomic_fetch_xor(__cxx_atomic_lock_impl<_Tp>* __a,
13926de760acSDavide Italiano                           _Tp __pattern, memory_order) {
13936de760acSDavide Italiano  __a->__lock();
13946de760acSDavide Italiano  _Tp __old = __a->__a_value;
13956de760acSDavide Italiano  __a->__a_value ^= __pattern;
13966de760acSDavide Italiano  __a->__unlock();
13976de760acSDavide Italiano  return __old;
13986de760acSDavide Italiano}
13996de760acSDavide Italiano
14006de760acSDavide Italiano#ifdef __cpp_lib_atomic_is_always_lock_free
14016de760acSDavide Italiano
14026de760acSDavide Italianotemplate<typename _Tp> struct __cxx_is_always_lock_free {
14036de760acSDavide Italiano    enum { __value = __atomic_always_lock_free(sizeof(_Tp), 0) }; };
14046de760acSDavide Italiano
14056de760acSDavide Italiano#else
14066de760acSDavide Italiano
14076de760acSDavide Italianotemplate<typename _Tp> struct __cxx_is_always_lock_free { enum { __value = false }; };
14086de760acSDavide Italiano// Implementations must match the C ATOMIC_*_LOCK_FREE macro values.
14096de760acSDavide Italianotemplate<> struct __cxx_is_always_lock_free<bool> { enum { __value = 2 == ATOMIC_BOOL_LOCK_FREE }; };
14106de760acSDavide Italianotemplate<> struct __cxx_is_always_lock_free<char> { enum { __value = 2 == ATOMIC_CHAR_LOCK_FREE }; };
14116de760acSDavide Italianotemplate<> struct __cxx_is_always_lock_free<signed char> { enum { __value = 2 == ATOMIC_CHAR_LOCK_FREE }; };
14126de760acSDavide Italianotemplate<> struct __cxx_is_always_lock_free<unsigned char> { enum { __value = 2 == ATOMIC_CHAR_LOCK_FREE }; };
14135c40c994SArthur O'Dwyer#ifndef _LIBCPP_HAS_NO_CHAR8_T
14149c97e4efSMarek Kurdejtemplate<> struct __cxx_is_always_lock_free<char8_t> { enum { __value = 2 == ATOMIC_CHAR8_T_LOCK_FREE }; };
14159c97e4efSMarek Kurdej#endif
14166de760acSDavide Italianotemplate<> struct __cxx_is_always_lock_free<char16_t> { enum { __value = 2 == ATOMIC_CHAR16_T_LOCK_FREE }; };
14176de760acSDavide Italianotemplate<> struct __cxx_is_always_lock_free<char32_t> { enum { __value = 2 == ATOMIC_CHAR32_T_LOCK_FREE }; };
1418f4c1258dSLouis Dionne#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
14196de760acSDavide Italianotemplate<> struct __cxx_is_always_lock_free<wchar_t> { enum { __value = 2 == ATOMIC_WCHAR_T_LOCK_FREE }; };
1420f4c1258dSLouis Dionne#endif
14216de760acSDavide Italianotemplate<> struct __cxx_is_always_lock_free<short> { enum { __value = 2 == ATOMIC_SHORT_LOCK_FREE }; };
14226de760acSDavide Italianotemplate<> struct __cxx_is_always_lock_free<unsigned short> { enum { __value = 2 == ATOMIC_SHORT_LOCK_FREE }; };
14236de760acSDavide Italianotemplate<> struct __cxx_is_always_lock_free<int> { enum { __value = 2 == ATOMIC_INT_LOCK_FREE }; };
14246de760acSDavide Italianotemplate<> struct __cxx_is_always_lock_free<unsigned int> { enum { __value = 2 == ATOMIC_INT_LOCK_FREE }; };
14256de760acSDavide Italianotemplate<> struct __cxx_is_always_lock_free<long> { enum { __value = 2 == ATOMIC_LONG_LOCK_FREE }; };
14266de760acSDavide Italianotemplate<> struct __cxx_is_always_lock_free<unsigned long> { enum { __value = 2 == ATOMIC_LONG_LOCK_FREE }; };
14276de760acSDavide Italianotemplate<> struct __cxx_is_always_lock_free<long long> { enum { __value = 2 == ATOMIC_LLONG_LOCK_FREE }; };
14286de760acSDavide Italianotemplate<> struct __cxx_is_always_lock_free<unsigned long long> { enum { __value = 2 == ATOMIC_LLONG_LOCK_FREE }; };
14296de760acSDavide Italianotemplate<typename _Tp> struct __cxx_is_always_lock_free<_Tp*> { enum { __value = 2 == ATOMIC_POINTER_LOCK_FREE }; };
14306de760acSDavide Italianotemplate<> struct __cxx_is_always_lock_free<std::nullptr_t> { enum { __value = 2 == ATOMIC_POINTER_LOCK_FREE }; };
14316de760acSDavide Italiano
14326de760acSDavide Italiano#endif //__cpp_lib_atomic_is_always_lock_free
14336de760acSDavide Italiano
14346de760acSDavide Italianotemplate <typename _Tp,
14356de760acSDavide Italiano          typename _Base = typename conditional<__cxx_is_always_lock_free<_Tp>::__value,
14366de760acSDavide Italiano                                                __cxx_atomic_base_impl<_Tp>,
14376de760acSDavide Italiano                                                __cxx_atomic_lock_impl<_Tp> >::type>
14386de760acSDavide Italiano#else
14396de760acSDavide Italianotemplate <typename _Tp,
14406de760acSDavide Italiano          typename _Base = __cxx_atomic_base_impl<_Tp> >
14416de760acSDavide Italiano#endif //_LIBCPP_ATOMIC_ONLY_USE_BUILTINS
14426de760acSDavide Italianostruct __cxx_atomic_impl : public _Base {
14436de760acSDavide Italiano    static_assert(is_trivially_copyable<_Tp>::value,
14443e957e5dSLouis Dionne      "std::atomic<T> requires that 'T' be a trivially copyable type");
14456de760acSDavide Italiano
14464955095fSNikolas Klauser  _LIBCPP_INLINE_VISIBILITY __cxx_atomic_impl() _NOEXCEPT = default;
14476de760acSDavide Italiano  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR explicit __cxx_atomic_impl(_Tp value) _NOEXCEPT
14486de760acSDavide Italiano    : _Base(value) {}
14496de760acSDavide Italiano};
14506de760acSDavide Italiano
145154fa9ecdSOlivier Giroux#ifdef __linux__
145254fa9ecdSOlivier Giroux    using __cxx_contention_t = int32_t;
145354fa9ecdSOlivier Giroux#else
145454fa9ecdSOlivier Giroux    using __cxx_contention_t = int64_t;
145554fa9ecdSOlivier Giroux#endif //__linux__
145654fa9ecdSOlivier Giroux
145754fa9ecdSOlivier Girouxusing __cxx_atomic_contention_t = __cxx_atomic_impl<__cxx_contention_t>;
145854fa9ecdSOlivier Giroux
145992832e48SLouis Dionne#if defined(_LIBCPP_HAS_NO_THREADS)
146092832e48SLouis Dionne#   define _LIBCPP_HAS_NO_PLATFORM_WAIT
146192832e48SLouis Dionne#endif
146292832e48SLouis Dionne
146392832e48SLouis Dionne// TODO:
146492832e48SLouis Dionne// _LIBCPP_HAS_NO_PLATFORM_WAIT is currently a "dead" macro, in the sense that
146592832e48SLouis Dionne// it is not tied anywhere into the build system or even documented. We should
146692832e48SLouis Dionne// clean it up because it is technically never defined except when threads are
146792832e48SLouis Dionne// disabled. We should clean it up in its own changeset in case we break "bad"
146892832e48SLouis Dionne// users.
146954fa9ecdSOlivier Giroux#ifndef _LIBCPP_HAS_NO_PLATFORM_WAIT
147054fa9ecdSOlivier Giroux
147180e73f22SLouis Dionne_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_one(void const volatile*);
147280e73f22SLouis Dionne_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_all(void const volatile*);
147380e73f22SLouis Dionne_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t __libcpp_atomic_monitor(void const volatile*);
147480e73f22SLouis Dionne_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __libcpp_atomic_wait(void const volatile*, __cxx_contention_t);
147554fa9ecdSOlivier Giroux
147680e73f22SLouis Dionne_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_one(__cxx_atomic_contention_t const volatile*);
147780e73f22SLouis Dionne_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_all(__cxx_atomic_contention_t const volatile*);
147880e73f22SLouis Dionne_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t __libcpp_atomic_monitor(__cxx_atomic_contention_t const volatile*);
147980e73f22SLouis Dionne_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __libcpp_atomic_wait(__cxx_atomic_contention_t const volatile*, __cxx_contention_t);
148054fa9ecdSOlivier Giroux
148154fa9ecdSOlivier Girouxtemplate <class _Atp, class _Fn>
1482b21405d1SLouis Dionnestruct __libcpp_atomic_wait_backoff_impl {
1483b21405d1SLouis Dionne    _Atp* __a;
1484b21405d1SLouis Dionne    _Fn __test_fn;
148546c38761SLouis Dionne    _LIBCPP_AVAILABILITY_SYNC
1486b21405d1SLouis Dionne    _LIBCPP_INLINE_VISIBILITY bool operator()(chrono::nanoseconds __elapsed) const
148754fa9ecdSOlivier Giroux    {
148854fa9ecdSOlivier Giroux        if(__elapsed > chrono::microseconds(64))
148954fa9ecdSOlivier Giroux        {
149054fa9ecdSOlivier Giroux            auto const __monitor = __libcpp_atomic_monitor(__a);
149154fa9ecdSOlivier Giroux            if(__test_fn())
149254fa9ecdSOlivier Giroux                return true;
149354fa9ecdSOlivier Giroux            __libcpp_atomic_wait(__a, __monitor);
149454fa9ecdSOlivier Giroux        }
149554fa9ecdSOlivier Giroux        else if(__elapsed > chrono::microseconds(4))
149654fa9ecdSOlivier Giroux            __libcpp_thread_yield();
149754fa9ecdSOlivier Giroux        else
1498d2acf229SMarek Kurdej            {} // poll
149954fa9ecdSOlivier Giroux        return false;
1500b21405d1SLouis Dionne    }
150154fa9ecdSOlivier Giroux};
1502b21405d1SLouis Dionne
1503b21405d1SLouis Dionnetemplate <class _Atp, class _Fn>
150446c38761SLouis Dionne_LIBCPP_AVAILABILITY_SYNC
1505b21405d1SLouis Dionne_LIBCPP_INLINE_VISIBILITY bool __cxx_atomic_wait(_Atp* __a, _Fn && __test_fn)
1506b21405d1SLouis Dionne{
1507b21405d1SLouis Dionne    __libcpp_atomic_wait_backoff_impl<_Atp, typename decay<_Fn>::type> __backoff_fn = {__a, __test_fn};
1508b21405d1SLouis Dionne    return __libcpp_thread_poll_with_backoff(__test_fn, __backoff_fn);
150954fa9ecdSOlivier Giroux}
151054fa9ecdSOlivier Giroux
151154fa9ecdSOlivier Giroux#else // _LIBCPP_HAS_NO_PLATFORM_WAIT
151254fa9ecdSOlivier Giroux
151354fa9ecdSOlivier Girouxtemplate <class _Tp>
151454fa9ecdSOlivier Giroux_LIBCPP_INLINE_VISIBILITY void __cxx_atomic_notify_all(__cxx_atomic_impl<_Tp> const volatile*) { }
151554fa9ecdSOlivier Girouxtemplate <class _Tp>
151654fa9ecdSOlivier Giroux_LIBCPP_INLINE_VISIBILITY void __cxx_atomic_notify_one(__cxx_atomic_impl<_Tp> const volatile*) { }
151754fa9ecdSOlivier Girouxtemplate <class _Atp, class _Fn>
151854fa9ecdSOlivier Giroux_LIBCPP_INLINE_VISIBILITY bool __cxx_atomic_wait(_Atp*, _Fn && __test_fn)
151954fa9ecdSOlivier Giroux{
152092832e48SLouis Dionne#if defined(_LIBCPP_HAS_NO_THREADS)
152192832e48SLouis Dionne    using _Policy = __spinning_backoff_policy;
152292832e48SLouis Dionne#else
152392832e48SLouis Dionne    using _Policy = __libcpp_timed_backoff_policy;
152492832e48SLouis Dionne#endif
152592832e48SLouis Dionne    return __libcpp_thread_poll_with_backoff(__test_fn, _Policy());
152654fa9ecdSOlivier Giroux}
152754fa9ecdSOlivier Giroux
152854fa9ecdSOlivier Giroux#endif // _LIBCPP_HAS_NO_PLATFORM_WAIT
152954fa9ecdSOlivier Giroux
153054fa9ecdSOlivier Girouxtemplate <class _Atp, class _Tp>
1531b21405d1SLouis Dionnestruct __cxx_atomic_wait_test_fn_impl {
1532b21405d1SLouis Dionne    _Atp* __a;
1533b21405d1SLouis Dionne    _Tp __val;
1534b21405d1SLouis Dionne    memory_order __order;
1535b21405d1SLouis Dionne    _LIBCPP_INLINE_VISIBILITY bool operator()() const
1536b21405d1SLouis Dionne    {
1537b21405d1SLouis Dionne        return !__cxx_nonatomic_compare_equal(__cxx_atomic_load(__a, __order), __val);
1538b21405d1SLouis Dionne    }
1539b21405d1SLouis Dionne};
1540b21405d1SLouis Dionne
1541b21405d1SLouis Dionnetemplate <class _Atp, class _Tp>
154246c38761SLouis Dionne_LIBCPP_AVAILABILITY_SYNC
154354fa9ecdSOlivier Giroux_LIBCPP_INLINE_VISIBILITY bool __cxx_atomic_wait(_Atp* __a, _Tp const __val, memory_order __order)
154454fa9ecdSOlivier Giroux{
1545b21405d1SLouis Dionne    __cxx_atomic_wait_test_fn_impl<_Atp, _Tp> __test_fn = {__a, __val, __order};
154654fa9ecdSOlivier Giroux    return __cxx_atomic_wait(__a, __test_fn);
154754fa9ecdSOlivier Giroux}
154854fa9ecdSOlivier Giroux
1549c772a620SHoward Hinnant// general atomic<T>
1550c772a620SHoward Hinnant
1551c772a620SHoward Hinnanttemplate <class _Tp, bool = is_integral<_Tp>::value && !is_same<_Tp, bool>::value>
1552c772a620SHoward Hinnantstruct __atomic_base  // false
1553c772a620SHoward Hinnant{
15546de760acSDavide Italiano    mutable __cxx_atomic_impl<_Tp> __a_;
1555c772a620SHoward Hinnant
1556b95ee819SJF Bastien#if defined(__cpp_lib_atomic_is_always_lock_free)
1557b95ee819SJF Bastien  static _LIBCPP_CONSTEXPR bool is_always_lock_free = __atomic_always_lock_free(sizeof(__a_), 0);
1558b95ee819SJF Bastien#endif
1559b95ee819SJF Bastien
1560c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1561d01320c2SHoward Hinnant    bool is_lock_free() const volatile _NOEXCEPT
15626de760acSDavide Italiano        {return __cxx_atomic_is_lock_free(sizeof(_Tp));}
1563c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1564d01320c2SHoward Hinnant    bool is_lock_free() const _NOEXCEPT
1565776cc6e4SEric Fiselier        {return static_cast<__atomic_base const volatile*>(this)->is_lock_free();}
1566c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1567d01320c2SHoward Hinnant    void store(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
1568faf2a813SEric Fiselier      _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
15696de760acSDavide Italiano        {__cxx_atomic_store(&__a_, __d, __m);}
1570c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1571d01320c2SHoward Hinnant    void store(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT
1572faf2a813SEric Fiselier      _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
15736de760acSDavide Italiano        {__cxx_atomic_store(&__a_, __d, __m);}
1574c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1575d01320c2SHoward Hinnant    _Tp load(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
1576faf2a813SEric Fiselier      _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
15776de760acSDavide Italiano        {return __cxx_atomic_load(&__a_, __m);}
1578c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1579d01320c2SHoward Hinnant    _Tp load(memory_order __m = memory_order_seq_cst) const _NOEXCEPT
1580faf2a813SEric Fiselier      _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
15816de760acSDavide Italiano        {return __cxx_atomic_load(&__a_, __m);}
1582c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1583d01320c2SHoward Hinnant    operator _Tp() const volatile _NOEXCEPT {return load();}
1584c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1585d01320c2SHoward Hinnant    operator _Tp() const _NOEXCEPT          {return load();}
1586c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1587d01320c2SHoward Hinnant    _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
15886de760acSDavide Italiano        {return __cxx_atomic_exchange(&__a_, __d, __m);}
1589c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1590d01320c2SHoward Hinnant    _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT
15916de760acSDavide Italiano        {return __cxx_atomic_exchange(&__a_, __d, __m);}
1592c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1593c772a620SHoward Hinnant    bool compare_exchange_weak(_Tp& __e, _Tp __d,
1594d01320c2SHoward Hinnant                               memory_order __s, memory_order __f) volatile _NOEXCEPT
1595faf2a813SEric Fiselier      _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
15966de760acSDavide Italiano        {return __cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);}
1597c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1598c772a620SHoward Hinnant    bool compare_exchange_weak(_Tp& __e, _Tp __d,
1599d01320c2SHoward Hinnant                               memory_order __s, memory_order __f) _NOEXCEPT
1600faf2a813SEric Fiselier      _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
16016de760acSDavide Italiano        {return __cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);}
1602c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1603c772a620SHoward Hinnant    bool compare_exchange_strong(_Tp& __e, _Tp __d,
1604d01320c2SHoward Hinnant                                 memory_order __s, memory_order __f) volatile _NOEXCEPT
1605faf2a813SEric Fiselier      _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
16066de760acSDavide Italiano        {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);}
1607c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1608c772a620SHoward Hinnant    bool compare_exchange_strong(_Tp& __e, _Tp __d,
1609d01320c2SHoward Hinnant                                 memory_order __s, memory_order __f) _NOEXCEPT
1610faf2a813SEric Fiselier      _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
16116de760acSDavide Italiano        {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);}
1612c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1613c772a620SHoward Hinnant    bool compare_exchange_weak(_Tp& __e, _Tp __d,
1614d01320c2SHoward Hinnant                              memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
16156de760acSDavide Italiano        {return __cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);}
1616c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1617c772a620SHoward Hinnant    bool compare_exchange_weak(_Tp& __e, _Tp __d,
1618d01320c2SHoward Hinnant                               memory_order __m = memory_order_seq_cst) _NOEXCEPT
16196de760acSDavide Italiano        {return __cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);}
1620c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1621c772a620SHoward Hinnant    bool compare_exchange_strong(_Tp& __e, _Tp __d,
1622d01320c2SHoward Hinnant                              memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
16236de760acSDavide Italiano        {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}
1624c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1625c772a620SHoward Hinnant    bool compare_exchange_strong(_Tp& __e, _Tp __d,
1626d01320c2SHoward Hinnant                                 memory_order __m = memory_order_seq_cst) _NOEXCEPT
16276de760acSDavide Italiano        {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}
1628c772a620SHoward Hinnant
162946c38761SLouis Dionne    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void wait(_Tp __v, memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
163054fa9ecdSOlivier Giroux        {__cxx_atomic_wait(&__a_, __v, __m);}
163146c38761SLouis Dionne    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void wait(_Tp __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT
163254fa9ecdSOlivier Giroux        {__cxx_atomic_wait(&__a_, __v, __m);}
163346c38761SLouis Dionne    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_one() volatile _NOEXCEPT
163454fa9ecdSOlivier Giroux        {__cxx_atomic_notify_one(&__a_);}
163546c38761SLouis Dionne    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_one() _NOEXCEPT
163654fa9ecdSOlivier Giroux        {__cxx_atomic_notify_one(&__a_);}
163746c38761SLouis Dionne    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_all() volatile _NOEXCEPT
163854fa9ecdSOlivier Giroux        {__cxx_atomic_notify_all(&__a_);}
163946c38761SLouis Dionne    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_all() _NOEXCEPT
164054fa9ecdSOlivier Giroux        {__cxx_atomic_notify_all(&__a_);}
164154fa9ecdSOlivier Giroux
164256aac567SRaul Tambre#if _LIBCPP_STD_VER > 17
164356aac567SRaul Tambre    _LIBCPP_INLINE_VISIBILITY constexpr
164456aac567SRaul Tambre    __atomic_base() noexcept(is_nothrow_default_constructible_v<_Tp>) : __a_(_Tp()) {}
164556aac567SRaul Tambre#else
1646c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
16474955095fSNikolas Klauser    __atomic_base() _NOEXCEPT = default;
164856aac567SRaul Tambre#endif
1649da9ca0b4SHoward Hinnant
16506de760acSDavide Italiano    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
16516de760acSDavide Italiano    __atomic_base(_Tp __d) _NOEXCEPT : __a_(__d) {}
16526de760acSDavide Italiano
16538f56dedbSEric Fiselier#ifndef _LIBCPP_CXX03_LANG
1654c772a620SHoward Hinnant    __atomic_base(const __atomic_base&) = delete;
16558f56dedbSEric Fiselier#else
1656b5452b3dSHoward Hinnantprivate:
165754fa9ecdSOlivier Giroux    _LIBCPP_INLINE_VISIBILITY
1658b5452b3dSHoward Hinnant    __atomic_base(const __atomic_base&);
16598f56dedbSEric Fiselier#endif
1660c772a620SHoward Hinnant};
1661c772a620SHoward Hinnant
1662b95ee819SJF Bastien#if defined(__cpp_lib_atomic_is_always_lock_free)
1663b95ee819SJF Bastientemplate <class _Tp, bool __b>
1664b95ee819SJF Bastien_LIBCPP_CONSTEXPR bool __atomic_base<_Tp, __b>::is_always_lock_free;
1665b95ee819SJF Bastien#endif
1666b95ee819SJF Bastien
1667c772a620SHoward Hinnant// atomic<Integral>
1668c772a620SHoward Hinnant
1669c772a620SHoward Hinnanttemplate <class _Tp>
1670c772a620SHoward Hinnantstruct __atomic_base<_Tp, true>
1671c772a620SHoward Hinnant    : public __atomic_base<_Tp, false>
1672c772a620SHoward Hinnant{
1673c772a620SHoward Hinnant    typedef __atomic_base<_Tp, false> __base;
167456aac567SRaul Tambre
167556aac567SRaul Tambre    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
16764955095fSNikolas Klauser    __atomic_base() _NOEXCEPT = default;
167756aac567SRaul Tambre
1678c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1679d01320c2SHoward Hinnant    _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __base(__d) {}
1680c772a620SHoward Hinnant
1681c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1682d01320c2SHoward Hinnant    _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
16836de760acSDavide Italiano        {return __cxx_atomic_fetch_add(&this->__a_, __op, __m);}
1684c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1685d01320c2SHoward Hinnant    _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
16866de760acSDavide Italiano        {return __cxx_atomic_fetch_add(&this->__a_, __op, __m);}
1687c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1688d01320c2SHoward Hinnant    _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
16896de760acSDavide Italiano        {return __cxx_atomic_fetch_sub(&this->__a_, __op, __m);}
1690c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1691d01320c2SHoward Hinnant    _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
16926de760acSDavide Italiano        {return __cxx_atomic_fetch_sub(&this->__a_, __op, __m);}
1693c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1694d01320c2SHoward Hinnant    _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
16956de760acSDavide Italiano        {return __cxx_atomic_fetch_and(&this->__a_, __op, __m);}
1696c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1697d01320c2SHoward Hinnant    _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
16986de760acSDavide Italiano        {return __cxx_atomic_fetch_and(&this->__a_, __op, __m);}
1699c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1700d01320c2SHoward Hinnant    _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
17016de760acSDavide Italiano        {return __cxx_atomic_fetch_or(&this->__a_, __op, __m);}
1702c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1703d01320c2SHoward Hinnant    _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
17046de760acSDavide Italiano        {return __cxx_atomic_fetch_or(&this->__a_, __op, __m);}
1705c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1706d01320c2SHoward Hinnant    _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
17076de760acSDavide Italiano        {return __cxx_atomic_fetch_xor(&this->__a_, __op, __m);}
1708c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1709d01320c2SHoward Hinnant    _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
17106de760acSDavide Italiano        {return __cxx_atomic_fetch_xor(&this->__a_, __op, __m);}
1711c772a620SHoward Hinnant
1712c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1713d01320c2SHoward Hinnant    _Tp operator++(int) volatile _NOEXCEPT      {return fetch_add(_Tp(1));}
1714c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1715d01320c2SHoward Hinnant    _Tp operator++(int) _NOEXCEPT               {return fetch_add(_Tp(1));}
1716c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1717d01320c2SHoward Hinnant    _Tp operator--(int) volatile _NOEXCEPT      {return fetch_sub(_Tp(1));}
1718c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1719d01320c2SHoward Hinnant    _Tp operator--(int) _NOEXCEPT               {return fetch_sub(_Tp(1));}
1720c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1721d01320c2SHoward Hinnant    _Tp operator++() volatile _NOEXCEPT         {return fetch_add(_Tp(1)) + _Tp(1);}
1722c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1723d01320c2SHoward Hinnant    _Tp operator++() _NOEXCEPT                  {return fetch_add(_Tp(1)) + _Tp(1);}
1724c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1725d01320c2SHoward Hinnant    _Tp operator--() volatile _NOEXCEPT         {return fetch_sub(_Tp(1)) - _Tp(1);}
1726c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1727d01320c2SHoward Hinnant    _Tp operator--() _NOEXCEPT                  {return fetch_sub(_Tp(1)) - _Tp(1);}
1728c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1729d01320c2SHoward Hinnant    _Tp operator+=(_Tp __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;}
1730c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1731d01320c2SHoward Hinnant    _Tp operator+=(_Tp __op) _NOEXCEPT          {return fetch_add(__op) + __op;}
1732c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1733d01320c2SHoward Hinnant    _Tp operator-=(_Tp __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;}
1734c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1735d01320c2SHoward Hinnant    _Tp operator-=(_Tp __op) _NOEXCEPT          {return fetch_sub(__op) - __op;}
1736c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1737d01320c2SHoward Hinnant    _Tp operator&=(_Tp __op) volatile _NOEXCEPT {return fetch_and(__op) & __op;}
1738c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1739d01320c2SHoward Hinnant    _Tp operator&=(_Tp __op) _NOEXCEPT          {return fetch_and(__op) & __op;}
1740c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1741d01320c2SHoward Hinnant    _Tp operator|=(_Tp __op) volatile _NOEXCEPT {return fetch_or(__op) | __op;}
1742c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1743d01320c2SHoward Hinnant    _Tp operator|=(_Tp __op) _NOEXCEPT          {return fetch_or(__op) | __op;}
1744c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1745d01320c2SHoward Hinnant    _Tp operator^=(_Tp __op) volatile _NOEXCEPT {return fetch_xor(__op) ^ __op;}
1746c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1747d01320c2SHoward Hinnant    _Tp operator^=(_Tp __op) _NOEXCEPT          {return fetch_xor(__op) ^ __op;}
1748c772a620SHoward Hinnant};
1749c772a620SHoward Hinnant
1750c772a620SHoward Hinnant// atomic<T>
1751c772a620SHoward Hinnant
1752c772a620SHoward Hinnanttemplate <class _Tp>
1753c772a620SHoward Hinnantstruct atomic
1754c772a620SHoward Hinnant    : public __atomic_base<_Tp>
1755c772a620SHoward Hinnant{
1756c772a620SHoward Hinnant    typedef __atomic_base<_Tp> __base;
175754fa9ecdSOlivier Giroux    typedef _Tp value_type;
1758fc4bff0cSOlivier Giroux    typedef value_type difference_type;
175956aac567SRaul Tambre
176056aac567SRaul Tambre#if _LIBCPP_STD_VER > 17
176156aac567SRaul Tambre    _LIBCPP_INLINE_VISIBILITY
176256aac567SRaul Tambre    atomic() = default;
176356aac567SRaul Tambre#else
1764c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
17654955095fSNikolas Klauser    atomic() _NOEXCEPT = default;
176656aac567SRaul Tambre#endif
176756aac567SRaul Tambre
1768c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1769d01320c2SHoward Hinnant    _LIBCPP_CONSTEXPR atomic(_Tp __d) _NOEXCEPT : __base(__d) {}
1770c5f5f0a1SHoward Hinnant
1771c5f5f0a1SHoward 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;}
1777c448ea94SRuslan Arutyunyan
1778c448ea94SRuslan Arutyunyan    atomic& operator=(const atomic&) = delete;
1779c448ea94SRuslan Arutyunyan    atomic& operator=(const atomic&) volatile = delete;
1780c772a620SHoward Hinnant};
1781c772a620SHoward Hinnant
1782c772a620SHoward Hinnant// atomic<T*>
1783c772a620SHoward Hinnant
1784c772a620SHoward Hinnanttemplate <class _Tp>
1785c772a620SHoward Hinnantstruct atomic<_Tp*>
1786c772a620SHoward Hinnant    : public __atomic_base<_Tp*>
1787c772a620SHoward Hinnant{
1788c5f5f0a1SHoward Hinnant    typedef __atomic_base<_Tp*> __base;
178954fa9ecdSOlivier Giroux    typedef _Tp* value_type;
1790fc4bff0cSOlivier Giroux    typedef ptrdiff_t difference_type;
179156aac567SRaul Tambre
1792c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
17934955095fSNikolas Klauser    atomic() _NOEXCEPT = default;
179456aac567SRaul Tambre
1795c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1796d01320c2SHoward Hinnant    _LIBCPP_CONSTEXPR atomic(_Tp* __d) _NOEXCEPT : __base(__d) {}
1797c772a620SHoward Hinnant
1798c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1799d01320c2SHoward Hinnant    _Tp* operator=(_Tp* __d) volatile _NOEXCEPT
1800c5f5f0a1SHoward Hinnant        {__base::store(__d); return __d;}
1801c5f5f0a1SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1802d01320c2SHoward Hinnant    _Tp* operator=(_Tp* __d) _NOEXCEPT
1803c5f5f0a1SHoward Hinnant        {__base::store(__d); return __d;}
1804c5f5f0a1SHoward Hinnant
1805c5f5f0a1SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1806aac5b84dSMark de Wever    _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
1807aac5b84dSMark de Wever        // __atomic_fetch_add accepts function pointers, guard against them.
1808aac5b84dSMark de Wever        static_assert(!is_function<typename remove_pointer<_Tp>::type>::value, "Pointer to function isn't allowed");
1809aac5b84dSMark de Wever        return __cxx_atomic_fetch_add(&this->__a_, __op, __m);
1810aac5b84dSMark de Wever    }
1811aac5b84dSMark de Wever
1812c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1813aac5b84dSMark de Wever    _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
1814aac5b84dSMark de Wever        // __atomic_fetch_add accepts function pointers, guard against them.
1815aac5b84dSMark de Wever        static_assert(!is_function<typename remove_pointer<_Tp>::type>::value, "Pointer to function isn't allowed");
1816aac5b84dSMark de Wever        return __cxx_atomic_fetch_add(&this->__a_, __op, __m);
1817aac5b84dSMark de Wever    }
1818aac5b84dSMark de Wever
1819c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1820aac5b84dSMark de Wever    _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
1821aac5b84dSMark de Wever        // __atomic_fetch_add accepts function pointers, guard against them.
1822aac5b84dSMark de Wever        static_assert(!is_function<typename remove_pointer<_Tp>::type>::value, "Pointer to function isn't allowed");
1823aac5b84dSMark de Wever        return __cxx_atomic_fetch_sub(&this->__a_, __op, __m);
1824aac5b84dSMark de Wever    }
1825aac5b84dSMark de Wever
1826c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1827aac5b84dSMark de Wever    _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
1828aac5b84dSMark de Wever        // __atomic_fetch_add accepts function pointers, guard against them.
1829aac5b84dSMark de Wever        static_assert(!is_function<typename remove_pointer<_Tp>::type>::value, "Pointer to function isn't allowed");
1830aac5b84dSMark de Wever        return __cxx_atomic_fetch_sub(&this->__a_, __op, __m);
1831aac5b84dSMark de Wever    }
1832c772a620SHoward Hinnant
1833c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1834d01320c2SHoward Hinnant    _Tp* operator++(int) volatile _NOEXCEPT            {return fetch_add(1);}
1835c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1836d01320c2SHoward Hinnant    _Tp* operator++(int) _NOEXCEPT                     {return fetch_add(1);}
1837c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1838d01320c2SHoward Hinnant    _Tp* operator--(int) volatile _NOEXCEPT            {return fetch_sub(1);}
1839c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1840d01320c2SHoward Hinnant    _Tp* operator--(int) _NOEXCEPT                     {return fetch_sub(1);}
1841c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1842d01320c2SHoward Hinnant    _Tp* operator++() volatile _NOEXCEPT               {return fetch_add(1) + 1;}
1843c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1844d01320c2SHoward Hinnant    _Tp* operator++() _NOEXCEPT                        {return fetch_add(1) + 1;}
1845c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1846d01320c2SHoward Hinnant    _Tp* operator--() volatile _NOEXCEPT               {return fetch_sub(1) - 1;}
1847c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1848d01320c2SHoward Hinnant    _Tp* operator--() _NOEXCEPT                        {return fetch_sub(1) - 1;}
1849c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1850d01320c2SHoward Hinnant    _Tp* operator+=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;}
1851c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1852d01320c2SHoward Hinnant    _Tp* operator+=(ptrdiff_t __op) _NOEXCEPT          {return fetch_add(__op) + __op;}
1853c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1854d01320c2SHoward Hinnant    _Tp* operator-=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;}
1855c772a620SHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
1856d01320c2SHoward Hinnant    _Tp* operator-=(ptrdiff_t __op) _NOEXCEPT          {return fetch_sub(__op) - __op;}
1857c448ea94SRuslan Arutyunyan
1858c448ea94SRuslan Arutyunyan    atomic& operator=(const atomic&) = delete;
1859c448ea94SRuslan Arutyunyan    atomic& operator=(const atomic&) volatile = delete;
1860c772a620SHoward Hinnant};
18619847abacSHoward Hinnant
18629847abacSHoward Hinnant// atomic_is_lock_free
18639847abacSHoward Hinnant
18649847abacSHoward Hinnanttemplate <class _Tp>
18656de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
18669847abacSHoward Hinnantbool
1867d01320c2SHoward Hinnantatomic_is_lock_free(const volatile atomic<_Tp>* __o) _NOEXCEPT
18689847abacSHoward Hinnant{
1869c772a620SHoward Hinnant    return __o->is_lock_free();
18709847abacSHoward Hinnant}
18719847abacSHoward Hinnant
18729847abacSHoward Hinnanttemplate <class _Tp>
18736de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
18749847abacSHoward Hinnantbool
1875d01320c2SHoward Hinnantatomic_is_lock_free(const atomic<_Tp>* __o) _NOEXCEPT
18769847abacSHoward Hinnant{
1877c772a620SHoward Hinnant    return __o->is_lock_free();
18789847abacSHoward Hinnant}
18799847abacSHoward Hinnant
18809847abacSHoward Hinnant// atomic_init
18819847abacSHoward Hinnant
18829847abacSHoward Hinnanttemplate <class _Tp>
188356aac567SRaul Tambre_LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_INLINE_VISIBILITY
18849847abacSHoward Hinnantvoid
1885fc4bff0cSOlivier Girouxatomic_init(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
18869847abacSHoward Hinnant{
18876de760acSDavide Italiano    __cxx_atomic_init(&__o->__a_, __d);
18889847abacSHoward Hinnant}
18899847abacSHoward Hinnant
18909847abacSHoward Hinnanttemplate <class _Tp>
189156aac567SRaul Tambre_LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_INLINE_VISIBILITY
18929847abacSHoward Hinnantvoid
1893fc4bff0cSOlivier Girouxatomic_init(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
18949847abacSHoward Hinnant{
18956de760acSDavide Italiano    __cxx_atomic_init(&__o->__a_, __d);
18969847abacSHoward Hinnant}
18979847abacSHoward Hinnant
18989847abacSHoward Hinnant// atomic_store
18999847abacSHoward Hinnant
19009847abacSHoward Hinnanttemplate <class _Tp>
19016de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
19029847abacSHoward Hinnantvoid
1903fc4bff0cSOlivier Girouxatomic_store(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
19049847abacSHoward Hinnant{
1905c772a620SHoward Hinnant    __o->store(__d);
19069847abacSHoward Hinnant}
19079847abacSHoward Hinnant
19089847abacSHoward Hinnanttemplate <class _Tp>
19096de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
19109847abacSHoward Hinnantvoid
1911fc4bff0cSOlivier Girouxatomic_store(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
19129847abacSHoward Hinnant{
1913c772a620SHoward Hinnant    __o->store(__d);
19149847abacSHoward Hinnant}
19159847abacSHoward Hinnant
19169847abacSHoward Hinnant// atomic_store_explicit
19179847abacSHoward Hinnant
19189847abacSHoward Hinnanttemplate <class _Tp>
19196de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
19209847abacSHoward Hinnantvoid
1921fc4bff0cSOlivier Girouxatomic_store_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT
1922faf2a813SEric Fiselier  _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
19239847abacSHoward Hinnant{
1924c772a620SHoward Hinnant    __o->store(__d, __m);
19259847abacSHoward Hinnant}
19269847abacSHoward Hinnant
19279847abacSHoward Hinnanttemplate <class _Tp>
19286de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
19299847abacSHoward Hinnantvoid
1930fc4bff0cSOlivier Girouxatomic_store_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT
1931faf2a813SEric Fiselier  _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
19329847abacSHoward Hinnant{
1933c772a620SHoward Hinnant    __o->store(__d, __m);
19349847abacSHoward Hinnant}
19359847abacSHoward Hinnant
19369847abacSHoward Hinnant// atomic_load
19379847abacSHoward Hinnant
19389847abacSHoward Hinnanttemplate <class _Tp>
19396de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
19409847abacSHoward Hinnant_Tp
1941d01320c2SHoward Hinnantatomic_load(const volatile atomic<_Tp>* __o) _NOEXCEPT
19429847abacSHoward Hinnant{
1943c772a620SHoward Hinnant    return __o->load();
19449847abacSHoward Hinnant}
19459847abacSHoward Hinnant
19469847abacSHoward Hinnanttemplate <class _Tp>
19476de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
19489847abacSHoward Hinnant_Tp
1949d01320c2SHoward Hinnantatomic_load(const atomic<_Tp>* __o) _NOEXCEPT
19509847abacSHoward Hinnant{
1951c772a620SHoward Hinnant    return __o->load();
19529847abacSHoward Hinnant}
19539847abacSHoward Hinnant
19549847abacSHoward Hinnant// atomic_load_explicit
19559847abacSHoward Hinnant
19569847abacSHoward Hinnanttemplate <class _Tp>
19576de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
19589847abacSHoward Hinnant_Tp
1959d01320c2SHoward Hinnantatomic_load_explicit(const volatile atomic<_Tp>* __o, memory_order __m) _NOEXCEPT
1960faf2a813SEric Fiselier  _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
19619847abacSHoward Hinnant{
1962c772a620SHoward Hinnant    return __o->load(__m);
19639847abacSHoward Hinnant}
19649847abacSHoward Hinnant
19659847abacSHoward Hinnanttemplate <class _Tp>
19666de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
19679847abacSHoward Hinnant_Tp
1968d01320c2SHoward Hinnantatomic_load_explicit(const atomic<_Tp>* __o, memory_order __m) _NOEXCEPT
1969faf2a813SEric Fiselier  _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
19709847abacSHoward Hinnant{
1971c772a620SHoward Hinnant    return __o->load(__m);
19729847abacSHoward Hinnant}
19739847abacSHoward Hinnant
19749847abacSHoward Hinnant// atomic_exchange
19759847abacSHoward Hinnant
19769847abacSHoward Hinnanttemplate <class _Tp>
19776de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
19789847abacSHoward Hinnant_Tp
1979fc4bff0cSOlivier Girouxatomic_exchange(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
19809847abacSHoward Hinnant{
1981c772a620SHoward Hinnant    return __o->exchange(__d);
19829847abacSHoward Hinnant}
19839847abacSHoward Hinnant
19849847abacSHoward Hinnanttemplate <class _Tp>
19856de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
19869847abacSHoward Hinnant_Tp
1987fc4bff0cSOlivier Girouxatomic_exchange(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
19889847abacSHoward Hinnant{
1989c772a620SHoward Hinnant    return __o->exchange(__d);
19909847abacSHoward Hinnant}
19919847abacSHoward Hinnant
19929847abacSHoward Hinnant// atomic_exchange_explicit
19939847abacSHoward Hinnant
19949847abacSHoward Hinnanttemplate <class _Tp>
19956de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
19969847abacSHoward Hinnant_Tp
1997fc4bff0cSOlivier Girouxatomic_exchange_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT
19989847abacSHoward Hinnant{
1999c772a620SHoward Hinnant    return __o->exchange(__d, __m);
20009847abacSHoward Hinnant}
20019847abacSHoward Hinnant
20029847abacSHoward Hinnanttemplate <class _Tp>
20036de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
20049847abacSHoward Hinnant_Tp
2005fc4bff0cSOlivier Girouxatomic_exchange_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT
20069847abacSHoward Hinnant{
2007c772a620SHoward Hinnant    return __o->exchange(__d, __m);
20089847abacSHoward Hinnant}
20099847abacSHoward Hinnant
20109847abacSHoward Hinnant// atomic_compare_exchange_weak
20119847abacSHoward Hinnant
20129847abacSHoward Hinnanttemplate <class _Tp>
20136de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
20149847abacSHoward Hinnantbool
2015fc4bff0cSOlivier Girouxatomic_compare_exchange_weak(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT
20169847abacSHoward Hinnant{
2017c772a620SHoward Hinnant    return __o->compare_exchange_weak(*__e, __d);
20189847abacSHoward Hinnant}
20199847abacSHoward Hinnant
20209847abacSHoward Hinnanttemplate <class _Tp>
20216de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
20229847abacSHoward Hinnantbool
2023fc4bff0cSOlivier Girouxatomic_compare_exchange_weak(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT
20249847abacSHoward Hinnant{
2025c772a620SHoward Hinnant    return __o->compare_exchange_weak(*__e, __d);
20269847abacSHoward Hinnant}
20279847abacSHoward Hinnant
20289847abacSHoward Hinnant// atomic_compare_exchange_strong
20299847abacSHoward Hinnant
20309847abacSHoward Hinnanttemplate <class _Tp>
20316de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
20329847abacSHoward Hinnantbool
2033fc4bff0cSOlivier Girouxatomic_compare_exchange_strong(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT
20349847abacSHoward Hinnant{
2035c772a620SHoward Hinnant    return __o->compare_exchange_strong(*__e, __d);
20369847abacSHoward Hinnant}
20379847abacSHoward Hinnant
20389847abacSHoward Hinnanttemplate <class _Tp>
20396de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
20409847abacSHoward Hinnantbool
2041fc4bff0cSOlivier Girouxatomic_compare_exchange_strong(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT
20429847abacSHoward Hinnant{
2043c772a620SHoward Hinnant    return __o->compare_exchange_strong(*__e, __d);
20449847abacSHoward Hinnant}
20459847abacSHoward Hinnant
20469847abacSHoward Hinnant// atomic_compare_exchange_weak_explicit
20479847abacSHoward Hinnant
20489847abacSHoward Hinnanttemplate <class _Tp>
20496de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
20509847abacSHoward Hinnantbool
2051fc4bff0cSOlivier Girouxatomic_compare_exchange_weak_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e,
2052fc4bff0cSOlivier Giroux                                      typename atomic<_Tp>::value_type __d,
2053d01320c2SHoward Hinnant                                      memory_order __s, memory_order __f) _NOEXCEPT
2054faf2a813SEric Fiselier  _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
20559847abacSHoward Hinnant{
2056c772a620SHoward Hinnant    return __o->compare_exchange_weak(*__e, __d, __s, __f);
20579847abacSHoward Hinnant}
20589847abacSHoward Hinnant
20599847abacSHoward Hinnanttemplate <class _Tp>
20606de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
20619847abacSHoward Hinnantbool
2062fc4bff0cSOlivier Girouxatomic_compare_exchange_weak_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d,
2063d01320c2SHoward Hinnant                                      memory_order __s, memory_order __f) _NOEXCEPT
2064faf2a813SEric Fiselier  _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
20659847abacSHoward Hinnant{
2066c772a620SHoward Hinnant    return __o->compare_exchange_weak(*__e, __d, __s, __f);
20679847abacSHoward Hinnant}
20689847abacSHoward Hinnant
20699847abacSHoward Hinnant// atomic_compare_exchange_strong_explicit
20709847abacSHoward Hinnant
20719847abacSHoward Hinnanttemplate <class _Tp>
20726de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
20739847abacSHoward Hinnantbool
20749847abacSHoward Hinnantatomic_compare_exchange_strong_explicit(volatile atomic<_Tp>* __o,
2075fc4bff0cSOlivier Giroux                                        typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d,
2076d01320c2SHoward Hinnant                                        memory_order __s, memory_order __f) _NOEXCEPT
2077faf2a813SEric Fiselier  _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
20789847abacSHoward Hinnant{
2079c772a620SHoward Hinnant    return __o->compare_exchange_strong(*__e, __d, __s, __f);
20809847abacSHoward Hinnant}
20819847abacSHoward Hinnant
20829847abacSHoward Hinnanttemplate <class _Tp>
20836de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
20849847abacSHoward Hinnantbool
2085fc4bff0cSOlivier Girouxatomic_compare_exchange_strong_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e,
2086fc4bff0cSOlivier Giroux                                        typename atomic<_Tp>::value_type __d,
2087d01320c2SHoward Hinnant                                        memory_order __s, memory_order __f) _NOEXCEPT
2088faf2a813SEric Fiselier  _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
20899847abacSHoward Hinnant{
2090c772a620SHoward Hinnant    return __o->compare_exchange_strong(*__e, __d, __s, __f);
20919847abacSHoward Hinnant}
20929847abacSHoward Hinnant
209354fa9ecdSOlivier Giroux// atomic_wait
209454fa9ecdSOlivier Giroux
209554fa9ecdSOlivier Girouxtemplate <class _Tp>
209646c38761SLouis Dionne_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
209754fa9ecdSOlivier Girouxvoid atomic_wait(const volatile atomic<_Tp>* __o,
209854fa9ecdSOlivier Giroux                 typename atomic<_Tp>::value_type __v) _NOEXCEPT
209954fa9ecdSOlivier Giroux{
210054fa9ecdSOlivier Giroux    return __o->wait(__v);
210154fa9ecdSOlivier Giroux}
210254fa9ecdSOlivier Giroux
210354fa9ecdSOlivier Girouxtemplate <class _Tp>
210446c38761SLouis Dionne_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
210554fa9ecdSOlivier Girouxvoid atomic_wait(const atomic<_Tp>* __o,
210654fa9ecdSOlivier Giroux                 typename atomic<_Tp>::value_type __v) _NOEXCEPT
210754fa9ecdSOlivier Giroux{
210854fa9ecdSOlivier Giroux    return __o->wait(__v);
210954fa9ecdSOlivier Giroux}
211054fa9ecdSOlivier Giroux
211154fa9ecdSOlivier Giroux// atomic_wait_explicit
211254fa9ecdSOlivier Giroux
211354fa9ecdSOlivier Girouxtemplate <class _Tp>
211446c38761SLouis Dionne_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
211554fa9ecdSOlivier Girouxvoid atomic_wait_explicit(const volatile atomic<_Tp>* __o,
211654fa9ecdSOlivier Giroux                          typename atomic<_Tp>::value_type __v,
211754fa9ecdSOlivier Giroux                          memory_order __m) _NOEXCEPT
211854fa9ecdSOlivier Giroux  _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
211954fa9ecdSOlivier Giroux{
212054fa9ecdSOlivier Giroux    return __o->wait(__v, __m);
212154fa9ecdSOlivier Giroux}
212254fa9ecdSOlivier Giroux
212354fa9ecdSOlivier Girouxtemplate <class _Tp>
212446c38761SLouis Dionne_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
212554fa9ecdSOlivier Girouxvoid atomic_wait_explicit(const atomic<_Tp>* __o,
212654fa9ecdSOlivier Giroux                          typename atomic<_Tp>::value_type __v,
212754fa9ecdSOlivier Giroux                          memory_order __m) _NOEXCEPT
212854fa9ecdSOlivier Giroux  _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
212954fa9ecdSOlivier Giroux{
213054fa9ecdSOlivier Giroux    return __o->wait(__v, __m);
213154fa9ecdSOlivier Giroux}
213254fa9ecdSOlivier Giroux
213354fa9ecdSOlivier Giroux// atomic_notify_one
213454fa9ecdSOlivier Giroux
213554fa9ecdSOlivier Girouxtemplate <class _Tp>
213646c38761SLouis Dionne_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
213754fa9ecdSOlivier Girouxvoid atomic_notify_one(volatile atomic<_Tp>* __o) _NOEXCEPT
213854fa9ecdSOlivier Giroux{
213954fa9ecdSOlivier Giroux    __o->notify_one();
214054fa9ecdSOlivier Giroux}
214154fa9ecdSOlivier Girouxtemplate <class _Tp>
214246c38761SLouis Dionne_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
214354fa9ecdSOlivier Girouxvoid atomic_notify_one(atomic<_Tp>* __o) _NOEXCEPT
214454fa9ecdSOlivier Giroux{
214554fa9ecdSOlivier Giroux    __o->notify_one();
214654fa9ecdSOlivier Giroux}
214754fa9ecdSOlivier Giroux
214854fa9ecdSOlivier Giroux// atomic_notify_one
214954fa9ecdSOlivier Giroux
215054fa9ecdSOlivier Girouxtemplate <class _Tp>
215146c38761SLouis Dionne_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
215254fa9ecdSOlivier Girouxvoid atomic_notify_all(volatile atomic<_Tp>* __o) _NOEXCEPT
215354fa9ecdSOlivier Giroux{
215454fa9ecdSOlivier Giroux    __o->notify_all();
215554fa9ecdSOlivier Giroux}
215654fa9ecdSOlivier Girouxtemplate <class _Tp>
215746c38761SLouis Dionne_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
215854fa9ecdSOlivier Girouxvoid atomic_notify_all(atomic<_Tp>* __o) _NOEXCEPT
215954fa9ecdSOlivier Giroux{
216054fa9ecdSOlivier Giroux    __o->notify_all();
216154fa9ecdSOlivier Giroux}
216254fa9ecdSOlivier Giroux
2163c772a620SHoward Hinnant// atomic_fetch_add
21649847abacSHoward Hinnant
21659847abacSHoward Hinnanttemplate <class _Tp>
21666de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
2167c772a620SHoward Hinnant_Tp
2168fc4bff0cSOlivier Girouxatomic_fetch_add(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT
21699847abacSHoward Hinnant{
2170c772a620SHoward Hinnant    return __o->fetch_add(__op);
2171c772a620SHoward Hinnant}
21729847abacSHoward Hinnant
2173c772a620SHoward Hinnanttemplate <class _Tp>
21746de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
2175c772a620SHoward Hinnant_Tp
2176fc4bff0cSOlivier Girouxatomic_fetch_add(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT
2177c772a620SHoward Hinnant{
2178c772a620SHoward Hinnant    return __o->fetch_add(__op);
2179c772a620SHoward Hinnant}
2180c772a620SHoward Hinnant
2181c772a620SHoward Hinnant// atomic_fetch_add_explicit
2182c772a620SHoward Hinnant
2183c772a620SHoward Hinnanttemplate <class _Tp>
21846de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
2185aac5b84dSMark de Wever_Tp atomic_fetch_add_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT
2186c772a620SHoward Hinnant{
2187c772a620SHoward Hinnant    return __o->fetch_add(__op, __m);
2188c772a620SHoward Hinnant}
2189c772a620SHoward Hinnant
2190c772a620SHoward Hinnanttemplate <class _Tp>
21916de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
2192aac5b84dSMark de Wever_Tp atomic_fetch_add_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT
219359fc8677SOlivier Giroux{
219459fc8677SOlivier Giroux    return __o->fetch_add(__op, __m);
219559fc8677SOlivier Giroux}
219659fc8677SOlivier Giroux
2197c772a620SHoward Hinnant// atomic_fetch_sub
2198c772a620SHoward Hinnant
2199c772a620SHoward Hinnanttemplate <class _Tp>
22006de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
2201aac5b84dSMark de Wever_Tp atomic_fetch_sub(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT
2202c772a620SHoward Hinnant{
2203c772a620SHoward Hinnant    return __o->fetch_sub(__op);
2204c772a620SHoward Hinnant}
2205c772a620SHoward Hinnant
2206c772a620SHoward Hinnanttemplate <class _Tp>
22076de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
2208aac5b84dSMark de Wever_Tp atomic_fetch_sub(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT
220959fc8677SOlivier Giroux{
221059fc8677SOlivier Giroux    return __o->fetch_sub(__op);
221159fc8677SOlivier Giroux}
221259fc8677SOlivier Giroux
2213c772a620SHoward Hinnant// atomic_fetch_sub_explicit
2214c772a620SHoward Hinnant
2215c772a620SHoward Hinnanttemplate <class _Tp>
22166de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
2217aac5b84dSMark de Wever_Tp atomic_fetch_sub_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT
2218c772a620SHoward Hinnant{
2219c772a620SHoward Hinnant    return __o->fetch_sub(__op, __m);
2220c772a620SHoward Hinnant}
2221c772a620SHoward Hinnant
2222c772a620SHoward Hinnanttemplate <class _Tp>
22236de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
2224aac5b84dSMark de Wever_Tp atomic_fetch_sub_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT
222559fc8677SOlivier Giroux{
222659fc8677SOlivier Giroux    return __o->fetch_sub(__op, __m);
222759fc8677SOlivier Giroux}
222859fc8677SOlivier Giroux
2229c772a620SHoward Hinnant// atomic_fetch_and
2230c772a620SHoward Hinnant
2231c772a620SHoward Hinnanttemplate <class _Tp>
22326de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
2233c772a620SHoward Hinnanttypename enable_if
2234c772a620SHoward Hinnant<
2235c772a620SHoward Hinnant    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2236c772a620SHoward Hinnant    _Tp
2237c772a620SHoward Hinnant>::type
2238fc4bff0cSOlivier Girouxatomic_fetch_and(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
2239c772a620SHoward Hinnant{
2240c772a620SHoward Hinnant    return __o->fetch_and(__op);
2241c772a620SHoward Hinnant}
2242c772a620SHoward Hinnant
2243c772a620SHoward Hinnanttemplate <class _Tp>
22446de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
2245c772a620SHoward Hinnanttypename enable_if
2246c772a620SHoward Hinnant<
2247c772a620SHoward Hinnant    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2248c772a620SHoward Hinnant    _Tp
2249c772a620SHoward Hinnant>::type
2250fc4bff0cSOlivier Girouxatomic_fetch_and(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
2251c772a620SHoward Hinnant{
2252c772a620SHoward Hinnant    return __o->fetch_and(__op);
2253c772a620SHoward Hinnant}
2254c772a620SHoward Hinnant
2255c772a620SHoward Hinnant// atomic_fetch_and_explicit
2256c772a620SHoward Hinnant
2257c772a620SHoward Hinnanttemplate <class _Tp>
22586de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
2259c772a620SHoward Hinnanttypename enable_if
2260c772a620SHoward Hinnant<
2261c772a620SHoward Hinnant    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2262c772a620SHoward Hinnant    _Tp
2263c772a620SHoward Hinnant>::type
2264fc4bff0cSOlivier Girouxatomic_fetch_and_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
2265c772a620SHoward Hinnant{
2266c772a620SHoward Hinnant    return __o->fetch_and(__op, __m);
2267c772a620SHoward Hinnant}
2268c772a620SHoward Hinnant
2269c772a620SHoward Hinnanttemplate <class _Tp>
22706de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
2271c772a620SHoward Hinnanttypename enable_if
2272c772a620SHoward Hinnant<
2273c772a620SHoward Hinnant    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2274c772a620SHoward Hinnant    _Tp
2275c772a620SHoward Hinnant>::type
2276fc4bff0cSOlivier Girouxatomic_fetch_and_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
2277c772a620SHoward Hinnant{
2278c772a620SHoward Hinnant    return __o->fetch_and(__op, __m);
2279c772a620SHoward Hinnant}
2280c772a620SHoward Hinnant
2281c772a620SHoward Hinnant// atomic_fetch_or
2282c772a620SHoward Hinnant
2283c772a620SHoward Hinnanttemplate <class _Tp>
22846de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
2285c772a620SHoward Hinnanttypename enable_if
2286c772a620SHoward Hinnant<
2287c772a620SHoward Hinnant    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2288c772a620SHoward Hinnant    _Tp
2289c772a620SHoward Hinnant>::type
2290fc4bff0cSOlivier Girouxatomic_fetch_or(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
2291c772a620SHoward Hinnant{
2292c772a620SHoward Hinnant    return __o->fetch_or(__op);
2293c772a620SHoward Hinnant}
2294c772a620SHoward Hinnant
2295c772a620SHoward Hinnanttemplate <class _Tp>
22966de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
2297c772a620SHoward Hinnanttypename enable_if
2298c772a620SHoward Hinnant<
2299c772a620SHoward Hinnant    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2300c772a620SHoward Hinnant    _Tp
2301c772a620SHoward Hinnant>::type
2302fc4bff0cSOlivier Girouxatomic_fetch_or(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
2303c772a620SHoward Hinnant{
2304c772a620SHoward Hinnant    return __o->fetch_or(__op);
2305c772a620SHoward Hinnant}
2306c772a620SHoward Hinnant
2307c772a620SHoward Hinnant// atomic_fetch_or_explicit
2308c772a620SHoward Hinnant
2309c772a620SHoward Hinnanttemplate <class _Tp>
23106de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
2311c772a620SHoward Hinnanttypename enable_if
2312c772a620SHoward Hinnant<
2313c772a620SHoward Hinnant    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2314c772a620SHoward Hinnant    _Tp
2315c772a620SHoward Hinnant>::type
2316fc4bff0cSOlivier Girouxatomic_fetch_or_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
2317c772a620SHoward Hinnant{
2318c772a620SHoward Hinnant    return __o->fetch_or(__op, __m);
2319c772a620SHoward Hinnant}
2320c772a620SHoward Hinnant
2321c772a620SHoward Hinnanttemplate <class _Tp>
23226de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
2323c772a620SHoward Hinnanttypename enable_if
2324c772a620SHoward Hinnant<
2325c772a620SHoward Hinnant    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2326c772a620SHoward Hinnant    _Tp
2327c772a620SHoward Hinnant>::type
2328fc4bff0cSOlivier Girouxatomic_fetch_or_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
2329c772a620SHoward Hinnant{
2330c772a620SHoward Hinnant    return __o->fetch_or(__op, __m);
2331c772a620SHoward Hinnant}
2332c772a620SHoward Hinnant
2333c772a620SHoward Hinnant// atomic_fetch_xor
2334c772a620SHoward Hinnant
2335c772a620SHoward Hinnanttemplate <class _Tp>
23366de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
2337c772a620SHoward Hinnanttypename enable_if
2338c772a620SHoward Hinnant<
2339c772a620SHoward Hinnant    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2340c772a620SHoward Hinnant    _Tp
2341c772a620SHoward Hinnant>::type
2342fc4bff0cSOlivier Girouxatomic_fetch_xor(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
2343c772a620SHoward Hinnant{
2344c772a620SHoward Hinnant    return __o->fetch_xor(__op);
2345c772a620SHoward Hinnant}
2346c772a620SHoward Hinnant
2347c772a620SHoward Hinnanttemplate <class _Tp>
23486de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
2349c772a620SHoward Hinnanttypename enable_if
2350c772a620SHoward Hinnant<
2351c772a620SHoward Hinnant    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2352c772a620SHoward Hinnant    _Tp
2353c772a620SHoward Hinnant>::type
2354fc4bff0cSOlivier Girouxatomic_fetch_xor(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
2355c772a620SHoward Hinnant{
2356c772a620SHoward Hinnant    return __o->fetch_xor(__op);
2357c772a620SHoward Hinnant}
2358c772a620SHoward Hinnant
2359c772a620SHoward Hinnant// atomic_fetch_xor_explicit
2360c772a620SHoward Hinnant
2361c772a620SHoward Hinnanttemplate <class _Tp>
23626de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
2363c772a620SHoward Hinnanttypename enable_if
2364c772a620SHoward Hinnant<
2365c772a620SHoward Hinnant    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2366c772a620SHoward Hinnant    _Tp
2367c772a620SHoward Hinnant>::type
2368fc4bff0cSOlivier Girouxatomic_fetch_xor_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
2369c772a620SHoward Hinnant{
2370c772a620SHoward Hinnant    return __o->fetch_xor(__op, __m);
2371c772a620SHoward Hinnant}
2372c772a620SHoward Hinnant
2373c772a620SHoward Hinnanttemplate <class _Tp>
23746de760acSDavide Italiano_LIBCPP_INLINE_VISIBILITY
2375c772a620SHoward Hinnanttypename enable_if
2376c772a620SHoward Hinnant<
2377c772a620SHoward Hinnant    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2378c772a620SHoward Hinnant    _Tp
2379c772a620SHoward Hinnant>::type
2380fc4bff0cSOlivier Girouxatomic_fetch_xor_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
2381c772a620SHoward Hinnant{
2382c772a620SHoward Hinnant    return __o->fetch_xor(__op, __m);
2383c772a620SHoward Hinnant}
23849847abacSHoward Hinnant
2385b5452b3dSHoward Hinnant// flag type and operations
2386b5452b3dSHoward Hinnant
2387b5452b3dSHoward Hinnanttypedef struct atomic_flag
2388b5452b3dSHoward Hinnant{
23896de760acSDavide Italiano    __cxx_atomic_impl<_LIBCPP_ATOMIC_FLAG_TYPE> __a_;
2390b5452b3dSHoward Hinnant
2391b5452b3dSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
239254fa9ecdSOlivier Giroux    bool test(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
239354fa9ecdSOlivier Giroux        {return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m);}
239454fa9ecdSOlivier Giroux    _LIBCPP_INLINE_VISIBILITY
239554fa9ecdSOlivier Giroux    bool test(memory_order __m = memory_order_seq_cst) const _NOEXCEPT
239654fa9ecdSOlivier Giroux        {return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m);}
239754fa9ecdSOlivier Giroux
239854fa9ecdSOlivier Giroux    _LIBCPP_INLINE_VISIBILITY
2399d01320c2SHoward Hinnant    bool test_and_set(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
24006de760acSDavide Italiano        {return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);}
2401b5452b3dSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
2402d01320c2SHoward Hinnant    bool test_and_set(memory_order __m = memory_order_seq_cst) _NOEXCEPT
24036de760acSDavide Italiano        {return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);}
2404b5452b3dSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
2405d01320c2SHoward Hinnant    void clear(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
24066de760acSDavide Italiano        {__cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);}
2407b5452b3dSHoward Hinnant    _LIBCPP_INLINE_VISIBILITY
2408d01320c2SHoward Hinnant    void clear(memory_order __m = memory_order_seq_cst) _NOEXCEPT
24096de760acSDavide Italiano        {__cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);}
2410b5452b3dSHoward Hinnant
241146c38761SLouis Dionne    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
241254fa9ecdSOlivier Giroux    void wait(bool __v, memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
241354fa9ecdSOlivier Giroux        {__cxx_atomic_wait(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);}
241446c38761SLouis Dionne    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
241554fa9ecdSOlivier Giroux    void wait(bool __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT
241654fa9ecdSOlivier Giroux        {__cxx_atomic_wait(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);}
241746c38761SLouis Dionne    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
241854fa9ecdSOlivier Giroux    void notify_one() volatile _NOEXCEPT
241954fa9ecdSOlivier Giroux        {__cxx_atomic_notify_one(&__a_);}
242046c38761SLouis Dionne    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
242154fa9ecdSOlivier Giroux    void notify_one() _NOEXCEPT
242254fa9ecdSOlivier Giroux        {__cxx_atomic_notify_one(&__a_);}
242346c38761SLouis Dionne    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
242454fa9ecdSOlivier Giroux    void notify_all() volatile _NOEXCEPT
242554fa9ecdSOlivier Giroux        {__cxx_atomic_notify_all(&__a_);}
242646c38761SLouis Dionne    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
242754fa9ecdSOlivier Giroux    void notify_all() _NOEXCEPT
242854fa9ecdSOlivier Giroux        {__cxx_atomic_notify_all(&__a_);}
242954fa9ecdSOlivier Giroux
243056aac567SRaul Tambre#if _LIBCPP_STD_VER > 17
243156aac567SRaul Tambre    _LIBCPP_INLINE_VISIBILITY constexpr
243256aac567SRaul Tambre    atomic_flag() _NOEXCEPT : __a_(false) {}
243356aac567SRaul Tambre#else
243454fa9ecdSOlivier Giroux    _LIBCPP_INLINE_VISIBILITY
24354955095fSNikolas Klauser    atomic_flag() _NOEXCEPT = default;
243656aac567SRaul Tambre#endif
2437da9ca0b4SHoward Hinnant
24383df56fddSMarshall Clow    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
243915a29721SEric Fiselier    atomic_flag(bool __b) _NOEXCEPT : __a_(__b) {} // EXTENSION
2440b5452b3dSHoward Hinnant
24418f56dedbSEric Fiselier#ifndef _LIBCPP_CXX03_LANG
2442b5452b3dSHoward Hinnant    atomic_flag(const atomic_flag&) = delete;
2443b5452b3dSHoward Hinnant    atomic_flag& operator=(const atomic_flag&) = delete;
2444b5452b3dSHoward Hinnant    atomic_flag& operator=(const atomic_flag&) volatile = delete;
24458f56dedbSEric Fiselier#else
2446b5452b3dSHoward Hinnantprivate:
244754fa9ecdSOlivier Giroux    _LIBCPP_INLINE_VISIBILITY
2448b5452b3dSHoward Hinnant    atomic_flag(const atomic_flag&);
244954fa9ecdSOlivier Giroux    _LIBCPP_INLINE_VISIBILITY
2450b5452b3dSHoward Hinnant    atomic_flag& operator=(const atomic_flag&);
245154fa9ecdSOlivier Giroux    _LIBCPP_INLINE_VISIBILITY
2452b5452b3dSHoward Hinnant    atomic_flag& operator=(const atomic_flag&) volatile;
24538f56dedbSEric Fiselier#endif
2454b5452b3dSHoward Hinnant} atomic_flag;
2455b5452b3dSHoward Hinnant
245654fa9ecdSOlivier Giroux
245754fa9ecdSOlivier Girouxinline _LIBCPP_INLINE_VISIBILITY
245854fa9ecdSOlivier Girouxbool
245954fa9ecdSOlivier Girouxatomic_flag_test(const volatile atomic_flag* __o) _NOEXCEPT
246054fa9ecdSOlivier Giroux{
246154fa9ecdSOlivier Giroux    return __o->test();
246254fa9ecdSOlivier Giroux}
246354fa9ecdSOlivier Giroux
246454fa9ecdSOlivier Girouxinline _LIBCPP_INLINE_VISIBILITY
246554fa9ecdSOlivier Girouxbool
246654fa9ecdSOlivier Girouxatomic_flag_test(const atomic_flag* __o) _NOEXCEPT
246754fa9ecdSOlivier Giroux{
246854fa9ecdSOlivier Giroux    return __o->test();
246954fa9ecdSOlivier Giroux}
247054fa9ecdSOlivier Giroux
247154fa9ecdSOlivier Girouxinline _LIBCPP_INLINE_VISIBILITY
247254fa9ecdSOlivier Girouxbool
247354fa9ecdSOlivier Girouxatomic_flag_test_explicit(const volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
247454fa9ecdSOlivier Giroux{
247554fa9ecdSOlivier Giroux    return __o->test(__m);
247654fa9ecdSOlivier Giroux}
247754fa9ecdSOlivier Giroux
247854fa9ecdSOlivier Girouxinline _LIBCPP_INLINE_VISIBILITY
247954fa9ecdSOlivier Girouxbool
248054fa9ecdSOlivier Girouxatomic_flag_test_explicit(const atomic_flag* __o, memory_order __m) _NOEXCEPT
248154fa9ecdSOlivier Giroux{
248254fa9ecdSOlivier Giroux    return __o->test(__m);
248354fa9ecdSOlivier Giroux}
248454fa9ecdSOlivier Giroux
2485b5452b3dSHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
2486b5452b3dSHoward Hinnantbool
2487d01320c2SHoward Hinnantatomic_flag_test_and_set(volatile atomic_flag* __o) _NOEXCEPT
2488b5452b3dSHoward Hinnant{
2489b5452b3dSHoward Hinnant    return __o->test_and_set();
2490b5452b3dSHoward Hinnant}
2491b5452b3dSHoward Hinnant
2492b5452b3dSHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
2493b5452b3dSHoward Hinnantbool
2494d01320c2SHoward Hinnantatomic_flag_test_and_set(atomic_flag* __o) _NOEXCEPT
2495b5452b3dSHoward Hinnant{
2496b5452b3dSHoward Hinnant    return __o->test_and_set();
2497b5452b3dSHoward Hinnant}
2498b5452b3dSHoward Hinnant
2499b5452b3dSHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
2500b5452b3dSHoward Hinnantbool
2501d01320c2SHoward Hinnantatomic_flag_test_and_set_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
2502b5452b3dSHoward Hinnant{
2503b5452b3dSHoward Hinnant    return __o->test_and_set(__m);
2504b5452b3dSHoward Hinnant}
2505b5452b3dSHoward Hinnant
2506b5452b3dSHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
2507b5452b3dSHoward Hinnantbool
2508d01320c2SHoward Hinnantatomic_flag_test_and_set_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT
2509b5452b3dSHoward Hinnant{
2510b5452b3dSHoward Hinnant    return __o->test_and_set(__m);
2511b5452b3dSHoward Hinnant}
2512b5452b3dSHoward Hinnant
2513b5452b3dSHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
2514b5452b3dSHoward Hinnantvoid
2515d01320c2SHoward Hinnantatomic_flag_clear(volatile atomic_flag* __o) _NOEXCEPT
2516b5452b3dSHoward Hinnant{
2517b5452b3dSHoward Hinnant    __o->clear();
2518b5452b3dSHoward Hinnant}
2519b5452b3dSHoward Hinnant
2520b5452b3dSHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
2521b5452b3dSHoward Hinnantvoid
2522d01320c2SHoward Hinnantatomic_flag_clear(atomic_flag* __o) _NOEXCEPT
2523b5452b3dSHoward Hinnant{
2524b5452b3dSHoward Hinnant    __o->clear();
2525b5452b3dSHoward Hinnant}
2526b5452b3dSHoward Hinnant
2527b5452b3dSHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
2528b5452b3dSHoward Hinnantvoid
2529d01320c2SHoward Hinnantatomic_flag_clear_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
2530b5452b3dSHoward Hinnant{
2531b5452b3dSHoward Hinnant    __o->clear(__m);
2532b5452b3dSHoward Hinnant}
2533b5452b3dSHoward Hinnant
2534b5452b3dSHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
2535b5452b3dSHoward Hinnantvoid
2536d01320c2SHoward Hinnantatomic_flag_clear_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT
2537b5452b3dSHoward Hinnant{
2538b5452b3dSHoward Hinnant    __o->clear(__m);
2539b5452b3dSHoward Hinnant}
2540b5452b3dSHoward Hinnant
254146c38761SLouis Dionneinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
254254fa9ecdSOlivier Girouxvoid
254354fa9ecdSOlivier Girouxatomic_flag_wait(const volatile atomic_flag* __o, bool __v) _NOEXCEPT
254454fa9ecdSOlivier Giroux{
254554fa9ecdSOlivier Giroux    __o->wait(__v);
254654fa9ecdSOlivier Giroux}
254754fa9ecdSOlivier Giroux
254846c38761SLouis Dionneinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
254954fa9ecdSOlivier Girouxvoid
255054fa9ecdSOlivier Girouxatomic_flag_wait(const atomic_flag* __o, bool __v) _NOEXCEPT
255154fa9ecdSOlivier Giroux{
255254fa9ecdSOlivier Giroux    __o->wait(__v);
255354fa9ecdSOlivier Giroux}
255454fa9ecdSOlivier Giroux
255546c38761SLouis Dionneinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
255654fa9ecdSOlivier Girouxvoid
255754fa9ecdSOlivier Girouxatomic_flag_wait_explicit(const volatile atomic_flag* __o,
255854fa9ecdSOlivier Giroux                          bool __v, memory_order __m) _NOEXCEPT
255954fa9ecdSOlivier Giroux{
256054fa9ecdSOlivier Giroux    __o->wait(__v, __m);
256154fa9ecdSOlivier Giroux}
256254fa9ecdSOlivier Giroux
256346c38761SLouis Dionneinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
256454fa9ecdSOlivier Girouxvoid
256554fa9ecdSOlivier Girouxatomic_flag_wait_explicit(const atomic_flag* __o,
256654fa9ecdSOlivier Giroux                          bool __v, memory_order __m) _NOEXCEPT
256754fa9ecdSOlivier Giroux{
256854fa9ecdSOlivier Giroux    __o->wait(__v, __m);
256954fa9ecdSOlivier Giroux}
257054fa9ecdSOlivier Giroux
257146c38761SLouis Dionneinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
257254fa9ecdSOlivier Girouxvoid
257354fa9ecdSOlivier Girouxatomic_flag_notify_one(volatile atomic_flag* __o) _NOEXCEPT
257454fa9ecdSOlivier Giroux{
257554fa9ecdSOlivier Giroux    __o->notify_one();
257654fa9ecdSOlivier Giroux}
257754fa9ecdSOlivier Giroux
257846c38761SLouis Dionneinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
257954fa9ecdSOlivier Girouxvoid
258054fa9ecdSOlivier Girouxatomic_flag_notify_one(atomic_flag* __o) _NOEXCEPT
258154fa9ecdSOlivier Giroux{
258254fa9ecdSOlivier Giroux    __o->notify_one();
258354fa9ecdSOlivier Giroux}
258454fa9ecdSOlivier Giroux
258546c38761SLouis Dionneinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
258654fa9ecdSOlivier Girouxvoid
258754fa9ecdSOlivier Girouxatomic_flag_notify_all(volatile atomic_flag* __o) _NOEXCEPT
258854fa9ecdSOlivier Giroux{
258954fa9ecdSOlivier Giroux    __o->notify_all();
259054fa9ecdSOlivier Giroux}
259154fa9ecdSOlivier Giroux
259246c38761SLouis Dionneinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
259354fa9ecdSOlivier Girouxvoid
259454fa9ecdSOlivier Girouxatomic_flag_notify_all(atomic_flag* __o) _NOEXCEPT
259554fa9ecdSOlivier Giroux{
259654fa9ecdSOlivier Giroux    __o->notify_all();
259754fa9ecdSOlivier Giroux}
259854fa9ecdSOlivier Giroux
2599b5452b3dSHoward Hinnant// fences
2600b5452b3dSHoward Hinnant
2601b5452b3dSHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
2602b5452b3dSHoward Hinnantvoid
2603d01320c2SHoward Hinnantatomic_thread_fence(memory_order __m) _NOEXCEPT
2604b5452b3dSHoward Hinnant{
26056de760acSDavide Italiano    __cxx_atomic_thread_fence(__m);
2606b5452b3dSHoward Hinnant}
2607b5452b3dSHoward Hinnant
2608b5452b3dSHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY
2609b5452b3dSHoward Hinnantvoid
2610d01320c2SHoward Hinnantatomic_signal_fence(memory_order __m) _NOEXCEPT
2611b5452b3dSHoward Hinnant{
26126de760acSDavide Italiano    __cxx_atomic_signal_fence(__m);
2613b5452b3dSHoward Hinnant}
2614b5452b3dSHoward Hinnant
2615c5f5f0a1SHoward Hinnant// Atomics for standard typedef types
2616c5f5f0a1SHoward Hinnant
261711467662SHoward Hinnanttypedef atomic<bool>               atomic_bool;
2618c5f5f0a1SHoward Hinnanttypedef atomic<char>               atomic_char;
2619c5f5f0a1SHoward Hinnanttypedef atomic<signed char>        atomic_schar;
2620c5f5f0a1SHoward Hinnanttypedef atomic<unsigned char>      atomic_uchar;
2621c5f5f0a1SHoward Hinnanttypedef atomic<short>              atomic_short;
2622c5f5f0a1SHoward Hinnanttypedef atomic<unsigned short>     atomic_ushort;
2623c5f5f0a1SHoward Hinnanttypedef atomic<int>                atomic_int;
2624c5f5f0a1SHoward Hinnanttypedef atomic<unsigned int>       atomic_uint;
2625c5f5f0a1SHoward Hinnanttypedef atomic<long>               atomic_long;
2626c5f5f0a1SHoward Hinnanttypedef atomic<unsigned long>      atomic_ulong;
2627c5f5f0a1SHoward Hinnanttypedef atomic<long long>          atomic_llong;
2628c5f5f0a1SHoward Hinnanttypedef atomic<unsigned long long> atomic_ullong;
26295c40c994SArthur O'Dwyer#ifndef _LIBCPP_HAS_NO_CHAR8_T
26309c97e4efSMarek Kurdejtypedef atomic<char8_t>            atomic_char8_t;
26319c97e4efSMarek Kurdej#endif
2632c5f5f0a1SHoward Hinnanttypedef atomic<char16_t>           atomic_char16_t;
2633c5f5f0a1SHoward Hinnanttypedef atomic<char32_t>           atomic_char32_t;
2634f4c1258dSLouis Dionne#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
2635c5f5f0a1SHoward Hinnanttypedef atomic<wchar_t>            atomic_wchar_t;
2636f4c1258dSLouis Dionne#endif
2637c5f5f0a1SHoward Hinnant
2638c5f5f0a1SHoward Hinnanttypedef atomic<int_least8_t>   atomic_int_least8_t;
2639c5f5f0a1SHoward Hinnanttypedef atomic<uint_least8_t>  atomic_uint_least8_t;
2640c5f5f0a1SHoward Hinnanttypedef atomic<int_least16_t>  atomic_int_least16_t;
2641c5f5f0a1SHoward Hinnanttypedef atomic<uint_least16_t> atomic_uint_least16_t;
2642c5f5f0a1SHoward Hinnanttypedef atomic<int_least32_t>  atomic_int_least32_t;
2643c5f5f0a1SHoward Hinnanttypedef atomic<uint_least32_t> atomic_uint_least32_t;
2644c5f5f0a1SHoward Hinnanttypedef atomic<int_least64_t>  atomic_int_least64_t;
2645c5f5f0a1SHoward Hinnanttypedef atomic<uint_least64_t> atomic_uint_least64_t;
2646c5f5f0a1SHoward Hinnant
2647c5f5f0a1SHoward Hinnanttypedef atomic<int_fast8_t>   atomic_int_fast8_t;
2648c5f5f0a1SHoward Hinnanttypedef atomic<uint_fast8_t>  atomic_uint_fast8_t;
2649c5f5f0a1SHoward Hinnanttypedef atomic<int_fast16_t>  atomic_int_fast16_t;
2650c5f5f0a1SHoward Hinnanttypedef atomic<uint_fast16_t> atomic_uint_fast16_t;
2651c5f5f0a1SHoward Hinnanttypedef atomic<int_fast32_t>  atomic_int_fast32_t;
2652c5f5f0a1SHoward Hinnanttypedef atomic<uint_fast32_t> atomic_uint_fast32_t;
2653c5f5f0a1SHoward Hinnanttypedef atomic<int_fast64_t>  atomic_int_fast64_t;
2654c5f5f0a1SHoward Hinnanttypedef atomic<uint_fast64_t> atomic_uint_fast64_t;
2655c5f5f0a1SHoward Hinnant
2656e766a87bSMarshall Clowtypedef atomic< int8_t>  atomic_int8_t;
2657e766a87bSMarshall Clowtypedef atomic<uint8_t>  atomic_uint8_t;
2658e766a87bSMarshall Clowtypedef atomic< int16_t> atomic_int16_t;
2659e766a87bSMarshall Clowtypedef atomic<uint16_t> atomic_uint16_t;
2660e766a87bSMarshall Clowtypedef atomic< int32_t> atomic_int32_t;
2661e766a87bSMarshall Clowtypedef atomic<uint32_t> atomic_uint32_t;
2662e766a87bSMarshall Clowtypedef atomic< int64_t> atomic_int64_t;
2663e766a87bSMarshall Clowtypedef atomic<uint64_t> atomic_uint64_t;
2664e766a87bSMarshall Clow
2665c5f5f0a1SHoward Hinnanttypedef atomic<intptr_t>  atomic_intptr_t;
2666c5f5f0a1SHoward Hinnanttypedef atomic<uintptr_t> atomic_uintptr_t;
2667c5f5f0a1SHoward Hinnanttypedef atomic<size_t>    atomic_size_t;
2668c5f5f0a1SHoward Hinnanttypedef atomic<ptrdiff_t> atomic_ptrdiff_t;
2669c5f5f0a1SHoward Hinnanttypedef atomic<intmax_t>  atomic_intmax_t;
2670c5f5f0a1SHoward Hinnanttypedef atomic<uintmax_t> atomic_uintmax_t;
2671c5f5f0a1SHoward Hinnant
267254fa9ecdSOlivier Giroux// atomic_*_lock_free : prefer the contention type most highly, then the largest lock-free type
267354fa9ecdSOlivier Giroux
267454fa9ecdSOlivier Giroux#ifdef __cpp_lib_atomic_is_always_lock_free
267554fa9ecdSOlivier Giroux# define _LIBCPP_CONTENTION_LOCK_FREE __atomic_always_lock_free(sizeof(__cxx_contention_t), 0)
267654fa9ecdSOlivier Giroux#else
267754fa9ecdSOlivier Giroux# define _LIBCPP_CONTENTION_LOCK_FREE false
267854fa9ecdSOlivier Giroux#endif
267954fa9ecdSOlivier Giroux
268054fa9ecdSOlivier Giroux#if ATOMIC_LLONG_LOCK_FREE == 2
268154fa9ecdSOlivier Girouxtypedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, long long>::type          __libcpp_signed_lock_free;
268254fa9ecdSOlivier Girouxtypedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned long long>::type __libcpp_unsigned_lock_free;
268354fa9ecdSOlivier Giroux#elif ATOMIC_INT_LOCK_FREE == 2
268454fa9ecdSOlivier Girouxtypedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, int>::type                __libcpp_signed_lock_free;
268554fa9ecdSOlivier Girouxtypedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned int>::type       __libcpp_unsigned_lock_free;
268654fa9ecdSOlivier Giroux#elif ATOMIC_SHORT_LOCK_FREE == 2
268754fa9ecdSOlivier Girouxtypedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, short>::type              __libcpp_signed_lock_free;
268854fa9ecdSOlivier Girouxtypedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned short>::type     __libcpp_unsigned_lock_free;
268954fa9ecdSOlivier Giroux#elif ATOMIC_CHAR_LOCK_FREE == 2
269054fa9ecdSOlivier Girouxtypedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, char>::type               __libcpp_signed_lock_free;
269154fa9ecdSOlivier Girouxtypedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned char>::type      __libcpp_unsigned_lock_free;
269254fa9ecdSOlivier Giroux#else
269354fa9ecdSOlivier Giroux    // No signed/unsigned lock-free types
269454fa9ecdSOlivier Giroux#endif
269554fa9ecdSOlivier Giroux
269654fa9ecdSOlivier Girouxtypedef atomic<__libcpp_signed_lock_free> atomic_signed_lock_free;
269754fa9ecdSOlivier Girouxtypedef atomic<__libcpp_unsigned_lock_free> atomic_unsigned_lock_free;
269854fa9ecdSOlivier Giroux
269988efc1c7SHoward Hinnant#define ATOMIC_FLAG_INIT {false}
27002b672e24SHoward Hinnant#define ATOMIC_VAR_INIT(__v) {__v}
27012b672e24SHoward Hinnant
2702*4e730aebSRaul Tambre#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_DISABLE_DEPRECATION_WARNINGS)
2703*4e730aebSRaul Tambre# if defined(_LIBCPP_CLANG_VER) && _LIBCPP_CLANG_VER >= 1400
2704*4e730aebSRaul Tambre#  pragma clang deprecated(ATOMIC_FLAG_INIT)
2705*4e730aebSRaul Tambre#  pragma clang deprecated(ATOMIC_VAR_INIT)
2706*4e730aebSRaul Tambre# endif
2707*4e730aebSRaul Tambre#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_DISABLE_DEPRECATION_WARNINGS)
2708*4e730aebSRaul Tambre
2709cd39d413SHoward Hinnant_LIBCPP_END_NAMESPACE_STD
2710cd39d413SHoward Hinnant
2711cd39d413SHoward Hinnant#endif // _LIBCPP_ATOMIC
2712