xref: /freebsd/contrib/llvm-project/libcxx/include/atomic (revision fe6060f10f634930ff71b7c50291ddc610da2475)
10b57cec5SDimitry Andric// -*- C++ -*-
20b57cec5SDimitry Andric//===--------------------------- atomic -----------------------------------===//
30b57cec5SDimitry Andric//
40b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
50b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information.
60b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
70b57cec5SDimitry Andric//
80b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
90b57cec5SDimitry Andric
100b57cec5SDimitry Andric#ifndef _LIBCPP_ATOMIC
110b57cec5SDimitry Andric#define _LIBCPP_ATOMIC
120b57cec5SDimitry Andric
130b57cec5SDimitry Andric/*
140b57cec5SDimitry Andric    atomic synopsis
150b57cec5SDimitry Andric
160b57cec5SDimitry Andricnamespace std
170b57cec5SDimitry Andric{
180b57cec5SDimitry Andric
19e8d8bef9SDimitry Andric// feature test macro [version.syn]
200b57cec5SDimitry Andric
21e8d8bef9SDimitry Andric#define __cpp_lib_atomic_is_always_lock_free
22e8d8bef9SDimitry Andric#define __cpp_lib_atomic_flag_test
23e8d8bef9SDimitry Andric#define __cpp_lib_atomic_lock_free_type_aliases
24e8d8bef9SDimitry Andric#define __cpp_lib_atomic_wait
250b57cec5SDimitry Andric
260b57cec5SDimitry Andric // order and consistency
270b57cec5SDimitry Andric
280b57cec5SDimitry Andric enum memory_order: unspecified // enum class in C++20
290b57cec5SDimitry Andric {
300b57cec5SDimitry Andric    relaxed,
310b57cec5SDimitry Andric    consume, // load-consume
320b57cec5SDimitry Andric    acquire, // load-acquire
330b57cec5SDimitry Andric    release, // store-release
340b57cec5SDimitry Andric    acq_rel, // store-release load-acquire
350b57cec5SDimitry Andric    seq_cst // store-release load-acquire
360b57cec5SDimitry Andric };
370b57cec5SDimitry Andric
380b57cec5SDimitry Andric inline constexpr auto memory_order_relaxed = memory_order::relaxed;
390b57cec5SDimitry Andric inline constexpr auto memory_order_consume = memory_order::consume;
400b57cec5SDimitry Andric inline constexpr auto memory_order_acquire = memory_order::acquire;
410b57cec5SDimitry Andric inline constexpr auto memory_order_release = memory_order::release;
420b57cec5SDimitry Andric inline constexpr auto memory_order_acq_rel = memory_order::acq_rel;
430b57cec5SDimitry Andric inline constexpr auto memory_order_seq_cst = memory_order::seq_cst;
440b57cec5SDimitry Andric
450b57cec5SDimitry Andrictemplate <class T> T kill_dependency(T y) noexcept;
460b57cec5SDimitry Andric
470b57cec5SDimitry Andric// lock-free property
480b57cec5SDimitry Andric
490b57cec5SDimitry Andric#define ATOMIC_BOOL_LOCK_FREE unspecified
500b57cec5SDimitry Andric#define ATOMIC_CHAR_LOCK_FREE unspecified
51e8d8bef9SDimitry Andric#define ATOMIC_CHAR8_T_LOCK_FREE unspecified // C++20
520b57cec5SDimitry Andric#define ATOMIC_CHAR16_T_LOCK_FREE unspecified
530b57cec5SDimitry Andric#define ATOMIC_CHAR32_T_LOCK_FREE unspecified
540b57cec5SDimitry Andric#define ATOMIC_WCHAR_T_LOCK_FREE unspecified
550b57cec5SDimitry Andric#define ATOMIC_SHORT_LOCK_FREE unspecified
560b57cec5SDimitry Andric#define ATOMIC_INT_LOCK_FREE unspecified
570b57cec5SDimitry Andric#define ATOMIC_LONG_LOCK_FREE unspecified
580b57cec5SDimitry Andric#define ATOMIC_LLONG_LOCK_FREE unspecified
590b57cec5SDimitry Andric#define ATOMIC_POINTER_LOCK_FREE unspecified
600b57cec5SDimitry Andric
610b57cec5SDimitry Andrictemplate <class T>
620b57cec5SDimitry Andricstruct atomic
630b57cec5SDimitry Andric{
645ffd83dbSDimitry Andric    using value_type = T;
655ffd83dbSDimitry Andric
660b57cec5SDimitry Andric    static constexpr bool is_always_lock_free;
670b57cec5SDimitry Andric    bool is_lock_free() const volatile noexcept;
680b57cec5SDimitry Andric    bool is_lock_free() const noexcept;
695ffd83dbSDimitry Andric
70*fe6060f1SDimitry Andric    atomic() noexcept = default; // until C++20
71*fe6060f1SDimitry Andric    constexpr atomic() noexcept(is_nothrow_default_constructible_v<T>); // since C++20
725ffd83dbSDimitry Andric    constexpr atomic(T desr) noexcept;
735ffd83dbSDimitry Andric    atomic(const atomic&) = delete;
745ffd83dbSDimitry Andric    atomic& operator=(const atomic&) = delete;
755ffd83dbSDimitry Andric    atomic& operator=(const atomic&) volatile = delete;
765ffd83dbSDimitry Andric
770b57cec5SDimitry Andric    T load(memory_order m = memory_order_seq_cst) const volatile noexcept;
780b57cec5SDimitry Andric    T load(memory_order m = memory_order_seq_cst) const noexcept;
790b57cec5SDimitry Andric    operator T() const volatile noexcept;
800b57cec5SDimitry Andric    operator T() const noexcept;
815ffd83dbSDimitry Andric    void store(T desr, memory_order m = memory_order_seq_cst) volatile noexcept;
825ffd83dbSDimitry Andric    void store(T desr, memory_order m = memory_order_seq_cst) noexcept;
835ffd83dbSDimitry Andric    T operator=(T) volatile noexcept;
845ffd83dbSDimitry Andric    T operator=(T) noexcept;
855ffd83dbSDimitry Andric
860b57cec5SDimitry Andric    T exchange(T desr, memory_order m = memory_order_seq_cst) volatile noexcept;
870b57cec5SDimitry Andric    T exchange(T desr, memory_order m = memory_order_seq_cst) noexcept;
880b57cec5SDimitry Andric    bool compare_exchange_weak(T& expc, T desr,
890b57cec5SDimitry Andric                               memory_order s, memory_order f) volatile noexcept;
900b57cec5SDimitry Andric    bool compare_exchange_weak(T& expc, T desr, memory_order s, memory_order f) noexcept;
910b57cec5SDimitry Andric    bool compare_exchange_strong(T& expc, T desr,
920b57cec5SDimitry Andric                                 memory_order s, memory_order f) volatile noexcept;
930b57cec5SDimitry Andric    bool compare_exchange_strong(T& expc, T desr,
940b57cec5SDimitry Andric                                 memory_order s, memory_order f) noexcept;
950b57cec5SDimitry Andric    bool compare_exchange_weak(T& expc, T desr,
960b57cec5SDimitry Andric                               memory_order m = memory_order_seq_cst) volatile noexcept;
970b57cec5SDimitry Andric    bool compare_exchange_weak(T& expc, T desr,
980b57cec5SDimitry Andric                               memory_order m = memory_order_seq_cst) noexcept;
990b57cec5SDimitry Andric    bool compare_exchange_strong(T& expc, T desr,
1000b57cec5SDimitry Andric                                memory_order m = memory_order_seq_cst) volatile noexcept;
1010b57cec5SDimitry Andric    bool compare_exchange_strong(T& expc, T desr,
1020b57cec5SDimitry Andric                                 memory_order m = memory_order_seq_cst) noexcept;
1030b57cec5SDimitry Andric
1045ffd83dbSDimitry Andric    void wait(T, memory_order = memory_order::seq_cst) const volatile noexcept;
1055ffd83dbSDimitry Andric    void wait(T, memory_order = memory_order::seq_cst) const noexcept;
1065ffd83dbSDimitry Andric    void notify_one() volatile noexcept;
1075ffd83dbSDimitry Andric    void notify_one() noexcept;
1085ffd83dbSDimitry Andric    void notify_all() volatile noexcept;
1095ffd83dbSDimitry Andric    void notify_all() noexcept;
1100b57cec5SDimitry Andric};
1110b57cec5SDimitry Andric
1120b57cec5SDimitry Andrictemplate <>
1130b57cec5SDimitry Andricstruct atomic<integral>
1140b57cec5SDimitry Andric{
1155ffd83dbSDimitry Andric    using value_type = integral;
116e8d8bef9SDimitry Andric    using difference_type = value_type;
1175ffd83dbSDimitry Andric
1180b57cec5SDimitry Andric    static constexpr bool is_always_lock_free;
1190b57cec5SDimitry Andric    bool is_lock_free() const volatile noexcept;
1200b57cec5SDimitry Andric    bool is_lock_free() const noexcept;
1215ffd83dbSDimitry Andric
1225ffd83dbSDimitry Andric    atomic() noexcept = default;
1235ffd83dbSDimitry Andric    constexpr atomic(integral desr) noexcept;
1245ffd83dbSDimitry Andric    atomic(const atomic&) = delete;
1255ffd83dbSDimitry Andric    atomic& operator=(const atomic&) = delete;
1265ffd83dbSDimitry Andric    atomic& operator=(const atomic&) volatile = delete;
1275ffd83dbSDimitry Andric
1280b57cec5SDimitry Andric    integral load(memory_order m = memory_order_seq_cst) const volatile noexcept;
1290b57cec5SDimitry Andric    integral load(memory_order m = memory_order_seq_cst) const noexcept;
1300b57cec5SDimitry Andric    operator integral() const volatile noexcept;
1310b57cec5SDimitry Andric    operator integral() const noexcept;
1325ffd83dbSDimitry Andric    void store(integral desr, memory_order m = memory_order_seq_cst) volatile noexcept;
1335ffd83dbSDimitry Andric    void store(integral desr, memory_order m = memory_order_seq_cst) noexcept;
1345ffd83dbSDimitry Andric    integral operator=(integral desr) volatile noexcept;
1355ffd83dbSDimitry Andric    integral operator=(integral desr) noexcept;
1365ffd83dbSDimitry Andric
1370b57cec5SDimitry Andric    integral exchange(integral desr,
1380b57cec5SDimitry Andric                      memory_order m = memory_order_seq_cst) volatile noexcept;
1390b57cec5SDimitry Andric    integral exchange(integral desr, memory_order m = memory_order_seq_cst) noexcept;
1400b57cec5SDimitry Andric    bool compare_exchange_weak(integral& expc, integral desr,
1410b57cec5SDimitry Andric                               memory_order s, memory_order f) volatile noexcept;
1420b57cec5SDimitry Andric    bool compare_exchange_weak(integral& expc, integral desr,
1430b57cec5SDimitry Andric                               memory_order s, memory_order f) noexcept;
1440b57cec5SDimitry Andric    bool compare_exchange_strong(integral& expc, integral desr,
1450b57cec5SDimitry Andric                                 memory_order s, memory_order f) volatile noexcept;
1460b57cec5SDimitry Andric    bool compare_exchange_strong(integral& expc, integral desr,
1470b57cec5SDimitry Andric                                 memory_order s, memory_order f) noexcept;
1480b57cec5SDimitry Andric    bool compare_exchange_weak(integral& expc, integral desr,
1490b57cec5SDimitry Andric                               memory_order m = memory_order_seq_cst) volatile noexcept;
1500b57cec5SDimitry Andric    bool compare_exchange_weak(integral& expc, integral desr,
1510b57cec5SDimitry Andric                               memory_order m = memory_order_seq_cst) noexcept;
1520b57cec5SDimitry Andric    bool compare_exchange_strong(integral& expc, integral desr,
1530b57cec5SDimitry Andric                                memory_order m = memory_order_seq_cst) volatile noexcept;
1540b57cec5SDimitry Andric    bool compare_exchange_strong(integral& expc, integral desr,
1550b57cec5SDimitry Andric                                 memory_order m = memory_order_seq_cst) noexcept;
1560b57cec5SDimitry Andric
1575ffd83dbSDimitry Andric    integral fetch_add(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
1580b57cec5SDimitry Andric    integral fetch_add(integral op, memory_order m = memory_order_seq_cst) noexcept;
1595ffd83dbSDimitry Andric    integral fetch_sub(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
1600b57cec5SDimitry Andric    integral fetch_sub(integral op, memory_order m = memory_order_seq_cst) noexcept;
1615ffd83dbSDimitry Andric    integral fetch_and(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
1620b57cec5SDimitry Andric    integral fetch_and(integral op, memory_order m = memory_order_seq_cst) noexcept;
1635ffd83dbSDimitry Andric    integral fetch_or(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
1640b57cec5SDimitry Andric    integral fetch_or(integral op, memory_order m = memory_order_seq_cst) noexcept;
1655ffd83dbSDimitry Andric    integral fetch_xor(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
1660b57cec5SDimitry Andric    integral fetch_xor(integral op, memory_order m = memory_order_seq_cst) noexcept;
1670b57cec5SDimitry Andric
1680b57cec5SDimitry Andric    integral operator++(int) volatile noexcept;
1690b57cec5SDimitry Andric    integral operator++(int) noexcept;
1700b57cec5SDimitry Andric    integral operator--(int) volatile noexcept;
1710b57cec5SDimitry Andric    integral operator--(int) noexcept;
1720b57cec5SDimitry Andric    integral operator++() volatile noexcept;
1730b57cec5SDimitry Andric    integral operator++() noexcept;
1740b57cec5SDimitry Andric    integral operator--() volatile noexcept;
1750b57cec5SDimitry Andric    integral operator--() noexcept;
1760b57cec5SDimitry Andric    integral operator+=(integral op) volatile noexcept;
1770b57cec5SDimitry Andric    integral operator+=(integral op) noexcept;
1780b57cec5SDimitry Andric    integral operator-=(integral op) volatile noexcept;
1790b57cec5SDimitry Andric    integral operator-=(integral op) noexcept;
1800b57cec5SDimitry Andric    integral operator&=(integral op) volatile noexcept;
1810b57cec5SDimitry Andric    integral operator&=(integral op) noexcept;
1820b57cec5SDimitry Andric    integral operator|=(integral op) volatile noexcept;
1830b57cec5SDimitry Andric    integral operator|=(integral op) noexcept;
1840b57cec5SDimitry Andric    integral operator^=(integral op) volatile noexcept;
1850b57cec5SDimitry Andric    integral operator^=(integral op) noexcept;
1865ffd83dbSDimitry Andric
1875ffd83dbSDimitry Andric    void wait(integral, memory_order = memory_order::seq_cst) const volatile noexcept;
1885ffd83dbSDimitry Andric    void wait(integral, memory_order = memory_order::seq_cst) const noexcept;
1895ffd83dbSDimitry Andric    void notify_one() volatile noexcept;
1905ffd83dbSDimitry Andric    void notify_one() noexcept;
1915ffd83dbSDimitry Andric    void notify_all() volatile noexcept;
1925ffd83dbSDimitry Andric    void notify_all() noexcept;
1930b57cec5SDimitry Andric};
1940b57cec5SDimitry Andric
1950b57cec5SDimitry Andrictemplate <class T>
1960b57cec5SDimitry Andricstruct atomic<T*>
1970b57cec5SDimitry Andric{
1985ffd83dbSDimitry Andric    using value_type = T*;
199e8d8bef9SDimitry Andric    using difference_type = ptrdiff_t;
2005ffd83dbSDimitry Andric
2010b57cec5SDimitry Andric    static constexpr bool is_always_lock_free;
2020b57cec5SDimitry Andric    bool is_lock_free() const volatile noexcept;
2030b57cec5SDimitry Andric    bool is_lock_free() const noexcept;
2045ffd83dbSDimitry Andric
205*fe6060f1SDimitry Andric    atomic() noexcept = default; // until C++20
206*fe6060f1SDimitry Andric    constexpr atomic() noexcept; // since C++20
2075ffd83dbSDimitry Andric    constexpr atomic(T* desr) noexcept;
2085ffd83dbSDimitry Andric    atomic(const atomic&) = delete;
2095ffd83dbSDimitry Andric    atomic& operator=(const atomic&) = delete;
2105ffd83dbSDimitry Andric    atomic& operator=(const atomic&) volatile = delete;
2115ffd83dbSDimitry Andric
2120b57cec5SDimitry Andric    T* load(memory_order m = memory_order_seq_cst) const volatile noexcept;
2130b57cec5SDimitry Andric    T* load(memory_order m = memory_order_seq_cst) const noexcept;
2140b57cec5SDimitry Andric    operator T*() const volatile noexcept;
2150b57cec5SDimitry Andric    operator T*() const noexcept;
2165ffd83dbSDimitry Andric    void store(T* desr, memory_order m = memory_order_seq_cst) volatile noexcept;
2175ffd83dbSDimitry Andric    void store(T* desr, memory_order m = memory_order_seq_cst) noexcept;
2185ffd83dbSDimitry Andric    T* operator=(T*) volatile noexcept;
2195ffd83dbSDimitry Andric    T* operator=(T*) noexcept;
2205ffd83dbSDimitry Andric
2210b57cec5SDimitry Andric    T* exchange(T* desr, memory_order m = memory_order_seq_cst) volatile noexcept;
2220b57cec5SDimitry Andric    T* exchange(T* desr, memory_order m = memory_order_seq_cst) noexcept;
2230b57cec5SDimitry Andric    bool compare_exchange_weak(T*& expc, T* desr,
2240b57cec5SDimitry Andric                               memory_order s, memory_order f) volatile noexcept;
2250b57cec5SDimitry Andric    bool compare_exchange_weak(T*& expc, T* desr,
2260b57cec5SDimitry Andric                               memory_order s, memory_order f) noexcept;
2270b57cec5SDimitry Andric    bool compare_exchange_strong(T*& expc, T* desr,
2280b57cec5SDimitry Andric                                 memory_order s, memory_order f) volatile noexcept;
2290b57cec5SDimitry Andric    bool compare_exchange_strong(T*& expc, T* desr,
2300b57cec5SDimitry Andric                                 memory_order s, memory_order f) noexcept;
2310b57cec5SDimitry Andric    bool compare_exchange_weak(T*& expc, T* desr,
2320b57cec5SDimitry Andric                               memory_order m = memory_order_seq_cst) volatile noexcept;
2330b57cec5SDimitry Andric    bool compare_exchange_weak(T*& expc, T* desr,
2340b57cec5SDimitry Andric                               memory_order m = memory_order_seq_cst) noexcept;
2350b57cec5SDimitry Andric    bool compare_exchange_strong(T*& expc, T* desr,
2360b57cec5SDimitry Andric                                memory_order m = memory_order_seq_cst) volatile noexcept;
2370b57cec5SDimitry Andric    bool compare_exchange_strong(T*& expc, T* desr,
2380b57cec5SDimitry Andric                                 memory_order m = memory_order_seq_cst) noexcept;
2390b57cec5SDimitry Andric    T* fetch_add(ptrdiff_t op, memory_order m = memory_order_seq_cst) volatile noexcept;
2400b57cec5SDimitry Andric    T* fetch_add(ptrdiff_t op, memory_order m = memory_order_seq_cst) noexcept;
2410b57cec5SDimitry Andric    T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst) volatile noexcept;
2420b57cec5SDimitry Andric    T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst) noexcept;
2430b57cec5SDimitry Andric
2440b57cec5SDimitry Andric    T* operator++(int) volatile noexcept;
2450b57cec5SDimitry Andric    T* operator++(int) noexcept;
2460b57cec5SDimitry Andric    T* operator--(int) volatile noexcept;
2470b57cec5SDimitry Andric    T* operator--(int) noexcept;
2480b57cec5SDimitry Andric    T* operator++() volatile noexcept;
2490b57cec5SDimitry Andric    T* operator++() noexcept;
2500b57cec5SDimitry Andric    T* operator--() volatile noexcept;
2510b57cec5SDimitry Andric    T* operator--() noexcept;
2520b57cec5SDimitry Andric    T* operator+=(ptrdiff_t op) volatile noexcept;
2530b57cec5SDimitry Andric    T* operator+=(ptrdiff_t op) noexcept;
2540b57cec5SDimitry Andric    T* operator-=(ptrdiff_t op) volatile noexcept;
2550b57cec5SDimitry Andric    T* operator-=(ptrdiff_t op) noexcept;
2565ffd83dbSDimitry Andric
2575ffd83dbSDimitry Andric    void wait(T*, memory_order = memory_order::seq_cst) const volatile noexcept;
2585ffd83dbSDimitry Andric    void wait(T*, memory_order = memory_order::seq_cst) const noexcept;
2595ffd83dbSDimitry Andric    void notify_one() volatile noexcept;
2605ffd83dbSDimitry Andric    void notify_one() noexcept;
2615ffd83dbSDimitry Andric    void notify_all() volatile noexcept;
2625ffd83dbSDimitry Andric    void notify_all() noexcept;
2630b57cec5SDimitry Andric};
2640b57cec5SDimitry Andric
2650b57cec5SDimitry Andric
2660b57cec5SDimitry Andrictemplate <class T>
2675ffd83dbSDimitry Andric  bool atomic_is_lock_free(const volatile atomic<T>* obj) noexcept;
2680b57cec5SDimitry Andric
2690b57cec5SDimitry Andrictemplate <class T>
2705ffd83dbSDimitry Andric  bool atomic_is_lock_free(const atomic<T>* obj) noexcept;
2710b57cec5SDimitry Andric
2720b57cec5SDimitry Andrictemplate <class T>
2735ffd83dbSDimitry Andric  void atomic_store(volatile atomic<T>* obj, T desr) noexcept;
2740b57cec5SDimitry Andric
2750b57cec5SDimitry Andrictemplate <class T>
2765ffd83dbSDimitry Andric  void atomic_store(atomic<T>* obj, T desr) noexcept;
2770b57cec5SDimitry Andric
2780b57cec5SDimitry Andrictemplate <class T>
2795ffd83dbSDimitry Andric  void atomic_store_explicit(volatile atomic<T>* obj, T desr, memory_order m) noexcept;
2800b57cec5SDimitry Andric
2810b57cec5SDimitry Andrictemplate <class T>
2825ffd83dbSDimitry Andric  void atomic_store_explicit(atomic<T>* obj, T desr, memory_order m) noexcept;
2830b57cec5SDimitry Andric
2840b57cec5SDimitry Andrictemplate <class T>
2855ffd83dbSDimitry Andric  T atomic_load(const volatile atomic<T>* obj) noexcept;
2860b57cec5SDimitry Andric
2870b57cec5SDimitry Andrictemplate <class T>
2885ffd83dbSDimitry Andric  T atomic_load(const atomic<T>* obj) noexcept;
2890b57cec5SDimitry Andric
2900b57cec5SDimitry Andrictemplate <class T>
2915ffd83dbSDimitry Andric  T atomic_load_explicit(const volatile atomic<T>* obj, memory_order m) noexcept;
2920b57cec5SDimitry Andric
2930b57cec5SDimitry Andrictemplate <class T>
2945ffd83dbSDimitry Andric  T atomic_load_explicit(const atomic<T>* obj, memory_order m) noexcept;
2950b57cec5SDimitry Andric
2960b57cec5SDimitry Andrictemplate <class T>
2975ffd83dbSDimitry Andric  T atomic_exchange(volatile atomic<T>* obj, T desr) noexcept;
2980b57cec5SDimitry Andric
2990b57cec5SDimitry Andrictemplate <class T>
3005ffd83dbSDimitry Andric  T atomic_exchange(atomic<T>* obj, T desr) noexcept;
3010b57cec5SDimitry Andric
3020b57cec5SDimitry Andrictemplate <class T>
3035ffd83dbSDimitry Andric  T atomic_exchange_explicit(volatile atomic<T>* obj, T desr, memory_order m) noexcept;
3040b57cec5SDimitry Andric
3050b57cec5SDimitry Andrictemplate <class T>
3065ffd83dbSDimitry Andric  T atomic_exchange_explicit(atomic<T>* obj, T desr, memory_order m) noexcept;
3070b57cec5SDimitry Andric
3080b57cec5SDimitry Andrictemplate <class T>
3095ffd83dbSDimitry Andric  bool atomic_compare_exchange_weak(volatile atomic<T>* obj, T* expc, T desr) noexcept;
3100b57cec5SDimitry Andric
3110b57cec5SDimitry Andrictemplate <class T>
3125ffd83dbSDimitry Andric  bool atomic_compare_exchange_weak(atomic<T>* obj, T* expc, T desr) noexcept;
3130b57cec5SDimitry Andric
3140b57cec5SDimitry Andrictemplate <class T>
3155ffd83dbSDimitry Andric  bool atomic_compare_exchange_strong(volatile atomic<T>* obj, T* expc, T desr) noexcept;
3160b57cec5SDimitry Andric
3170b57cec5SDimitry Andrictemplate <class T>
3185ffd83dbSDimitry Andric  bool atomic_compare_exchange_strong(atomic<T>* obj, T* expc, T desr) noexcept;
3190b57cec5SDimitry Andric
3200b57cec5SDimitry Andrictemplate <class T>
3215ffd83dbSDimitry Andric  bool atomic_compare_exchange_weak_explicit(volatile atomic<T>* obj, T* expc,
3220b57cec5SDimitry Andric                                             T desr,
3230b57cec5SDimitry Andric                                             memory_order s, memory_order f) noexcept;
3240b57cec5SDimitry Andric
3250b57cec5SDimitry Andrictemplate <class T>
3265ffd83dbSDimitry Andric  bool atomic_compare_exchange_weak_explicit(atomic<T>* obj, T* expc, T desr,
3270b57cec5SDimitry Andric                                             memory_order s, memory_order f) noexcept;
3280b57cec5SDimitry Andric
3290b57cec5SDimitry Andrictemplate <class T>
3305ffd83dbSDimitry Andric  bool atomic_compare_exchange_strong_explicit(volatile atomic<T>* obj,
3310b57cec5SDimitry Andric                                               T* expc, T desr,
3320b57cec5SDimitry Andric                                               memory_order s, memory_order f) noexcept;
3330b57cec5SDimitry Andric
3340b57cec5SDimitry Andrictemplate <class T>
3355ffd83dbSDimitry Andric  bool atomic_compare_exchange_strong_explicit(atomic<T>* obj, T* expc,
3360b57cec5SDimitry Andric                                               T desr,
3370b57cec5SDimitry Andric                                               memory_order s, memory_order f) noexcept;
3380b57cec5SDimitry Andric
3395ffd83dbSDimitry Andrictemplate <class T>
3405ffd83dbSDimitry Andric  void atomic_wait(const volatile atomic<T>* obj, T old) noexcept;
3415ffd83dbSDimitry Andric
3425ffd83dbSDimitry Andrictemplate <class T>
3435ffd83dbSDimitry Andric  void atomic_wait(const atomic<T>* obj, T old) noexcept;
3445ffd83dbSDimitry Andric
3455ffd83dbSDimitry Andrictemplate <class T>
3465ffd83dbSDimitry Andric  void atomic_wait_explicit(const volatile atomic<T>* obj, T old, memory_order m) noexcept;
3475ffd83dbSDimitry Andric
3485ffd83dbSDimitry Andrictemplate <class T>
3495ffd83dbSDimitry Andric  void atomic_wait_explicit(const atomic<T>* obj, T old, memory_order m) noexcept;
3505ffd83dbSDimitry Andric
3515ffd83dbSDimitry Andrictemplate <class T>
3525ffd83dbSDimitry Andric  void atomic_one(volatile atomic<T>* obj) noexcept;
3535ffd83dbSDimitry Andric
3545ffd83dbSDimitry Andrictemplate <class T>
3555ffd83dbSDimitry Andric  void atomic_one(atomic<T>* obj) noexcept;
3565ffd83dbSDimitry Andric
3575ffd83dbSDimitry Andrictemplate <class T>
3585ffd83dbSDimitry Andric  void atomic_all(volatile atomic<T>* obj) noexcept;
3595ffd83dbSDimitry Andric
3605ffd83dbSDimitry Andrictemplate <class T>
3615ffd83dbSDimitry Andric  void atomic_all(atomic<T>* obj) noexcept;
3620b57cec5SDimitry Andric
3630b57cec5SDimitry Andrictemplate <class Integral>
3645ffd83dbSDimitry Andric  Integral atomic_fetch_add(volatile atomic<Integral>* obj, Integral op) noexcept;
3650b57cec5SDimitry Andric
3660b57cec5SDimitry Andrictemplate <class Integral>
3675ffd83dbSDimitry Andric  Integral atomic_fetch_add(atomic<Integral>* obj, Integral op) noexcept;
3685ffd83dbSDimitry Andric
3695ffd83dbSDimitry Andrictemplate <class Integral>
3705ffd83dbSDimitry Andric  Integral atomic_fetch_add_explicit(volatile atomic<Integral>* obj, Integral op,
3710b57cec5SDimitry Andric                              memory_order m) noexcept;
3720b57cec5SDimitry Andrictemplate <class Integral>
3735ffd83dbSDimitry Andric  Integral atomic_fetch_add_explicit(atomic<Integral>* obj, Integral op,
3740b57cec5SDimitry Andric                              memory_order m) noexcept;
3750b57cec5SDimitry Andrictemplate <class Integral>
3765ffd83dbSDimitry Andric  Integral atomic_fetch_sub(volatile atomic<Integral>* obj, Integral op) noexcept;
3770b57cec5SDimitry Andric
3780b57cec5SDimitry Andrictemplate <class Integral>
3795ffd83dbSDimitry Andric  Integral atomic_fetch_sub(atomic<Integral>* obj, Integral op) noexcept;
3800b57cec5SDimitry Andric
3810b57cec5SDimitry Andrictemplate <class Integral>
3825ffd83dbSDimitry Andric  Integral atomic_fetch_sub_explicit(volatile atomic<Integral>* obj, Integral op,
3830b57cec5SDimitry Andric                                     memory_order m) noexcept;
3840b57cec5SDimitry Andric
3850b57cec5SDimitry Andrictemplate <class Integral>
3865ffd83dbSDimitry Andric  Integral atomic_fetch_sub_explicit(atomic<Integral>* obj, Integral op,
3875ffd83dbSDimitry Andric                                     memory_order m) noexcept;
3880b57cec5SDimitry Andric
3890b57cec5SDimitry Andrictemplate <class Integral>
3905ffd83dbSDimitry Andric  Integral atomic_fetch_and(volatile atomic<Integral>* obj, Integral op) noexcept;
3910b57cec5SDimitry Andric
3920b57cec5SDimitry Andrictemplate <class Integral>
3935ffd83dbSDimitry Andric  Integral atomic_fetch_and(atomic<Integral>* obj, Integral op) noexcept;
3940b57cec5SDimitry Andric
3950b57cec5SDimitry Andrictemplate <class Integral>
3965ffd83dbSDimitry Andric  Integral atomic_fetch_and_explicit(volatile atomic<Integral>* obj, Integral op,
3970b57cec5SDimitry Andric                                     memory_order m) noexcept;
3980b57cec5SDimitry Andric
3990b57cec5SDimitry Andrictemplate <class Integral>
4005ffd83dbSDimitry Andric  Integral atomic_fetch_and_explicit(atomic<Integral>* obj, Integral op,
4015ffd83dbSDimitry Andric                                     memory_order m) noexcept;
4020b57cec5SDimitry Andric
4030b57cec5SDimitry Andrictemplate <class Integral>
4045ffd83dbSDimitry Andric  Integral atomic_fetch_or(volatile atomic<Integral>* obj, Integral op) noexcept;
4055ffd83dbSDimitry Andric
4060b57cec5SDimitry Andrictemplate <class Integral>
4075ffd83dbSDimitry Andric  Integral atomic_fetch_or(atomic<Integral>* obj, Integral op) noexcept;
4085ffd83dbSDimitry Andric
4095ffd83dbSDimitry Andrictemplate <class Integral>
4105ffd83dbSDimitry Andric  Integral atomic_fetch_or_explicit(volatile atomic<Integral>* obj, Integral op,
4115ffd83dbSDimitry Andric                             memory_order m) noexcept;
4125ffd83dbSDimitry Andric
4135ffd83dbSDimitry Andrictemplate <class Integral>
4145ffd83dbSDimitry Andric  Integral atomic_fetch_or_explicit(atomic<Integral>* obj, Integral op,
4155ffd83dbSDimitry Andric                             memory_order m) noexcept;
4165ffd83dbSDimitry Andric
4175ffd83dbSDimitry Andrictemplate <class Integral>
4185ffd83dbSDimitry Andric  Integral atomic_fetch_xor(volatile atomic<Integral>* obj, Integral op) noexcept;
4195ffd83dbSDimitry Andric
4205ffd83dbSDimitry Andrictemplate <class Integral>
4215ffd83dbSDimitry Andric  Integral atomic_fetch_xor(atomic<Integral>* obj, Integral op) noexcept;
4225ffd83dbSDimitry Andric
4235ffd83dbSDimitry Andrictemplate <class Integral>
4245ffd83dbSDimitry Andric  Integral atomic_fetch_xor_explicit(volatile atomic<Integral>* obj, Integral op,
4255ffd83dbSDimitry Andric                                     memory_order m) noexcept;
4265ffd83dbSDimitry Andric
4275ffd83dbSDimitry Andrictemplate <class Integral>
4285ffd83dbSDimitry Andric  Integral atomic_fetch_xor_explicit(atomic<Integral>* obj, Integral op,
4290b57cec5SDimitry Andric                                     memory_order m) noexcept;
4300b57cec5SDimitry Andric
4310b57cec5SDimitry Andrictemplate <class T>
4325ffd83dbSDimitry Andric  T* atomic_fetch_add(volatile atomic<T*>* obj, ptrdiff_t op) noexcept;
4330b57cec5SDimitry Andric
4340b57cec5SDimitry Andrictemplate <class T>
4355ffd83dbSDimitry Andric  T* atomic_fetch_add(atomic<T*>* obj, ptrdiff_t op) noexcept;
4360b57cec5SDimitry Andric
4370b57cec5SDimitry Andrictemplate <class T>
4385ffd83dbSDimitry Andric  T* atomic_fetch_add_explicit(volatile atomic<T*>* obj, ptrdiff_t op,
4390b57cec5SDimitry Andric                               memory_order m) noexcept;
4400b57cec5SDimitry Andric
4410b57cec5SDimitry Andrictemplate <class T>
4425ffd83dbSDimitry Andric  T* atomic_fetch_add_explicit(atomic<T*>* obj, ptrdiff_t op, memory_order m) noexcept;
4430b57cec5SDimitry Andric
4440b57cec5SDimitry Andrictemplate <class T>
4455ffd83dbSDimitry Andric  T* atomic_fetch_sub(volatile atomic<T*>* obj, ptrdiff_t op) noexcept;
4460b57cec5SDimitry Andric
4470b57cec5SDimitry Andrictemplate <class T>
4485ffd83dbSDimitry Andric  T* atomic_fetch_sub(atomic<T*>* obj, ptrdiff_t op) noexcept;
4495ffd83dbSDimitry Andric
4505ffd83dbSDimitry Andrictemplate <class T>
4515ffd83dbSDimitry Andric  T* atomic_fetch_sub_explicit(volatile atomic<T*>* obj, ptrdiff_t op,
4520b57cec5SDimitry Andric                               memory_order m) noexcept;
4535ffd83dbSDimitry Andric
4540b57cec5SDimitry Andrictemplate <class T>
4555ffd83dbSDimitry Andric  T* atomic_fetch_sub_explicit(atomic<T*>* obj, ptrdiff_t op, memory_order m) noexcept;
4560b57cec5SDimitry Andric
4570b57cec5SDimitry Andric// Atomics for standard typedef types
4580b57cec5SDimitry Andric
4590b57cec5SDimitry Andrictypedef atomic<bool>               atomic_bool;
4600b57cec5SDimitry Andrictypedef atomic<char>               atomic_char;
4610b57cec5SDimitry Andrictypedef atomic<signed char>        atomic_schar;
4620b57cec5SDimitry Andrictypedef atomic<unsigned char>      atomic_uchar;
4630b57cec5SDimitry Andrictypedef atomic<short>              atomic_short;
4640b57cec5SDimitry Andrictypedef atomic<unsigned short>     atomic_ushort;
4650b57cec5SDimitry Andrictypedef atomic<int>                atomic_int;
4660b57cec5SDimitry Andrictypedef atomic<unsigned int>       atomic_uint;
4670b57cec5SDimitry Andrictypedef atomic<long>               atomic_long;
4680b57cec5SDimitry Andrictypedef atomic<unsigned long>      atomic_ulong;
4690b57cec5SDimitry Andrictypedef atomic<long long>          atomic_llong;
4700b57cec5SDimitry Andrictypedef atomic<unsigned long long> atomic_ullong;
471e8d8bef9SDimitry Andrictypedef atomic<char8_t>            atomic_char8_t; // C++20
4720b57cec5SDimitry Andrictypedef atomic<char16_t>           atomic_char16_t;
4730b57cec5SDimitry Andrictypedef atomic<char32_t>           atomic_char32_t;
4740b57cec5SDimitry Andrictypedef atomic<wchar_t>            atomic_wchar_t;
4750b57cec5SDimitry Andric
4760b57cec5SDimitry Andrictypedef atomic<int_least8_t>   atomic_int_least8_t;
4770b57cec5SDimitry Andrictypedef atomic<uint_least8_t>  atomic_uint_least8_t;
4780b57cec5SDimitry Andrictypedef atomic<int_least16_t>  atomic_int_least16_t;
4790b57cec5SDimitry Andrictypedef atomic<uint_least16_t> atomic_uint_least16_t;
4800b57cec5SDimitry Andrictypedef atomic<int_least32_t>  atomic_int_least32_t;
4810b57cec5SDimitry Andrictypedef atomic<uint_least32_t> atomic_uint_least32_t;
4820b57cec5SDimitry Andrictypedef atomic<int_least64_t>  atomic_int_least64_t;
4830b57cec5SDimitry Andrictypedef atomic<uint_least64_t> atomic_uint_least64_t;
4840b57cec5SDimitry Andric
4850b57cec5SDimitry Andrictypedef atomic<int_fast8_t>   atomic_int_fast8_t;
4860b57cec5SDimitry Andrictypedef atomic<uint_fast8_t>  atomic_uint_fast8_t;
4870b57cec5SDimitry Andrictypedef atomic<int_fast16_t>  atomic_int_fast16_t;
4880b57cec5SDimitry Andrictypedef atomic<uint_fast16_t> atomic_uint_fast16_t;
4890b57cec5SDimitry Andrictypedef atomic<int_fast32_t>  atomic_int_fast32_t;
4900b57cec5SDimitry Andrictypedef atomic<uint_fast32_t> atomic_uint_fast32_t;
4910b57cec5SDimitry Andrictypedef atomic<int_fast64_t>  atomic_int_fast64_t;
4920b57cec5SDimitry Andrictypedef atomic<uint_fast64_t> atomic_uint_fast64_t;
4930b57cec5SDimitry Andric
4940b57cec5SDimitry Andrictypedef atomic<int8_t>   atomic_int8_t;
4950b57cec5SDimitry Andrictypedef atomic<uint8_t>  atomic_uint8_t;
4960b57cec5SDimitry Andrictypedef atomic<int16_t>  atomic_int16_t;
4970b57cec5SDimitry Andrictypedef atomic<uint16_t> atomic_uint16_t;
4980b57cec5SDimitry Andrictypedef atomic<int32_t>  atomic_int32_t;
4990b57cec5SDimitry Andrictypedef atomic<uint32_t> atomic_uint32_t;
5000b57cec5SDimitry Andrictypedef atomic<int64_t>  atomic_int64_t;
5010b57cec5SDimitry Andrictypedef atomic<uint64_t> atomic_uint64_t;
5020b57cec5SDimitry Andric
5030b57cec5SDimitry Andrictypedef atomic<intptr_t>  atomic_intptr_t;
5040b57cec5SDimitry Andrictypedef atomic<uintptr_t> atomic_uintptr_t;
5050b57cec5SDimitry Andrictypedef atomic<size_t>    atomic_size_t;
5060b57cec5SDimitry Andrictypedef atomic<ptrdiff_t> atomic_ptrdiff_t;
5070b57cec5SDimitry Andrictypedef atomic<intmax_t>  atomic_intmax_t;
5080b57cec5SDimitry Andrictypedef atomic<uintmax_t> atomic_uintmax_t;
5090b57cec5SDimitry Andric
5105ffd83dbSDimitry Andric// flag type and operations
5115ffd83dbSDimitry Andric
5125ffd83dbSDimitry Andrictypedef struct atomic_flag
5135ffd83dbSDimitry Andric{
514*fe6060f1SDimitry Andric    atomic_flag() noexcept = default; // until C++20
515*fe6060f1SDimitry Andric    constexpr atomic_flag() noexcept; // since C++20
5165ffd83dbSDimitry Andric    atomic_flag(const atomic_flag&) = delete;
5175ffd83dbSDimitry Andric    atomic_flag& operator=(const atomic_flag&) = delete;
5185ffd83dbSDimitry Andric    atomic_flag& operator=(const atomic_flag&) volatile = delete;
5195ffd83dbSDimitry Andric
5205ffd83dbSDimitry Andric    bool test(memory_order m = memory_order_seq_cst) volatile noexcept;
5215ffd83dbSDimitry Andric    bool test(memory_order m = memory_order_seq_cst) noexcept;
5225ffd83dbSDimitry Andric    bool test_and_set(memory_order m = memory_order_seq_cst) volatile noexcept;
5235ffd83dbSDimitry Andric    bool test_and_set(memory_order m = memory_order_seq_cst) noexcept;
5245ffd83dbSDimitry Andric    void clear(memory_order m = memory_order_seq_cst) volatile noexcept;
5255ffd83dbSDimitry Andric    void clear(memory_order m = memory_order_seq_cst) noexcept;
5265ffd83dbSDimitry Andric
5275ffd83dbSDimitry Andric    void wait(bool, memory_order = memory_order::seq_cst) const volatile noexcept;
5285ffd83dbSDimitry Andric    void wait(bool, memory_order = memory_order::seq_cst) const noexcept;
5295ffd83dbSDimitry Andric    void notify_one() volatile noexcept;
5305ffd83dbSDimitry Andric    void notify_one() noexcept;
5315ffd83dbSDimitry Andric    void notify_all() volatile noexcept;
5325ffd83dbSDimitry Andric    void notify_all() noexcept;
5335ffd83dbSDimitry Andric} atomic_flag;
5345ffd83dbSDimitry Andric
5355ffd83dbSDimitry Andricbool atomic_flag_test(volatile atomic_flag* obj) noexcept;
5365ffd83dbSDimitry Andricbool atomic_flag_test(atomic_flag* obj) noexcept;
5375ffd83dbSDimitry Andricbool atomic_flag_test_explicit(volatile atomic_flag* obj,
5385ffd83dbSDimitry Andric                               memory_order m) noexcept;
5395ffd83dbSDimitry Andricbool atomic_flag_test_explicit(atomic_flag* obj, memory_order m) noexcept;
5405ffd83dbSDimitry Andricbool atomic_flag_test_and_set(volatile atomic_flag* obj) noexcept;
5415ffd83dbSDimitry Andricbool atomic_flag_test_and_set(atomic_flag* obj) noexcept;
5425ffd83dbSDimitry Andricbool atomic_flag_test_and_set_explicit(volatile atomic_flag* obj,
5435ffd83dbSDimitry Andric                                       memory_order m) noexcept;
5445ffd83dbSDimitry Andricbool atomic_flag_test_and_set_explicit(atomic_flag* obj, memory_order m) noexcept;
5455ffd83dbSDimitry Andricvoid atomic_flag_clear(volatile atomic_flag* obj) noexcept;
5465ffd83dbSDimitry Andricvoid atomic_flag_clear(atomic_flag* obj) noexcept;
5475ffd83dbSDimitry Andricvoid atomic_flag_clear_explicit(volatile atomic_flag* obj, memory_order m) noexcept;
5485ffd83dbSDimitry Andricvoid atomic_flag_clear_explicit(atomic_flag* obj, memory_order m) noexcept;
5495ffd83dbSDimitry Andric
5505ffd83dbSDimitry Andricvoid atomic_wait(const volatile atomic_flag* obj, T old) noexcept;
5515ffd83dbSDimitry Andricvoid atomic_wait(const atomic_flag* obj, T old) noexcept;
5525ffd83dbSDimitry Andricvoid atomic_wait_explicit(const volatile atomic_flag* obj, T old, memory_order m) noexcept;
5535ffd83dbSDimitry Andricvoid atomic_wait_explicit(const atomic_flag* obj, T old, memory_order m) noexcept;
5545ffd83dbSDimitry Andricvoid atomic_one(volatile atomic_flag* obj) noexcept;
5555ffd83dbSDimitry Andricvoid atomic_one(atomic_flag* obj) noexcept;
5565ffd83dbSDimitry Andricvoid atomic_all(volatile atomic_flag* obj) noexcept;
5575ffd83dbSDimitry Andricvoid atomic_all(atomic_flag* obj) noexcept;
5585ffd83dbSDimitry Andric
5590b57cec5SDimitry Andric// fences
5600b57cec5SDimitry Andric
5610b57cec5SDimitry Andricvoid atomic_thread_fence(memory_order m) noexcept;
5620b57cec5SDimitry Andricvoid atomic_signal_fence(memory_order m) noexcept;
5630b57cec5SDimitry Andric
5645ffd83dbSDimitry Andric// deprecated
5655ffd83dbSDimitry Andric
5665ffd83dbSDimitry Andrictemplate <class T>
5675ffd83dbSDimitry Andric  void atomic_init(volatile atomic<T>* obj, typename atomic<T>::value_type desr) noexcept;
5685ffd83dbSDimitry Andric
5695ffd83dbSDimitry Andrictemplate <class T>
5705ffd83dbSDimitry Andric  void atomic_init(atomic<T>* obj, typename atomic<T>::value_type desr) noexcept;
5715ffd83dbSDimitry Andric
5725ffd83dbSDimitry Andric#define ATOMIC_VAR_INIT(value) see below
5735ffd83dbSDimitry Andric
5745ffd83dbSDimitry Andric#define ATOMIC_FLAG_INIT see below
5755ffd83dbSDimitry Andric
5760b57cec5SDimitry Andric}  // std
5770b57cec5SDimitry Andric
5780b57cec5SDimitry Andric*/
5790b57cec5SDimitry Andric
580e8d8bef9SDimitry Andric#include <__availability>
581*fe6060f1SDimitry Andric#include <__config>
5825ffd83dbSDimitry Andric#include <__threading_support>
5830b57cec5SDimitry Andric#include <cstddef>
5840b57cec5SDimitry Andric#include <cstdint>
5855ffd83dbSDimitry Andric#include <cstring>
5860b57cec5SDimitry Andric#include <type_traits>
5870b57cec5SDimitry Andric#include <version>
5880b57cec5SDimitry Andric
5890b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
5900b57cec5SDimitry Andric#pragma GCC system_header
5910b57cec5SDimitry Andric#endif
5920b57cec5SDimitry Andric
5930b57cec5SDimitry Andric#ifdef _LIBCPP_HAS_NO_THREADS
5940b57cec5SDimitry Andric# error <atomic> is not supported on this single threaded system
5950b57cec5SDimitry Andric#endif
5960b57cec5SDimitry Andric#ifdef _LIBCPP_HAS_NO_ATOMIC_HEADER
5970b57cec5SDimitry Andric# error <atomic> is not implemented
5980b57cec5SDimitry Andric#endif
5990b57cec5SDimitry Andric#ifdef kill_dependency
6000b57cec5SDimitry Andric# error C++ standard library is incompatible with <stdatomic.h>
6010b57cec5SDimitry Andric#endif
6020b57cec5SDimitry Andric
6030b57cec5SDimitry Andric#define _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) \
6040b57cec5SDimitry Andric  _LIBCPP_DIAGNOSE_WARNING(__m == memory_order_consume || \
6050b57cec5SDimitry Andric                           __m == memory_order_acquire || \
6060b57cec5SDimitry Andric                           __m == memory_order_acq_rel,   \
6070b57cec5SDimitry Andric                        "memory order argument to atomic operation is invalid")
6080b57cec5SDimitry Andric
6090b57cec5SDimitry Andric#define _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) \
6100b57cec5SDimitry Andric  _LIBCPP_DIAGNOSE_WARNING(__m == memory_order_release || \
6110b57cec5SDimitry Andric                           __m == memory_order_acq_rel,   \
6120b57cec5SDimitry Andric                        "memory order argument to atomic operation is invalid")
6130b57cec5SDimitry Andric
6140b57cec5SDimitry Andric#define _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__m, __f) \
6150b57cec5SDimitry Andric  _LIBCPP_DIAGNOSE_WARNING(__f == memory_order_release || \
6160b57cec5SDimitry Andric                           __f == memory_order_acq_rel,   \
6170b57cec5SDimitry Andric                        "memory order argument to atomic operation is invalid")
6180b57cec5SDimitry Andric
6190b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD
6200b57cec5SDimitry Andric
6210b57cec5SDimitry Andric// Figure out what the underlying type for `memory_order` would be if it were
6220b57cec5SDimitry Andric// declared as an unscoped enum (accounting for -fshort-enums). Use this result
6230b57cec5SDimitry Andric// to pin the underlying type in C++20.
6240b57cec5SDimitry Andricenum __legacy_memory_order {
6250b57cec5SDimitry Andric    __mo_relaxed,
6260b57cec5SDimitry Andric    __mo_consume,
6270b57cec5SDimitry Andric    __mo_acquire,
6280b57cec5SDimitry Andric    __mo_release,
6290b57cec5SDimitry Andric    __mo_acq_rel,
6300b57cec5SDimitry Andric    __mo_seq_cst
6310b57cec5SDimitry Andric};
6320b57cec5SDimitry Andric
6330b57cec5SDimitry Andrictypedef underlying_type<__legacy_memory_order>::type __memory_order_underlying_t;
6340b57cec5SDimitry Andric
6350b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 17
6360b57cec5SDimitry Andric
6370b57cec5SDimitry Andricenum class memory_order : __memory_order_underlying_t {
6380b57cec5SDimitry Andric  relaxed = __mo_relaxed,
6390b57cec5SDimitry Andric  consume = __mo_consume,
6400b57cec5SDimitry Andric  acquire = __mo_acquire,
6410b57cec5SDimitry Andric  release = __mo_release,
6420b57cec5SDimitry Andric  acq_rel = __mo_acq_rel,
6430b57cec5SDimitry Andric  seq_cst = __mo_seq_cst
6440b57cec5SDimitry Andric};
6450b57cec5SDimitry Andric
6460b57cec5SDimitry Andricinline constexpr auto memory_order_relaxed = memory_order::relaxed;
6470b57cec5SDimitry Andricinline constexpr auto memory_order_consume = memory_order::consume;
6480b57cec5SDimitry Andricinline constexpr auto memory_order_acquire = memory_order::acquire;
6490b57cec5SDimitry Andricinline constexpr auto memory_order_release = memory_order::release;
6500b57cec5SDimitry Andricinline constexpr auto memory_order_acq_rel = memory_order::acq_rel;
6510b57cec5SDimitry Andricinline constexpr auto memory_order_seq_cst = memory_order::seq_cst;
6520b57cec5SDimitry Andric
6530b57cec5SDimitry Andric#else
6540b57cec5SDimitry Andric
6550b57cec5SDimitry Andrictypedef enum memory_order {
6560b57cec5SDimitry Andric  memory_order_relaxed = __mo_relaxed,
6570b57cec5SDimitry Andric  memory_order_consume = __mo_consume,
6580b57cec5SDimitry Andric  memory_order_acquire = __mo_acquire,
6590b57cec5SDimitry Andric  memory_order_release = __mo_release,
6600b57cec5SDimitry Andric  memory_order_acq_rel = __mo_acq_rel,
6610b57cec5SDimitry Andric  memory_order_seq_cst = __mo_seq_cst,
6620b57cec5SDimitry Andric} memory_order;
6630b57cec5SDimitry Andric
6640b57cec5SDimitry Andric#endif // _LIBCPP_STD_VER > 17
6650b57cec5SDimitry Andric
6665ffd83dbSDimitry Andrictemplate <typename _Tp> _LIBCPP_INLINE_VISIBILITY
6675ffd83dbSDimitry Andricbool __cxx_nonatomic_compare_equal(_Tp const& __lhs, _Tp const& __rhs) {
668e8d8bef9SDimitry Andric    return _VSTD::memcmp(&__lhs, &__rhs, sizeof(_Tp)) == 0;
6695ffd83dbSDimitry Andric}
6705ffd83dbSDimitry Andric
6710b57cec5SDimitry Andricstatic_assert((is_same<underlying_type<memory_order>::type, __memory_order_underlying_t>::value),
6720b57cec5SDimitry Andric  "unexpected underlying type for std::memory_order");
6730b57cec5SDimitry Andric
6740b57cec5SDimitry Andric#if defined(_LIBCPP_HAS_GCC_ATOMIC_IMP) || \
6750b57cec5SDimitry Andric    defined(_LIBCPP_ATOMIC_ONLY_USE_BUILTINS)
6760b57cec5SDimitry Andric
6770b57cec5SDimitry Andric// [atomics.types.generic]p1 guarantees _Tp is trivially copyable. Because
6780b57cec5SDimitry Andric// the default operator= in an object is not volatile, a byte-by-byte copy
6790b57cec5SDimitry Andric// is required.
6800b57cec5SDimitry Andrictemplate <typename _Tp, typename _Tv> _LIBCPP_INLINE_VISIBILITY
6810b57cec5SDimitry Andrictypename enable_if<is_assignable<_Tp&, _Tv>::value>::type
6820b57cec5SDimitry Andric__cxx_atomic_assign_volatile(_Tp& __a_value, _Tv const& __val) {
6830b57cec5SDimitry Andric  __a_value = __val;
6840b57cec5SDimitry Andric}
6850b57cec5SDimitry Andrictemplate <typename _Tp, typename _Tv> _LIBCPP_INLINE_VISIBILITY
6860b57cec5SDimitry Andrictypename enable_if<is_assignable<_Tp&, _Tv>::value>::type
6870b57cec5SDimitry Andric__cxx_atomic_assign_volatile(_Tp volatile& __a_value, _Tv volatile const& __val) {
6880b57cec5SDimitry Andric  volatile char* __to = reinterpret_cast<volatile char*>(&__a_value);
6890b57cec5SDimitry Andric  volatile char* __end = __to + sizeof(_Tp);
6900b57cec5SDimitry Andric  volatile const char* __from = reinterpret_cast<volatile const char*>(&__val);
6910b57cec5SDimitry Andric  while (__to != __end)
6920b57cec5SDimitry Andric    *__to++ = *__from++;
6930b57cec5SDimitry Andric}
6940b57cec5SDimitry Andric
6950b57cec5SDimitry Andric#endif
6960b57cec5SDimitry Andric
6970b57cec5SDimitry Andric#if defined(_LIBCPP_HAS_GCC_ATOMIC_IMP)
6980b57cec5SDimitry Andric
6990b57cec5SDimitry Andrictemplate <typename _Tp>
7000b57cec5SDimitry Andricstruct __cxx_atomic_base_impl {
7010b57cec5SDimitry Andric
7020b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
7030b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
7040b57cec5SDimitry Andric    __cxx_atomic_base_impl() _NOEXCEPT = default;
7050b57cec5SDimitry Andric#else
7060b57cec5SDimitry Andric    __cxx_atomic_base_impl() _NOEXCEPT : __a_value() {}
7070b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG
7080b57cec5SDimitry Andric  _LIBCPP_CONSTEXPR explicit __cxx_atomic_base_impl(_Tp value) _NOEXCEPT
7090b57cec5SDimitry Andric    : __a_value(value) {}
7100b57cec5SDimitry Andric  _Tp __a_value;
7110b57cec5SDimitry Andric};
7120b57cec5SDimitry Andric
7130b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY inline _LIBCPP_CONSTEXPR int __to_gcc_order(memory_order __order) {
7140b57cec5SDimitry Andric  // Avoid switch statement to make this a constexpr.
7150b57cec5SDimitry Andric  return __order == memory_order_relaxed ? __ATOMIC_RELAXED:
7160b57cec5SDimitry Andric         (__order == memory_order_acquire ? __ATOMIC_ACQUIRE:
7170b57cec5SDimitry Andric          (__order == memory_order_release ? __ATOMIC_RELEASE:
7180b57cec5SDimitry Andric           (__order == memory_order_seq_cst ? __ATOMIC_SEQ_CST:
7190b57cec5SDimitry Andric            (__order == memory_order_acq_rel ? __ATOMIC_ACQ_REL:
7200b57cec5SDimitry Andric              __ATOMIC_CONSUME))));
7210b57cec5SDimitry Andric}
7220b57cec5SDimitry Andric
7230b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY inline _LIBCPP_CONSTEXPR int __to_gcc_failure_order(memory_order __order) {
7240b57cec5SDimitry Andric  // Avoid switch statement to make this a constexpr.
7250b57cec5SDimitry Andric  return __order == memory_order_relaxed ? __ATOMIC_RELAXED:
7260b57cec5SDimitry Andric         (__order == memory_order_acquire ? __ATOMIC_ACQUIRE:
7270b57cec5SDimitry Andric          (__order == memory_order_release ? __ATOMIC_RELAXED:
7280b57cec5SDimitry Andric           (__order == memory_order_seq_cst ? __ATOMIC_SEQ_CST:
7290b57cec5SDimitry Andric            (__order == memory_order_acq_rel ? __ATOMIC_ACQUIRE:
7300b57cec5SDimitry Andric              __ATOMIC_CONSUME))));
7310b57cec5SDimitry Andric}
7320b57cec5SDimitry Andric
7330b57cec5SDimitry Andrictemplate <typename _Tp>
7340b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
7350b57cec5SDimitry Andricvoid __cxx_atomic_init(volatile __cxx_atomic_base_impl<_Tp>* __a,  _Tp __val) {
7360b57cec5SDimitry Andric  __cxx_atomic_assign_volatile(__a->__a_value, __val);
7370b57cec5SDimitry Andric}
7380b57cec5SDimitry Andric
7390b57cec5SDimitry Andrictemplate <typename _Tp>
7400b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
7410b57cec5SDimitry Andricvoid __cxx_atomic_init(__cxx_atomic_base_impl<_Tp>* __a,  _Tp __val) {
7420b57cec5SDimitry Andric  __a->__a_value = __val;
7430b57cec5SDimitry Andric}
7440b57cec5SDimitry Andric
7450b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY inline
7460b57cec5SDimitry Andricvoid __cxx_atomic_thread_fence(memory_order __order) {
7470b57cec5SDimitry Andric  __atomic_thread_fence(__to_gcc_order(__order));
7480b57cec5SDimitry Andric}
7490b57cec5SDimitry Andric
7500b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY inline
7510b57cec5SDimitry Andricvoid __cxx_atomic_signal_fence(memory_order __order) {
7520b57cec5SDimitry Andric  __atomic_signal_fence(__to_gcc_order(__order));
7530b57cec5SDimitry Andric}
7540b57cec5SDimitry Andric
7550b57cec5SDimitry Andrictemplate <typename _Tp>
7560b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
7570b57cec5SDimitry Andricvoid __cxx_atomic_store(volatile __cxx_atomic_base_impl<_Tp>* __a,  _Tp __val,
7580b57cec5SDimitry Andric                        memory_order __order) {
7590b57cec5SDimitry Andric  __atomic_store(&__a->__a_value, &__val,
7600b57cec5SDimitry Andric                 __to_gcc_order(__order));
7610b57cec5SDimitry Andric}
7620b57cec5SDimitry Andric
7630b57cec5SDimitry Andrictemplate <typename _Tp>
7640b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
7650b57cec5SDimitry Andricvoid __cxx_atomic_store(__cxx_atomic_base_impl<_Tp>* __a,  _Tp __val,
7660b57cec5SDimitry Andric                        memory_order __order) {
7670b57cec5SDimitry Andric  __atomic_store(&__a->__a_value, &__val,
7680b57cec5SDimitry Andric                 __to_gcc_order(__order));
7690b57cec5SDimitry Andric}
7700b57cec5SDimitry Andric
7710b57cec5SDimitry Andrictemplate <typename _Tp>
7720b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
7730b57cec5SDimitry Andric_Tp __cxx_atomic_load(const volatile __cxx_atomic_base_impl<_Tp>* __a,
7740b57cec5SDimitry Andric                      memory_order __order) {
7750b57cec5SDimitry Andric  _Tp __ret;
7760b57cec5SDimitry Andric  __atomic_load(&__a->__a_value, &__ret,
7770b57cec5SDimitry Andric                __to_gcc_order(__order));
7780b57cec5SDimitry Andric  return __ret;
7790b57cec5SDimitry Andric}
7800b57cec5SDimitry Andric
7810b57cec5SDimitry Andrictemplate <typename _Tp>
7820b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
7830b57cec5SDimitry Andric_Tp __cxx_atomic_load(const __cxx_atomic_base_impl<_Tp>* __a, memory_order __order) {
7840b57cec5SDimitry Andric  _Tp __ret;
7850b57cec5SDimitry Andric  __atomic_load(&__a->__a_value, &__ret,
7860b57cec5SDimitry Andric                __to_gcc_order(__order));
7870b57cec5SDimitry Andric  return __ret;
7880b57cec5SDimitry Andric}
7890b57cec5SDimitry Andric
7900b57cec5SDimitry Andrictemplate <typename _Tp>
7910b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
7920b57cec5SDimitry Andric_Tp __cxx_atomic_exchange(volatile __cxx_atomic_base_impl<_Tp>* __a,
7930b57cec5SDimitry Andric                          _Tp __value, memory_order __order) {
7940b57cec5SDimitry Andric  _Tp __ret;
7950b57cec5SDimitry Andric  __atomic_exchange(&__a->__a_value, &__value, &__ret,
7960b57cec5SDimitry Andric                    __to_gcc_order(__order));
7970b57cec5SDimitry Andric  return __ret;
7980b57cec5SDimitry Andric}
7990b57cec5SDimitry Andric
8000b57cec5SDimitry Andrictemplate <typename _Tp>
8010b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
8020b57cec5SDimitry Andric_Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp>* __a, _Tp __value,
8030b57cec5SDimitry Andric                          memory_order __order) {
8040b57cec5SDimitry Andric  _Tp __ret;
8050b57cec5SDimitry Andric  __atomic_exchange(&__a->__a_value, &__value, &__ret,
8060b57cec5SDimitry Andric                    __to_gcc_order(__order));
8070b57cec5SDimitry Andric  return __ret;
8080b57cec5SDimitry Andric}
8090b57cec5SDimitry Andric
8100b57cec5SDimitry Andrictemplate <typename _Tp>
8110b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
8120b57cec5SDimitry Andricbool __cxx_atomic_compare_exchange_strong(
8130b57cec5SDimitry Andric    volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value,
8140b57cec5SDimitry Andric    memory_order __success, memory_order __failure) {
8150b57cec5SDimitry Andric  return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
8160b57cec5SDimitry Andric                                   false,
8170b57cec5SDimitry Andric                                   __to_gcc_order(__success),
8180b57cec5SDimitry Andric                                   __to_gcc_failure_order(__failure));
8190b57cec5SDimitry Andric}
8200b57cec5SDimitry Andric
8210b57cec5SDimitry Andrictemplate <typename _Tp>
8220b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
8230b57cec5SDimitry Andricbool __cxx_atomic_compare_exchange_strong(
8240b57cec5SDimitry Andric    __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success,
8250b57cec5SDimitry Andric    memory_order __failure) {
8260b57cec5SDimitry Andric  return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
8270b57cec5SDimitry Andric                                   false,
8280b57cec5SDimitry Andric                                   __to_gcc_order(__success),
8290b57cec5SDimitry Andric                                   __to_gcc_failure_order(__failure));
8300b57cec5SDimitry Andric}
8310b57cec5SDimitry Andric
8320b57cec5SDimitry Andrictemplate <typename _Tp>
8330b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
8340b57cec5SDimitry Andricbool __cxx_atomic_compare_exchange_weak(
8350b57cec5SDimitry Andric    volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value,
8360b57cec5SDimitry Andric    memory_order __success, memory_order __failure) {
8370b57cec5SDimitry Andric  return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
8380b57cec5SDimitry Andric                                   true,
8390b57cec5SDimitry Andric                                   __to_gcc_order(__success),
8400b57cec5SDimitry Andric                                   __to_gcc_failure_order(__failure));
8410b57cec5SDimitry Andric}
8420b57cec5SDimitry Andric
8430b57cec5SDimitry Andrictemplate <typename _Tp>
8440b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
8450b57cec5SDimitry Andricbool __cxx_atomic_compare_exchange_weak(
8460b57cec5SDimitry Andric    __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success,
8470b57cec5SDimitry Andric    memory_order __failure) {
8480b57cec5SDimitry Andric  return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
8490b57cec5SDimitry Andric                                   true,
8500b57cec5SDimitry Andric                                   __to_gcc_order(__success),
8510b57cec5SDimitry Andric                                   __to_gcc_failure_order(__failure));
8520b57cec5SDimitry Andric}
8530b57cec5SDimitry Andric
8540b57cec5SDimitry Andrictemplate <typename _Tp>
8550b57cec5SDimitry Andricstruct __skip_amt { enum {value = 1}; };
8560b57cec5SDimitry Andric
8570b57cec5SDimitry Andrictemplate <typename _Tp>
8580b57cec5SDimitry Andricstruct __skip_amt<_Tp*> { enum {value = sizeof(_Tp)}; };
8590b57cec5SDimitry Andric
8600b57cec5SDimitry Andric// FIXME: Haven't figured out what the spec says about using arrays with
8610b57cec5SDimitry Andric// atomic_fetch_add. Force a failure rather than creating bad behavior.
8620b57cec5SDimitry Andrictemplate <typename _Tp>
8630b57cec5SDimitry Andricstruct __skip_amt<_Tp[]> { };
8640b57cec5SDimitry Andrictemplate <typename _Tp, int n>
8650b57cec5SDimitry Andricstruct __skip_amt<_Tp[n]> { };
8660b57cec5SDimitry Andric
8670b57cec5SDimitry Andrictemplate <typename _Tp, typename _Td>
8680b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
8690b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_add(volatile __cxx_atomic_base_impl<_Tp>* __a,
8700b57cec5SDimitry Andric                           _Td __delta, memory_order __order) {
8710b57cec5SDimitry Andric  return __atomic_fetch_add(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
8720b57cec5SDimitry Andric                            __to_gcc_order(__order));
8730b57cec5SDimitry Andric}
8740b57cec5SDimitry Andric
8750b57cec5SDimitry Andrictemplate <typename _Tp, typename _Td>
8760b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
8770b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp>* __a, _Td __delta,
8780b57cec5SDimitry Andric                           memory_order __order) {
8790b57cec5SDimitry Andric  return __atomic_fetch_add(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
8800b57cec5SDimitry Andric                            __to_gcc_order(__order));
8810b57cec5SDimitry Andric}
8820b57cec5SDimitry Andric
8830b57cec5SDimitry Andrictemplate <typename _Tp, typename _Td>
8840b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
8850b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_sub(volatile __cxx_atomic_base_impl<_Tp>* __a,
8860b57cec5SDimitry Andric                           _Td __delta, memory_order __order) {
8870b57cec5SDimitry Andric  return __atomic_fetch_sub(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
8880b57cec5SDimitry Andric                            __to_gcc_order(__order));
8890b57cec5SDimitry Andric}
8900b57cec5SDimitry Andric
8910b57cec5SDimitry Andrictemplate <typename _Tp, typename _Td>
8920b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
8930b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp>* __a, _Td __delta,
8940b57cec5SDimitry Andric                           memory_order __order) {
8950b57cec5SDimitry Andric  return __atomic_fetch_sub(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
8960b57cec5SDimitry Andric                            __to_gcc_order(__order));
8970b57cec5SDimitry Andric}
8980b57cec5SDimitry Andric
8990b57cec5SDimitry Andrictemplate <typename _Tp>
9000b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
9010b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_and(volatile __cxx_atomic_base_impl<_Tp>* __a,
9020b57cec5SDimitry Andric                           _Tp __pattern, memory_order __order) {
9030b57cec5SDimitry Andric  return __atomic_fetch_and(&__a->__a_value, __pattern,
9040b57cec5SDimitry Andric                            __to_gcc_order(__order));
9050b57cec5SDimitry Andric}
9060b57cec5SDimitry Andric
9070b57cec5SDimitry Andrictemplate <typename _Tp>
9080b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
9090b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp>* __a,
9100b57cec5SDimitry Andric                           _Tp __pattern, memory_order __order) {
9110b57cec5SDimitry Andric  return __atomic_fetch_and(&__a->__a_value, __pattern,
9120b57cec5SDimitry Andric                            __to_gcc_order(__order));
9130b57cec5SDimitry Andric}
9140b57cec5SDimitry Andric
9150b57cec5SDimitry Andrictemplate <typename _Tp>
9160b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
9170b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_or(volatile __cxx_atomic_base_impl<_Tp>* __a,
9180b57cec5SDimitry Andric                          _Tp __pattern, memory_order __order) {
9190b57cec5SDimitry Andric  return __atomic_fetch_or(&__a->__a_value, __pattern,
9200b57cec5SDimitry Andric                           __to_gcc_order(__order));
9210b57cec5SDimitry Andric}
9220b57cec5SDimitry Andric
9230b57cec5SDimitry Andrictemplate <typename _Tp>
9240b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
9250b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern,
9260b57cec5SDimitry Andric                          memory_order __order) {
9270b57cec5SDimitry Andric  return __atomic_fetch_or(&__a->__a_value, __pattern,
9280b57cec5SDimitry Andric                           __to_gcc_order(__order));
9290b57cec5SDimitry Andric}
9300b57cec5SDimitry Andric
9310b57cec5SDimitry Andrictemplate <typename _Tp>
9320b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
9330b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_xor(volatile __cxx_atomic_base_impl<_Tp>* __a,
9340b57cec5SDimitry Andric                           _Tp __pattern, memory_order __order) {
9350b57cec5SDimitry Andric  return __atomic_fetch_xor(&__a->__a_value, __pattern,
9360b57cec5SDimitry Andric                            __to_gcc_order(__order));
9370b57cec5SDimitry Andric}
9380b57cec5SDimitry Andric
9390b57cec5SDimitry Andrictemplate <typename _Tp>
9400b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
9410b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern,
9420b57cec5SDimitry Andric                           memory_order __order) {
9430b57cec5SDimitry Andric  return __atomic_fetch_xor(&__a->__a_value, __pattern,
9440b57cec5SDimitry Andric                            __to_gcc_order(__order));
9450b57cec5SDimitry Andric}
9460b57cec5SDimitry Andric
9470b57cec5SDimitry Andric#define __cxx_atomic_is_lock_free(__s) __atomic_is_lock_free(__s, 0)
9480b57cec5SDimitry Andric
9490b57cec5SDimitry Andric#elif defined(_LIBCPP_HAS_C_ATOMIC_IMP)
9500b57cec5SDimitry Andric
9510b57cec5SDimitry Andrictemplate <typename _Tp>
9520b57cec5SDimitry Andricstruct __cxx_atomic_base_impl {
9530b57cec5SDimitry Andric
9540b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
9550b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
9560b57cec5SDimitry Andric    __cxx_atomic_base_impl() _NOEXCEPT = default;
9570b57cec5SDimitry Andric#else
9580b57cec5SDimitry Andric    __cxx_atomic_base_impl() _NOEXCEPT : __a_value() {}
9590b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG
9600b57cec5SDimitry Andric  _LIBCPP_CONSTEXPR explicit __cxx_atomic_base_impl(_Tp value) _NOEXCEPT
9610b57cec5SDimitry Andric    : __a_value(value) {}
962e40139ffSDimitry Andric  _LIBCPP_DISABLE_EXTENSION_WARNING _Atomic(_Tp) __a_value;
9630b57cec5SDimitry Andric};
9640b57cec5SDimitry Andric
9650b57cec5SDimitry Andric#define __cxx_atomic_is_lock_free(__s) __c11_atomic_is_lock_free(__s)
9660b57cec5SDimitry Andric
9670b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY inline
9680b57cec5SDimitry Andricvoid __cxx_atomic_thread_fence(memory_order __order) _NOEXCEPT {
9690b57cec5SDimitry Andric    __c11_atomic_thread_fence(static_cast<__memory_order_underlying_t>(__order));
9700b57cec5SDimitry Andric}
9710b57cec5SDimitry Andric
9720b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY inline
9730b57cec5SDimitry Andricvoid __cxx_atomic_signal_fence(memory_order __order) _NOEXCEPT {
9740b57cec5SDimitry Andric    __c11_atomic_signal_fence(static_cast<__memory_order_underlying_t>(__order));
9750b57cec5SDimitry Andric}
9760b57cec5SDimitry Andric
9770b57cec5SDimitry Andrictemplate<class _Tp>
9780b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
9790b57cec5SDimitry Andricvoid __cxx_atomic_init(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __val) _NOEXCEPT {
9800b57cec5SDimitry Andric    __c11_atomic_init(&__a->__a_value, __val);
9810b57cec5SDimitry Andric}
9820b57cec5SDimitry Andrictemplate<class _Tp>
9830b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
9840b57cec5SDimitry Andricvoid __cxx_atomic_init(__cxx_atomic_base_impl<_Tp> * __a, _Tp __val) _NOEXCEPT {
9850b57cec5SDimitry Andric    __c11_atomic_init(&__a->__a_value, __val);
9860b57cec5SDimitry Andric}
9870b57cec5SDimitry Andric
9880b57cec5SDimitry Andrictemplate<class _Tp>
9890b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
9900b57cec5SDimitry Andricvoid __cxx_atomic_store(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __val, memory_order __order) _NOEXCEPT {
9910b57cec5SDimitry Andric    __c11_atomic_store(&__a->__a_value, __val, static_cast<__memory_order_underlying_t>(__order));
9920b57cec5SDimitry Andric}
9930b57cec5SDimitry Andrictemplate<class _Tp>
9940b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
9950b57cec5SDimitry Andricvoid __cxx_atomic_store(__cxx_atomic_base_impl<_Tp> * __a, _Tp __val, memory_order __order) _NOEXCEPT {
9960b57cec5SDimitry Andric    __c11_atomic_store(&__a->__a_value, __val, static_cast<__memory_order_underlying_t>(__order));
9970b57cec5SDimitry Andric}
9980b57cec5SDimitry Andric
9990b57cec5SDimitry Andrictemplate<class _Tp>
10000b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
10010b57cec5SDimitry Andric_Tp __cxx_atomic_load(__cxx_atomic_base_impl<_Tp> const volatile* __a, memory_order __order) _NOEXCEPT {
10020b57cec5SDimitry Andric    using __ptr_type = typename remove_const<decltype(__a->__a_value)>::type*;
10030b57cec5SDimitry Andric    return __c11_atomic_load(const_cast<__ptr_type>(&__a->__a_value), static_cast<__memory_order_underlying_t>(__order));
10040b57cec5SDimitry Andric}
10050b57cec5SDimitry Andrictemplate<class _Tp>
10060b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
10070b57cec5SDimitry Andric_Tp __cxx_atomic_load(__cxx_atomic_base_impl<_Tp> const* __a, memory_order __order) _NOEXCEPT {
10080b57cec5SDimitry Andric    using __ptr_type = typename remove_const<decltype(__a->__a_value)>::type*;
10090b57cec5SDimitry Andric    return __c11_atomic_load(const_cast<__ptr_type>(&__a->__a_value), static_cast<__memory_order_underlying_t>(__order));
10100b57cec5SDimitry Andric}
10110b57cec5SDimitry Andric
10120b57cec5SDimitry Andrictemplate<class _Tp>
10130b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
10140b57cec5SDimitry Andric_Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __value, memory_order __order) _NOEXCEPT {
10150b57cec5SDimitry Andric    return __c11_atomic_exchange(&__a->__a_value, __value, static_cast<__memory_order_underlying_t>(__order));
10160b57cec5SDimitry Andric}
10170b57cec5SDimitry Andrictemplate<class _Tp>
10180b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
10190b57cec5SDimitry Andric_Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp> * __a, _Tp __value, memory_order __order) _NOEXCEPT {
10200b57cec5SDimitry Andric    return __c11_atomic_exchange(&__a->__a_value, __value, static_cast<__memory_order_underlying_t>(__order));
10210b57cec5SDimitry Andric}
10220b57cec5SDimitry Andric
1023*fe6060f1SDimitry Andric_LIBCPP_INLINE_VISIBILITY inline _LIBCPP_CONSTEXPR memory_order __to_failure_order(memory_order __order) {
1024*fe6060f1SDimitry Andric  // Avoid switch statement to make this a constexpr.
1025*fe6060f1SDimitry Andric  return __order == memory_order_release ? memory_order_relaxed:
1026*fe6060f1SDimitry Andric         (__order == memory_order_acq_rel ? memory_order_acquire:
1027*fe6060f1SDimitry Andric             __order);
1028*fe6060f1SDimitry Andric}
1029*fe6060f1SDimitry Andric
10300b57cec5SDimitry Andrictemplate<class _Tp>
10310b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
10320b57cec5SDimitry Andricbool __cxx_atomic_compare_exchange_strong(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT {
1033*fe6060f1SDimitry Andric    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)));
10340b57cec5SDimitry Andric}
10350b57cec5SDimitry Andrictemplate<class _Tp>
10360b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
10370b57cec5SDimitry Andricbool __cxx_atomic_compare_exchange_strong(__cxx_atomic_base_impl<_Tp> * __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT {
1038*fe6060f1SDimitry Andric    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)));
10390b57cec5SDimitry Andric}
10400b57cec5SDimitry Andric
10410b57cec5SDimitry Andrictemplate<class _Tp>
10420b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
10430b57cec5SDimitry Andricbool __cxx_atomic_compare_exchange_weak(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT {
1044*fe6060f1SDimitry Andric    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)));
10450b57cec5SDimitry Andric}
10460b57cec5SDimitry Andrictemplate<class _Tp>
10470b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
10480b57cec5SDimitry Andricbool __cxx_atomic_compare_exchange_weak(__cxx_atomic_base_impl<_Tp> * __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT {
1049*fe6060f1SDimitry Andric    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)));
10500b57cec5SDimitry Andric}
10510b57cec5SDimitry Andric
10520b57cec5SDimitry Andrictemplate<class _Tp>
10530b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
10540b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __delta, memory_order __order) _NOEXCEPT {
10550b57cec5SDimitry Andric    return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
10560b57cec5SDimitry Andric}
10570b57cec5SDimitry Andrictemplate<class _Tp>
10580b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
10590b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp> * __a, _Tp __delta, memory_order __order) _NOEXCEPT {
10600b57cec5SDimitry Andric    return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
10610b57cec5SDimitry Andric}
10620b57cec5SDimitry Andric
10630b57cec5SDimitry Andrictemplate<class _Tp>
10640b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
10650b57cec5SDimitry Andric_Tp* __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp*> volatile* __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT {
10660b57cec5SDimitry Andric    return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
10670b57cec5SDimitry Andric}
10680b57cec5SDimitry Andrictemplate<class _Tp>
10690b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
10700b57cec5SDimitry Andric_Tp* __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp*> * __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT {
10710b57cec5SDimitry Andric    return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
10720b57cec5SDimitry Andric}
10730b57cec5SDimitry Andric
10740b57cec5SDimitry Andrictemplate<class _Tp>
10750b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
10760b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __delta, memory_order __order) _NOEXCEPT {
10770b57cec5SDimitry Andric    return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
10780b57cec5SDimitry Andric}
10790b57cec5SDimitry Andrictemplate<class _Tp>
10800b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
10810b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp> * __a, _Tp __delta, memory_order __order) _NOEXCEPT {
10820b57cec5SDimitry Andric    return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
10830b57cec5SDimitry Andric}
10840b57cec5SDimitry Andrictemplate<class _Tp>
10850b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
10860b57cec5SDimitry Andric_Tp* __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp*> volatile* __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT {
10870b57cec5SDimitry Andric    return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
10880b57cec5SDimitry Andric}
10890b57cec5SDimitry Andrictemplate<class _Tp>
10900b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
10910b57cec5SDimitry Andric_Tp* __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp*> * __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT {
10920b57cec5SDimitry Andric    return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
10930b57cec5SDimitry Andric}
10940b57cec5SDimitry Andric
10950b57cec5SDimitry Andrictemplate<class _Tp>
10960b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
10970b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
10980b57cec5SDimitry Andric    return __c11_atomic_fetch_and(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
10990b57cec5SDimitry Andric}
11000b57cec5SDimitry Andrictemplate<class _Tp>
11010b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
11020b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
11030b57cec5SDimitry Andric    return __c11_atomic_fetch_and(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
11040b57cec5SDimitry Andric}
11050b57cec5SDimitry Andric
11060b57cec5SDimitry Andrictemplate<class _Tp>
11070b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
11080b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
11090b57cec5SDimitry Andric    return __c11_atomic_fetch_or(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
11100b57cec5SDimitry Andric}
11110b57cec5SDimitry Andrictemplate<class _Tp>
11120b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
11130b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
11140b57cec5SDimitry Andric    return __c11_atomic_fetch_or(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
11150b57cec5SDimitry Andric}
11160b57cec5SDimitry Andric
11170b57cec5SDimitry Andrictemplate<class _Tp>
11180b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
11190b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
11200b57cec5SDimitry Andric    return __c11_atomic_fetch_xor(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
11210b57cec5SDimitry Andric}
11220b57cec5SDimitry Andrictemplate<class _Tp>
11230b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
11240b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
11250b57cec5SDimitry Andric    return __c11_atomic_fetch_xor(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
11260b57cec5SDimitry Andric}
11270b57cec5SDimitry Andric
11280b57cec5SDimitry Andric#endif // _LIBCPP_HAS_GCC_ATOMIC_IMP, _LIBCPP_HAS_C_ATOMIC_IMP
11290b57cec5SDimitry Andric
11300b57cec5SDimitry Andrictemplate <class _Tp>
11310b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
11320b57cec5SDimitry Andric_Tp kill_dependency(_Tp __y) _NOEXCEPT
11330b57cec5SDimitry Andric{
11340b57cec5SDimitry Andric    return __y;
11350b57cec5SDimitry Andric}
11360b57cec5SDimitry Andric
11370b57cec5SDimitry Andric#if defined(__CLANG_ATOMIC_BOOL_LOCK_FREE)
11380b57cec5SDimitry Andric# define ATOMIC_BOOL_LOCK_FREE      __CLANG_ATOMIC_BOOL_LOCK_FREE
11390b57cec5SDimitry Andric# define ATOMIC_CHAR_LOCK_FREE      __CLANG_ATOMIC_CHAR_LOCK_FREE
1140*fe6060f1SDimitry Andric#ifndef _LIBCPP_HAS_NO_CHAR8_T
1141e8d8bef9SDimitry Andric# define ATOMIC_CHAR8_T_LOCK_FREE   __CLANG_ATOMIC_CHAR8_T_LOCK_FREE
1142e8d8bef9SDimitry Andric#endif
11430b57cec5SDimitry Andric# define ATOMIC_CHAR16_T_LOCK_FREE  __CLANG_ATOMIC_CHAR16_T_LOCK_FREE
11440b57cec5SDimitry Andric# define ATOMIC_CHAR32_T_LOCK_FREE  __CLANG_ATOMIC_CHAR32_T_LOCK_FREE
11450b57cec5SDimitry Andric# define ATOMIC_WCHAR_T_LOCK_FREE   __CLANG_ATOMIC_WCHAR_T_LOCK_FREE
11460b57cec5SDimitry Andric# define ATOMIC_SHORT_LOCK_FREE     __CLANG_ATOMIC_SHORT_LOCK_FREE
11470b57cec5SDimitry Andric# define ATOMIC_INT_LOCK_FREE       __CLANG_ATOMIC_INT_LOCK_FREE
11480b57cec5SDimitry Andric# define ATOMIC_LONG_LOCK_FREE      __CLANG_ATOMIC_LONG_LOCK_FREE
11490b57cec5SDimitry Andric# define ATOMIC_LLONG_LOCK_FREE     __CLANG_ATOMIC_LLONG_LOCK_FREE
11500b57cec5SDimitry Andric# define ATOMIC_POINTER_LOCK_FREE   __CLANG_ATOMIC_POINTER_LOCK_FREE
11510b57cec5SDimitry Andric#elif defined(__GCC_ATOMIC_BOOL_LOCK_FREE)
11520b57cec5SDimitry Andric# define ATOMIC_BOOL_LOCK_FREE      __GCC_ATOMIC_BOOL_LOCK_FREE
11530b57cec5SDimitry Andric# define ATOMIC_CHAR_LOCK_FREE      __GCC_ATOMIC_CHAR_LOCK_FREE
1154*fe6060f1SDimitry Andric#ifndef _LIBCPP_HAS_NO_CHAR8_T
1155e8d8bef9SDimitry Andric# define ATOMIC_CHAR8_T_LOCK_FREE   __GCC_ATOMIC_CHAR8_T_LOCK_FREE
1156e8d8bef9SDimitry Andric#endif
11570b57cec5SDimitry Andric# define ATOMIC_CHAR16_T_LOCK_FREE  __GCC_ATOMIC_CHAR16_T_LOCK_FREE
11580b57cec5SDimitry Andric# define ATOMIC_CHAR32_T_LOCK_FREE  __GCC_ATOMIC_CHAR32_T_LOCK_FREE
11590b57cec5SDimitry Andric# define ATOMIC_WCHAR_T_LOCK_FREE   __GCC_ATOMIC_WCHAR_T_LOCK_FREE
11600b57cec5SDimitry Andric# define ATOMIC_SHORT_LOCK_FREE     __GCC_ATOMIC_SHORT_LOCK_FREE
11610b57cec5SDimitry Andric# define ATOMIC_INT_LOCK_FREE       __GCC_ATOMIC_INT_LOCK_FREE
11620b57cec5SDimitry Andric# define ATOMIC_LONG_LOCK_FREE      __GCC_ATOMIC_LONG_LOCK_FREE
11630b57cec5SDimitry Andric# define ATOMIC_LLONG_LOCK_FREE     __GCC_ATOMIC_LLONG_LOCK_FREE
11640b57cec5SDimitry Andric# define ATOMIC_POINTER_LOCK_FREE   __GCC_ATOMIC_POINTER_LOCK_FREE
11650b57cec5SDimitry Andric#endif
11660b57cec5SDimitry Andric
11670b57cec5SDimitry Andric#ifdef _LIBCPP_ATOMIC_ONLY_USE_BUILTINS
11680b57cec5SDimitry Andric
11690b57cec5SDimitry Andrictemplate<typename _Tp>
11700b57cec5SDimitry Andricstruct __cxx_atomic_lock_impl {
11710b57cec5SDimitry Andric
11720b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
11730b57cec5SDimitry Andric  __cxx_atomic_lock_impl() _NOEXCEPT
11740b57cec5SDimitry Andric    : __a_value(), __a_lock(0) {}
11750b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR explicit
11760b57cec5SDimitry Andric  __cxx_atomic_lock_impl(_Tp value) _NOEXCEPT
11770b57cec5SDimitry Andric    : __a_value(value), __a_lock(0) {}
11780b57cec5SDimitry Andric
11790b57cec5SDimitry Andric  _Tp __a_value;
11800b57cec5SDimitry Andric  mutable __cxx_atomic_base_impl<_LIBCPP_ATOMIC_FLAG_TYPE> __a_lock;
11810b57cec5SDimitry Andric
11820b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY void __lock() const volatile {
11830b57cec5SDimitry Andric    while(1 == __cxx_atomic_exchange(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(true), memory_order_acquire))
11840b57cec5SDimitry Andric        /*spin*/;
11850b57cec5SDimitry Andric  }
11860b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY void __lock() const {
11870b57cec5SDimitry Andric    while(1 == __cxx_atomic_exchange(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(true), memory_order_acquire))
11880b57cec5SDimitry Andric        /*spin*/;
11890b57cec5SDimitry Andric  }
11900b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY void __unlock() const volatile {
11910b57cec5SDimitry Andric    __cxx_atomic_store(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(false), memory_order_release);
11920b57cec5SDimitry Andric  }
11930b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY void __unlock() const {
11940b57cec5SDimitry Andric    __cxx_atomic_store(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(false), memory_order_release);
11950b57cec5SDimitry Andric  }
11960b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY _Tp __read() const volatile {
11970b57cec5SDimitry Andric    __lock();
11980b57cec5SDimitry Andric    _Tp __old;
11990b57cec5SDimitry Andric    __cxx_atomic_assign_volatile(__old, __a_value);
12000b57cec5SDimitry Andric    __unlock();
12010b57cec5SDimitry Andric    return __old;
12020b57cec5SDimitry Andric  }
12030b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY _Tp __read() const {
12040b57cec5SDimitry Andric    __lock();
12050b57cec5SDimitry Andric    _Tp __old = __a_value;
12060b57cec5SDimitry Andric    __unlock();
12070b57cec5SDimitry Andric    return __old;
12080b57cec5SDimitry Andric  }
12090b57cec5SDimitry Andric};
12100b57cec5SDimitry Andric
12110b57cec5SDimitry Andrictemplate <typename _Tp>
12120b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
12130b57cec5SDimitry Andricvoid __cxx_atomic_init(volatile __cxx_atomic_lock_impl<_Tp>* __a,  _Tp __val) {
12140b57cec5SDimitry Andric  __cxx_atomic_assign_volatile(__a->__a_value, __val);
12150b57cec5SDimitry Andric}
12160b57cec5SDimitry Andrictemplate <typename _Tp>
12170b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
12180b57cec5SDimitry Andricvoid __cxx_atomic_init(__cxx_atomic_lock_impl<_Tp>* __a,  _Tp __val) {
12190b57cec5SDimitry Andric  __a->__a_value = __val;
12200b57cec5SDimitry Andric}
12210b57cec5SDimitry Andric
12220b57cec5SDimitry Andrictemplate <typename _Tp>
12230b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
12240b57cec5SDimitry Andricvoid __cxx_atomic_store(volatile __cxx_atomic_lock_impl<_Tp>* __a,  _Tp __val, memory_order) {
12250b57cec5SDimitry Andric  __a->__lock();
12260b57cec5SDimitry Andric  __cxx_atomic_assign_volatile(__a->__a_value, __val);
12270b57cec5SDimitry Andric  __a->__unlock();
12280b57cec5SDimitry Andric}
12290b57cec5SDimitry Andrictemplate <typename _Tp>
12300b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
12310b57cec5SDimitry Andricvoid __cxx_atomic_store(__cxx_atomic_lock_impl<_Tp>* __a,  _Tp __val, memory_order) {
12320b57cec5SDimitry Andric  __a->__lock();
12330b57cec5SDimitry Andric  __a->__a_value = __val;
12340b57cec5SDimitry Andric  __a->__unlock();
12350b57cec5SDimitry Andric}
12360b57cec5SDimitry Andric
12370b57cec5SDimitry Andrictemplate <typename _Tp>
12380b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
12390b57cec5SDimitry Andric_Tp __cxx_atomic_load(const volatile __cxx_atomic_lock_impl<_Tp>* __a, memory_order) {
12400b57cec5SDimitry Andric  return __a->__read();
12410b57cec5SDimitry Andric}
12420b57cec5SDimitry Andrictemplate <typename _Tp>
12430b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
12440b57cec5SDimitry Andric_Tp __cxx_atomic_load(const __cxx_atomic_lock_impl<_Tp>* __a, memory_order) {
12450b57cec5SDimitry Andric  return __a->__read();
12460b57cec5SDimitry Andric}
12470b57cec5SDimitry Andric
12480b57cec5SDimitry Andrictemplate <typename _Tp>
12490b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
12500b57cec5SDimitry Andric_Tp __cxx_atomic_exchange(volatile __cxx_atomic_lock_impl<_Tp>* __a, _Tp __value, memory_order) {
12510b57cec5SDimitry Andric  __a->__lock();
12520b57cec5SDimitry Andric  _Tp __old;
12530b57cec5SDimitry Andric  __cxx_atomic_assign_volatile(__old, __a->__a_value);
12540b57cec5SDimitry Andric  __cxx_atomic_assign_volatile(__a->__a_value, __value);
12550b57cec5SDimitry Andric  __a->__unlock();
12560b57cec5SDimitry Andric  return __old;
12570b57cec5SDimitry Andric}
12580b57cec5SDimitry Andrictemplate <typename _Tp>
12590b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
12600b57cec5SDimitry Andric_Tp __cxx_atomic_exchange(__cxx_atomic_lock_impl<_Tp>* __a, _Tp __value, memory_order) {
12610b57cec5SDimitry Andric  __a->__lock();
12620b57cec5SDimitry Andric  _Tp __old = __a->__a_value;
12630b57cec5SDimitry Andric  __a->__a_value = __value;
12640b57cec5SDimitry Andric  __a->__unlock();
12650b57cec5SDimitry Andric  return __old;
12660b57cec5SDimitry Andric}
12670b57cec5SDimitry Andric
12680b57cec5SDimitry Andrictemplate <typename _Tp>
12690b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
12700b57cec5SDimitry Andricbool __cxx_atomic_compare_exchange_strong(volatile __cxx_atomic_lock_impl<_Tp>* __a,
12710b57cec5SDimitry Andric                                          _Tp* __expected, _Tp __value, memory_order, memory_order) {
12725ffd83dbSDimitry Andric  _Tp __temp;
1273e8d8bef9SDimitry Andric  __a->__lock();
12745ffd83dbSDimitry Andric  __cxx_atomic_assign_volatile(__temp, __a->__a_value);
1275e8d8bef9SDimitry Andric  bool __ret = (_VSTD::memcmp(&__temp, __expected, sizeof(_Tp)) == 0);
12760b57cec5SDimitry Andric  if(__ret)
12770b57cec5SDimitry Andric    __cxx_atomic_assign_volatile(__a->__a_value, __value);
12780b57cec5SDimitry Andric  else
12790b57cec5SDimitry Andric    __cxx_atomic_assign_volatile(*__expected, __a->__a_value);
12800b57cec5SDimitry Andric  __a->__unlock();
12810b57cec5SDimitry Andric  return __ret;
12820b57cec5SDimitry Andric}
12830b57cec5SDimitry Andrictemplate <typename _Tp>
12840b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
12850b57cec5SDimitry Andricbool __cxx_atomic_compare_exchange_strong(__cxx_atomic_lock_impl<_Tp>* __a,
12860b57cec5SDimitry Andric                                          _Tp* __expected, _Tp __value, memory_order, memory_order) {
12870b57cec5SDimitry Andric  __a->__lock();
1288e8d8bef9SDimitry Andric  bool __ret = (_VSTD::memcmp(&__a->__a_value, __expected, sizeof(_Tp)) == 0);
12890b57cec5SDimitry Andric  if(__ret)
1290e8d8bef9SDimitry Andric    _VSTD::memcpy(&__a->__a_value, &__value, sizeof(_Tp));
12910b57cec5SDimitry Andric  else
1292e8d8bef9SDimitry Andric    _VSTD::memcpy(__expected, &__a->__a_value, sizeof(_Tp));
12930b57cec5SDimitry Andric  __a->__unlock();
12940b57cec5SDimitry Andric  return __ret;
12950b57cec5SDimitry Andric}
12960b57cec5SDimitry Andric
12970b57cec5SDimitry Andrictemplate <typename _Tp>
12980b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
12990b57cec5SDimitry Andricbool __cxx_atomic_compare_exchange_weak(volatile __cxx_atomic_lock_impl<_Tp>* __a,
13000b57cec5SDimitry Andric                                        _Tp* __expected, _Tp __value, memory_order, memory_order) {
13015ffd83dbSDimitry Andric  _Tp __temp;
1302e8d8bef9SDimitry Andric  __a->__lock();
13035ffd83dbSDimitry Andric  __cxx_atomic_assign_volatile(__temp, __a->__a_value);
1304e8d8bef9SDimitry Andric  bool __ret = (_VSTD::memcmp(&__temp, __expected, sizeof(_Tp)) == 0);
13050b57cec5SDimitry Andric  if(__ret)
13060b57cec5SDimitry Andric    __cxx_atomic_assign_volatile(__a->__a_value, __value);
13070b57cec5SDimitry Andric  else
13080b57cec5SDimitry Andric    __cxx_atomic_assign_volatile(*__expected, __a->__a_value);
13090b57cec5SDimitry Andric  __a->__unlock();
13100b57cec5SDimitry Andric  return __ret;
13110b57cec5SDimitry Andric}
13120b57cec5SDimitry Andrictemplate <typename _Tp>
13130b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
13140b57cec5SDimitry Andricbool __cxx_atomic_compare_exchange_weak(__cxx_atomic_lock_impl<_Tp>* __a,
13150b57cec5SDimitry Andric                                        _Tp* __expected, _Tp __value, memory_order, memory_order) {
13160b57cec5SDimitry Andric  __a->__lock();
1317e8d8bef9SDimitry Andric  bool __ret = (_VSTD::memcmp(&__a->__a_value, __expected, sizeof(_Tp)) == 0);
13180b57cec5SDimitry Andric  if(__ret)
1319e8d8bef9SDimitry Andric    _VSTD::memcpy(&__a->__a_value, &__value, sizeof(_Tp));
13200b57cec5SDimitry Andric  else
1321e8d8bef9SDimitry Andric    _VSTD::memcpy(__expected, &__a->__a_value, sizeof(_Tp));
13220b57cec5SDimitry Andric  __a->__unlock();
13230b57cec5SDimitry Andric  return __ret;
13240b57cec5SDimitry Andric}
13250b57cec5SDimitry Andric
13260b57cec5SDimitry Andrictemplate <typename _Tp, typename _Td>
13270b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
13280b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_add(volatile __cxx_atomic_lock_impl<_Tp>* __a,
13290b57cec5SDimitry Andric                           _Td __delta, memory_order) {
13300b57cec5SDimitry Andric  __a->__lock();
13310b57cec5SDimitry Andric  _Tp __old;
13320b57cec5SDimitry Andric  __cxx_atomic_assign_volatile(__old, __a->__a_value);
13330b57cec5SDimitry Andric  __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old + __delta));
13340b57cec5SDimitry Andric  __a->__unlock();
13350b57cec5SDimitry Andric  return __old;
13360b57cec5SDimitry Andric}
13370b57cec5SDimitry Andrictemplate <typename _Tp, typename _Td>
13380b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
13390b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_add(__cxx_atomic_lock_impl<_Tp>* __a,
13400b57cec5SDimitry Andric                           _Td __delta, memory_order) {
13410b57cec5SDimitry Andric  __a->__lock();
13420b57cec5SDimitry Andric  _Tp __old = __a->__a_value;
13430b57cec5SDimitry Andric  __a->__a_value += __delta;
13440b57cec5SDimitry Andric  __a->__unlock();
13450b57cec5SDimitry Andric  return __old;
13460b57cec5SDimitry Andric}
13470b57cec5SDimitry Andric
13480b57cec5SDimitry Andrictemplate <typename _Tp, typename _Td>
13490b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
13500b57cec5SDimitry Andric_Tp* __cxx_atomic_fetch_add(volatile __cxx_atomic_lock_impl<_Tp*>* __a,
13510b57cec5SDimitry Andric                           ptrdiff_t __delta, memory_order) {
13520b57cec5SDimitry Andric  __a->__lock();
13530b57cec5SDimitry Andric  _Tp* __old;
13540b57cec5SDimitry Andric  __cxx_atomic_assign_volatile(__old, __a->__a_value);
13550b57cec5SDimitry Andric  __cxx_atomic_assign_volatile(__a->__a_value, __old + __delta);
13560b57cec5SDimitry Andric  __a->__unlock();
13570b57cec5SDimitry Andric  return __old;
13580b57cec5SDimitry Andric}
13590b57cec5SDimitry Andrictemplate <typename _Tp, typename _Td>
13600b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
13610b57cec5SDimitry Andric_Tp* __cxx_atomic_fetch_add(__cxx_atomic_lock_impl<_Tp*>* __a,
13620b57cec5SDimitry Andric                           ptrdiff_t __delta, memory_order) {
13630b57cec5SDimitry Andric  __a->__lock();
13640b57cec5SDimitry Andric  _Tp* __old = __a->__a_value;
13650b57cec5SDimitry Andric  __a->__a_value += __delta;
13660b57cec5SDimitry Andric  __a->__unlock();
13670b57cec5SDimitry Andric  return __old;
13680b57cec5SDimitry Andric}
13690b57cec5SDimitry Andric
13700b57cec5SDimitry Andrictemplate <typename _Tp, typename _Td>
13710b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
13720b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_sub(volatile __cxx_atomic_lock_impl<_Tp>* __a,
13730b57cec5SDimitry Andric                           _Td __delta, memory_order) {
13740b57cec5SDimitry Andric  __a->__lock();
13750b57cec5SDimitry Andric  _Tp __old;
13760b57cec5SDimitry Andric  __cxx_atomic_assign_volatile(__old, __a->__a_value);
13770b57cec5SDimitry Andric  __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old - __delta));
13780b57cec5SDimitry Andric  __a->__unlock();
13790b57cec5SDimitry Andric  return __old;
13800b57cec5SDimitry Andric}
13810b57cec5SDimitry Andrictemplate <typename _Tp, typename _Td>
13820b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
13830b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_sub(__cxx_atomic_lock_impl<_Tp>* __a,
13840b57cec5SDimitry Andric                           _Td __delta, memory_order) {
13850b57cec5SDimitry Andric  __a->__lock();
13860b57cec5SDimitry Andric  _Tp __old = __a->__a_value;
13870b57cec5SDimitry Andric  __a->__a_value -= __delta;
13880b57cec5SDimitry Andric  __a->__unlock();
13890b57cec5SDimitry Andric  return __old;
13900b57cec5SDimitry Andric}
13910b57cec5SDimitry Andric
13920b57cec5SDimitry Andrictemplate <typename _Tp>
13930b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
13940b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_and(volatile __cxx_atomic_lock_impl<_Tp>* __a,
13950b57cec5SDimitry Andric                           _Tp __pattern, memory_order) {
13960b57cec5SDimitry Andric  __a->__lock();
13970b57cec5SDimitry Andric  _Tp __old;
13980b57cec5SDimitry Andric  __cxx_atomic_assign_volatile(__old, __a->__a_value);
13990b57cec5SDimitry Andric  __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old & __pattern));
14000b57cec5SDimitry Andric  __a->__unlock();
14010b57cec5SDimitry Andric  return __old;
14020b57cec5SDimitry Andric}
14030b57cec5SDimitry Andrictemplate <typename _Tp>
14040b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
14050b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_and(__cxx_atomic_lock_impl<_Tp>* __a,
14060b57cec5SDimitry Andric                           _Tp __pattern, memory_order) {
14070b57cec5SDimitry Andric  __a->__lock();
14080b57cec5SDimitry Andric  _Tp __old = __a->__a_value;
14090b57cec5SDimitry Andric  __a->__a_value &= __pattern;
14100b57cec5SDimitry Andric  __a->__unlock();
14110b57cec5SDimitry Andric  return __old;
14120b57cec5SDimitry Andric}
14130b57cec5SDimitry Andric
14140b57cec5SDimitry Andrictemplate <typename _Tp>
14150b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
14160b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_or(volatile __cxx_atomic_lock_impl<_Tp>* __a,
14170b57cec5SDimitry Andric                          _Tp __pattern, memory_order) {
14180b57cec5SDimitry Andric  __a->__lock();
14190b57cec5SDimitry Andric  _Tp __old;
14200b57cec5SDimitry Andric  __cxx_atomic_assign_volatile(__old, __a->__a_value);
14210b57cec5SDimitry Andric  __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old | __pattern));
14220b57cec5SDimitry Andric  __a->__unlock();
14230b57cec5SDimitry Andric  return __old;
14240b57cec5SDimitry Andric}
14250b57cec5SDimitry Andrictemplate <typename _Tp>
14260b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
14270b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_or(__cxx_atomic_lock_impl<_Tp>* __a,
14280b57cec5SDimitry Andric                          _Tp __pattern, memory_order) {
14290b57cec5SDimitry Andric  __a->__lock();
14300b57cec5SDimitry Andric  _Tp __old = __a->__a_value;
14310b57cec5SDimitry Andric  __a->__a_value |= __pattern;
14320b57cec5SDimitry Andric  __a->__unlock();
14330b57cec5SDimitry Andric  return __old;
14340b57cec5SDimitry Andric}
14350b57cec5SDimitry Andric
14360b57cec5SDimitry Andrictemplate <typename _Tp>
14370b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
14380b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_xor(volatile __cxx_atomic_lock_impl<_Tp>* __a,
14390b57cec5SDimitry Andric                           _Tp __pattern, memory_order) {
14400b57cec5SDimitry Andric  __a->__lock();
14410b57cec5SDimitry Andric  _Tp __old;
14420b57cec5SDimitry Andric  __cxx_atomic_assign_volatile(__old, __a->__a_value);
14430b57cec5SDimitry Andric  __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old ^ __pattern));
14440b57cec5SDimitry Andric  __a->__unlock();
14450b57cec5SDimitry Andric  return __old;
14460b57cec5SDimitry Andric}
14470b57cec5SDimitry Andrictemplate <typename _Tp>
14480b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
14490b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_xor(__cxx_atomic_lock_impl<_Tp>* __a,
14500b57cec5SDimitry Andric                           _Tp __pattern, memory_order) {
14510b57cec5SDimitry Andric  __a->__lock();
14520b57cec5SDimitry Andric  _Tp __old = __a->__a_value;
14530b57cec5SDimitry Andric  __a->__a_value ^= __pattern;
14540b57cec5SDimitry Andric  __a->__unlock();
14550b57cec5SDimitry Andric  return __old;
14560b57cec5SDimitry Andric}
14570b57cec5SDimitry Andric
14580b57cec5SDimitry Andric#ifdef __cpp_lib_atomic_is_always_lock_free
14590b57cec5SDimitry Andric
14600b57cec5SDimitry Andrictemplate<typename _Tp> struct __cxx_is_always_lock_free {
14610b57cec5SDimitry Andric    enum { __value = __atomic_always_lock_free(sizeof(_Tp), 0) }; };
14620b57cec5SDimitry Andric
14630b57cec5SDimitry Andric#else
14640b57cec5SDimitry Andric
14650b57cec5SDimitry Andrictemplate<typename _Tp> struct __cxx_is_always_lock_free { enum { __value = false }; };
14660b57cec5SDimitry Andric// Implementations must match the C ATOMIC_*_LOCK_FREE macro values.
14670b57cec5SDimitry Andrictemplate<> struct __cxx_is_always_lock_free<bool> { enum { __value = 2 == ATOMIC_BOOL_LOCK_FREE }; };
14680b57cec5SDimitry Andrictemplate<> struct __cxx_is_always_lock_free<char> { enum { __value = 2 == ATOMIC_CHAR_LOCK_FREE }; };
14690b57cec5SDimitry Andrictemplate<> struct __cxx_is_always_lock_free<signed char> { enum { __value = 2 == ATOMIC_CHAR_LOCK_FREE }; };
14700b57cec5SDimitry Andrictemplate<> struct __cxx_is_always_lock_free<unsigned char> { enum { __value = 2 == ATOMIC_CHAR_LOCK_FREE }; };
1471*fe6060f1SDimitry Andric#ifndef _LIBCPP_HAS_NO_CHAR8_T
1472e8d8bef9SDimitry Andrictemplate<> struct __cxx_is_always_lock_free<char8_t> { enum { __value = 2 == ATOMIC_CHAR8_T_LOCK_FREE }; };
1473e8d8bef9SDimitry Andric#endif
14740b57cec5SDimitry Andrictemplate<> struct __cxx_is_always_lock_free<char16_t> { enum { __value = 2 == ATOMIC_CHAR16_T_LOCK_FREE }; };
14750b57cec5SDimitry Andrictemplate<> struct __cxx_is_always_lock_free<char32_t> { enum { __value = 2 == ATOMIC_CHAR32_T_LOCK_FREE }; };
14760b57cec5SDimitry Andrictemplate<> struct __cxx_is_always_lock_free<wchar_t> { enum { __value = 2 == ATOMIC_WCHAR_T_LOCK_FREE }; };
14770b57cec5SDimitry Andrictemplate<> struct __cxx_is_always_lock_free<short> { enum { __value = 2 == ATOMIC_SHORT_LOCK_FREE }; };
14780b57cec5SDimitry Andrictemplate<> struct __cxx_is_always_lock_free<unsigned short> { enum { __value = 2 == ATOMIC_SHORT_LOCK_FREE }; };
14790b57cec5SDimitry Andrictemplate<> struct __cxx_is_always_lock_free<int> { enum { __value = 2 == ATOMIC_INT_LOCK_FREE }; };
14800b57cec5SDimitry Andrictemplate<> struct __cxx_is_always_lock_free<unsigned int> { enum { __value = 2 == ATOMIC_INT_LOCK_FREE }; };
14810b57cec5SDimitry Andrictemplate<> struct __cxx_is_always_lock_free<long> { enum { __value = 2 == ATOMIC_LONG_LOCK_FREE }; };
14820b57cec5SDimitry Andrictemplate<> struct __cxx_is_always_lock_free<unsigned long> { enum { __value = 2 == ATOMIC_LONG_LOCK_FREE }; };
14830b57cec5SDimitry Andrictemplate<> struct __cxx_is_always_lock_free<long long> { enum { __value = 2 == ATOMIC_LLONG_LOCK_FREE }; };
14840b57cec5SDimitry Andrictemplate<> struct __cxx_is_always_lock_free<unsigned long long> { enum { __value = 2 == ATOMIC_LLONG_LOCK_FREE }; };
14850b57cec5SDimitry Andrictemplate<typename _Tp> struct __cxx_is_always_lock_free<_Tp*> { enum { __value = 2 == ATOMIC_POINTER_LOCK_FREE }; };
14860b57cec5SDimitry Andrictemplate<> struct __cxx_is_always_lock_free<std::nullptr_t> { enum { __value = 2 == ATOMIC_POINTER_LOCK_FREE }; };
14870b57cec5SDimitry Andric
14880b57cec5SDimitry Andric#endif //__cpp_lib_atomic_is_always_lock_free
14890b57cec5SDimitry Andric
14900b57cec5SDimitry Andrictemplate <typename _Tp,
14910b57cec5SDimitry Andric          typename _Base = typename conditional<__cxx_is_always_lock_free<_Tp>::__value,
14920b57cec5SDimitry Andric                                                __cxx_atomic_base_impl<_Tp>,
14930b57cec5SDimitry Andric                                                __cxx_atomic_lock_impl<_Tp> >::type>
14940b57cec5SDimitry Andric#else
14950b57cec5SDimitry Andrictemplate <typename _Tp,
14960b57cec5SDimitry Andric          typename _Base = __cxx_atomic_base_impl<_Tp> >
14970b57cec5SDimitry Andric#endif //_LIBCPP_ATOMIC_ONLY_USE_BUILTINS
14980b57cec5SDimitry Andricstruct __cxx_atomic_impl : public _Base {
14990b57cec5SDimitry Andric
15000b57cec5SDimitry Andric#if _GNUC_VER >= 501
15010b57cec5SDimitry Andric    static_assert(is_trivially_copyable<_Tp>::value,
15020b57cec5SDimitry Andric      "std::atomic<Tp> requires that 'Tp' be a trivially copyable type");
15030b57cec5SDimitry Andric#endif
15040b57cec5SDimitry Andric
15050b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY __cxx_atomic_impl() _NOEXCEPT _LIBCPP_DEFAULT
15060b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR explicit __cxx_atomic_impl(_Tp value) _NOEXCEPT
15070b57cec5SDimitry Andric    : _Base(value) {}
15080b57cec5SDimitry Andric};
15090b57cec5SDimitry Andric
1510d061adc4SAdrian Chadd#if defined(__linux__) || (defined(__FreeBSD__) && defined(__mips__))
15115ffd83dbSDimitry Andric    using __cxx_contention_t = int32_t;
15125ffd83dbSDimitry Andric#else
15135ffd83dbSDimitry Andric    using __cxx_contention_t = int64_t;
1514d061adc4SAdrian Chadd#endif
15155ffd83dbSDimitry Andric
15165ffd83dbSDimitry Andricusing __cxx_atomic_contention_t = __cxx_atomic_impl<__cxx_contention_t>;
15175ffd83dbSDimitry Andric
15185ffd83dbSDimitry Andric#ifndef _LIBCPP_HAS_NO_PLATFORM_WAIT
15195ffd83dbSDimitry Andric
15205ffd83dbSDimitry Andric_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_one(void const volatile*);
15215ffd83dbSDimitry Andric_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_all(void const volatile*);
15225ffd83dbSDimitry Andric_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t __libcpp_atomic_monitor(void const volatile*);
15235ffd83dbSDimitry Andric_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __libcpp_atomic_wait(void const volatile*, __cxx_contention_t);
15245ffd83dbSDimitry Andric
15255ffd83dbSDimitry Andric_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_one(__cxx_atomic_contention_t const volatile*);
15265ffd83dbSDimitry Andric_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_all(__cxx_atomic_contention_t const volatile*);
15275ffd83dbSDimitry Andric_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t __libcpp_atomic_monitor(__cxx_atomic_contention_t const volatile*);
15285ffd83dbSDimitry Andric_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __libcpp_atomic_wait(__cxx_atomic_contention_t const volatile*, __cxx_contention_t);
15295ffd83dbSDimitry Andric
15305ffd83dbSDimitry Andrictemplate <class _Atp, class _Fn>
15315ffd83dbSDimitry Andricstruct __libcpp_atomic_wait_backoff_impl {
15325ffd83dbSDimitry Andric    _Atp* __a;
15335ffd83dbSDimitry Andric    _Fn __test_fn;
15345ffd83dbSDimitry Andric    _LIBCPP_AVAILABILITY_SYNC
15355ffd83dbSDimitry Andric    _LIBCPP_INLINE_VISIBILITY bool operator()(chrono::nanoseconds __elapsed) const
15365ffd83dbSDimitry Andric    {
15375ffd83dbSDimitry Andric        if(__elapsed > chrono::microseconds(64))
15385ffd83dbSDimitry Andric        {
15395ffd83dbSDimitry Andric            auto const __monitor = __libcpp_atomic_monitor(__a);
15405ffd83dbSDimitry Andric            if(__test_fn())
15415ffd83dbSDimitry Andric                return true;
15425ffd83dbSDimitry Andric            __libcpp_atomic_wait(__a, __monitor);
15435ffd83dbSDimitry Andric        }
15445ffd83dbSDimitry Andric        else if(__elapsed > chrono::microseconds(4))
15455ffd83dbSDimitry Andric            __libcpp_thread_yield();
15465ffd83dbSDimitry Andric        else
1547e8d8bef9SDimitry Andric            {} // poll
15485ffd83dbSDimitry Andric        return false;
15495ffd83dbSDimitry Andric    }
15505ffd83dbSDimitry Andric};
15515ffd83dbSDimitry Andric
15525ffd83dbSDimitry Andrictemplate <class _Atp, class _Fn>
15535ffd83dbSDimitry Andric_LIBCPP_AVAILABILITY_SYNC
15545ffd83dbSDimitry Andric_LIBCPP_INLINE_VISIBILITY bool __cxx_atomic_wait(_Atp* __a, _Fn && __test_fn)
15555ffd83dbSDimitry Andric{
15565ffd83dbSDimitry Andric    __libcpp_atomic_wait_backoff_impl<_Atp, typename decay<_Fn>::type> __backoff_fn = {__a, __test_fn};
15575ffd83dbSDimitry Andric    return __libcpp_thread_poll_with_backoff(__test_fn, __backoff_fn);
15585ffd83dbSDimitry Andric}
15595ffd83dbSDimitry Andric
15605ffd83dbSDimitry Andric#else // _LIBCPP_HAS_NO_PLATFORM_WAIT
15615ffd83dbSDimitry Andric
15625ffd83dbSDimitry Andrictemplate <class _Tp>
15635ffd83dbSDimitry Andric_LIBCPP_INLINE_VISIBILITY void __cxx_atomic_notify_all(__cxx_atomic_impl<_Tp> const volatile*) { }
15645ffd83dbSDimitry Andrictemplate <class _Tp>
15655ffd83dbSDimitry Andric_LIBCPP_INLINE_VISIBILITY void __cxx_atomic_notify_one(__cxx_atomic_impl<_Tp> const volatile*) { }
15665ffd83dbSDimitry Andrictemplate <class _Atp, class _Fn>
15675ffd83dbSDimitry Andric_LIBCPP_INLINE_VISIBILITY bool __cxx_atomic_wait(_Atp*, _Fn && __test_fn)
15685ffd83dbSDimitry Andric{
15695ffd83dbSDimitry Andric    return __libcpp_thread_poll_with_backoff(__test_fn, __libcpp_timed_backoff_policy());
15705ffd83dbSDimitry Andric}
15715ffd83dbSDimitry Andric
15725ffd83dbSDimitry Andric#endif // _LIBCPP_HAS_NO_PLATFORM_WAIT
15735ffd83dbSDimitry Andric
15745ffd83dbSDimitry Andrictemplate <class _Atp, class _Tp>
15755ffd83dbSDimitry Andricstruct __cxx_atomic_wait_test_fn_impl {
15765ffd83dbSDimitry Andric    _Atp* __a;
15775ffd83dbSDimitry Andric    _Tp __val;
15785ffd83dbSDimitry Andric    memory_order __order;
15795ffd83dbSDimitry Andric    _LIBCPP_INLINE_VISIBILITY bool operator()() const
15805ffd83dbSDimitry Andric    {
15815ffd83dbSDimitry Andric        return !__cxx_nonatomic_compare_equal(__cxx_atomic_load(__a, __order), __val);
15825ffd83dbSDimitry Andric    }
15835ffd83dbSDimitry Andric};
15845ffd83dbSDimitry Andric
15855ffd83dbSDimitry Andrictemplate <class _Atp, class _Tp>
15865ffd83dbSDimitry Andric_LIBCPP_AVAILABILITY_SYNC
15875ffd83dbSDimitry Andric_LIBCPP_INLINE_VISIBILITY bool __cxx_atomic_wait(_Atp* __a, _Tp const __val, memory_order __order)
15885ffd83dbSDimitry Andric{
15895ffd83dbSDimitry Andric    __cxx_atomic_wait_test_fn_impl<_Atp, _Tp> __test_fn = {__a, __val, __order};
15905ffd83dbSDimitry Andric    return __cxx_atomic_wait(__a, __test_fn);
15915ffd83dbSDimitry Andric}
15925ffd83dbSDimitry Andric
15930b57cec5SDimitry Andric// general atomic<T>
15940b57cec5SDimitry Andric
15950b57cec5SDimitry Andrictemplate <class _Tp, bool = is_integral<_Tp>::value && !is_same<_Tp, bool>::value>
15960b57cec5SDimitry Andricstruct __atomic_base  // false
15970b57cec5SDimitry Andric{
15980b57cec5SDimitry Andric    mutable __cxx_atomic_impl<_Tp> __a_;
15990b57cec5SDimitry Andric
16000b57cec5SDimitry Andric#if defined(__cpp_lib_atomic_is_always_lock_free)
16010b57cec5SDimitry Andric  static _LIBCPP_CONSTEXPR bool is_always_lock_free = __atomic_always_lock_free(sizeof(__a_), 0);
16020b57cec5SDimitry Andric#endif
16030b57cec5SDimitry Andric
16040b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
16050b57cec5SDimitry Andric    bool is_lock_free() const volatile _NOEXCEPT
16060b57cec5SDimitry Andric        {return __cxx_atomic_is_lock_free(sizeof(_Tp));}
16070b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
16080b57cec5SDimitry Andric    bool is_lock_free() const _NOEXCEPT
16090b57cec5SDimitry Andric        {return static_cast<__atomic_base const volatile*>(this)->is_lock_free();}
16100b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
16110b57cec5SDimitry Andric    void store(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
16120b57cec5SDimitry Andric      _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
16130b57cec5SDimitry Andric        {__cxx_atomic_store(&__a_, __d, __m);}
16140b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
16150b57cec5SDimitry Andric    void store(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT
16160b57cec5SDimitry Andric      _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
16170b57cec5SDimitry Andric        {__cxx_atomic_store(&__a_, __d, __m);}
16180b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
16190b57cec5SDimitry Andric    _Tp load(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
16200b57cec5SDimitry Andric      _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
16210b57cec5SDimitry Andric        {return __cxx_atomic_load(&__a_, __m);}
16220b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
16230b57cec5SDimitry Andric    _Tp load(memory_order __m = memory_order_seq_cst) const _NOEXCEPT
16240b57cec5SDimitry Andric      _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
16250b57cec5SDimitry Andric        {return __cxx_atomic_load(&__a_, __m);}
16260b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
16270b57cec5SDimitry Andric    operator _Tp() const volatile _NOEXCEPT {return load();}
16280b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
16290b57cec5SDimitry Andric    operator _Tp() const _NOEXCEPT          {return load();}
16300b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
16310b57cec5SDimitry Andric    _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
16320b57cec5SDimitry Andric        {return __cxx_atomic_exchange(&__a_, __d, __m);}
16330b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
16340b57cec5SDimitry Andric    _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT
16350b57cec5SDimitry Andric        {return __cxx_atomic_exchange(&__a_, __d, __m);}
16360b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
16370b57cec5SDimitry Andric    bool compare_exchange_weak(_Tp& __e, _Tp __d,
16380b57cec5SDimitry Andric                               memory_order __s, memory_order __f) volatile _NOEXCEPT
16390b57cec5SDimitry Andric      _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
16400b57cec5SDimitry Andric        {return __cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);}
16410b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
16420b57cec5SDimitry Andric    bool compare_exchange_weak(_Tp& __e, _Tp __d,
16430b57cec5SDimitry Andric                               memory_order __s, memory_order __f) _NOEXCEPT
16440b57cec5SDimitry Andric      _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
16450b57cec5SDimitry Andric        {return __cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);}
16460b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
16470b57cec5SDimitry Andric    bool compare_exchange_strong(_Tp& __e, _Tp __d,
16480b57cec5SDimitry Andric                                 memory_order __s, memory_order __f) volatile _NOEXCEPT
16490b57cec5SDimitry Andric      _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
16500b57cec5SDimitry Andric        {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);}
16510b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
16520b57cec5SDimitry Andric    bool compare_exchange_strong(_Tp& __e, _Tp __d,
16530b57cec5SDimitry Andric                                 memory_order __s, memory_order __f) _NOEXCEPT
16540b57cec5SDimitry Andric      _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
16550b57cec5SDimitry Andric        {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);}
16560b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
16570b57cec5SDimitry Andric    bool compare_exchange_weak(_Tp& __e, _Tp __d,
16580b57cec5SDimitry Andric                              memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
16590b57cec5SDimitry Andric        {return __cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);}
16600b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
16610b57cec5SDimitry Andric    bool compare_exchange_weak(_Tp& __e, _Tp __d,
16620b57cec5SDimitry Andric                               memory_order __m = memory_order_seq_cst) _NOEXCEPT
16630b57cec5SDimitry Andric        {return __cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);}
16640b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
16650b57cec5SDimitry Andric    bool compare_exchange_strong(_Tp& __e, _Tp __d,
16660b57cec5SDimitry Andric                              memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
16670b57cec5SDimitry Andric        {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}
16680b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
16690b57cec5SDimitry Andric    bool compare_exchange_strong(_Tp& __e, _Tp __d,
16700b57cec5SDimitry Andric                                 memory_order __m = memory_order_seq_cst) _NOEXCEPT
16710b57cec5SDimitry Andric        {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}
16720b57cec5SDimitry Andric
16735ffd83dbSDimitry Andric    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void wait(_Tp __v, memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
16745ffd83dbSDimitry Andric        {__cxx_atomic_wait(&__a_, __v, __m);}
16755ffd83dbSDimitry Andric    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void wait(_Tp __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT
16765ffd83dbSDimitry Andric        {__cxx_atomic_wait(&__a_, __v, __m);}
16775ffd83dbSDimitry Andric    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_one() volatile _NOEXCEPT
16785ffd83dbSDimitry Andric        {__cxx_atomic_notify_one(&__a_);}
16795ffd83dbSDimitry Andric    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_one() _NOEXCEPT
16805ffd83dbSDimitry Andric        {__cxx_atomic_notify_one(&__a_);}
16815ffd83dbSDimitry Andric    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_all() volatile _NOEXCEPT
16825ffd83dbSDimitry Andric        {__cxx_atomic_notify_all(&__a_);}
16835ffd83dbSDimitry Andric    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_all() _NOEXCEPT
16845ffd83dbSDimitry Andric        {__cxx_atomic_notify_all(&__a_);}
16855ffd83dbSDimitry Andric
1686*fe6060f1SDimitry Andric#if _LIBCPP_STD_VER > 17
1687*fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY constexpr
1688*fe6060f1SDimitry Andric    __atomic_base() noexcept(is_nothrow_default_constructible_v<_Tp>) : __a_(_Tp()) {}
1689*fe6060f1SDimitry Andric#else
16900b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
16910b57cec5SDimitry Andric    __atomic_base() _NOEXCEPT _LIBCPP_DEFAULT
1692*fe6060f1SDimitry Andric#endif
16930b57cec5SDimitry Andric
16940b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
16950b57cec5SDimitry Andric    __atomic_base(_Tp __d) _NOEXCEPT : __a_(__d) {}
16960b57cec5SDimitry Andric
16970b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
16980b57cec5SDimitry Andric    __atomic_base(const __atomic_base&) = delete;
16990b57cec5SDimitry Andric#else
17000b57cec5SDimitry Andricprivate:
17015ffd83dbSDimitry Andric    _LIBCPP_INLINE_VISIBILITY
17020b57cec5SDimitry Andric    __atomic_base(const __atomic_base&);
17030b57cec5SDimitry Andric#endif
17040b57cec5SDimitry Andric};
17050b57cec5SDimitry Andric
17060b57cec5SDimitry Andric#if defined(__cpp_lib_atomic_is_always_lock_free)
17070b57cec5SDimitry Andrictemplate <class _Tp, bool __b>
17080b57cec5SDimitry Andric_LIBCPP_CONSTEXPR bool __atomic_base<_Tp, __b>::is_always_lock_free;
17090b57cec5SDimitry Andric#endif
17100b57cec5SDimitry Andric
17110b57cec5SDimitry Andric// atomic<Integral>
17120b57cec5SDimitry Andric
17130b57cec5SDimitry Andrictemplate <class _Tp>
17140b57cec5SDimitry Andricstruct __atomic_base<_Tp, true>
17150b57cec5SDimitry Andric    : public __atomic_base<_Tp, false>
17160b57cec5SDimitry Andric{
17170b57cec5SDimitry Andric    typedef __atomic_base<_Tp, false> __base;
1718*fe6060f1SDimitry Andric
1719*fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
17200b57cec5SDimitry Andric    __atomic_base() _NOEXCEPT _LIBCPP_DEFAULT
1721*fe6060f1SDimitry Andric
17220b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
17230b57cec5SDimitry Andric    _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __base(__d) {}
17240b57cec5SDimitry Andric
17250b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
17260b57cec5SDimitry Andric    _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
17270b57cec5SDimitry Andric        {return __cxx_atomic_fetch_add(&this->__a_, __op, __m);}
17280b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
17290b57cec5SDimitry Andric    _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
17300b57cec5SDimitry Andric        {return __cxx_atomic_fetch_add(&this->__a_, __op, __m);}
17310b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
17320b57cec5SDimitry Andric    _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
17330b57cec5SDimitry Andric        {return __cxx_atomic_fetch_sub(&this->__a_, __op, __m);}
17340b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
17350b57cec5SDimitry Andric    _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
17360b57cec5SDimitry Andric        {return __cxx_atomic_fetch_sub(&this->__a_, __op, __m);}
17370b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
17380b57cec5SDimitry Andric    _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
17390b57cec5SDimitry Andric        {return __cxx_atomic_fetch_and(&this->__a_, __op, __m);}
17400b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
17410b57cec5SDimitry Andric    _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
17420b57cec5SDimitry Andric        {return __cxx_atomic_fetch_and(&this->__a_, __op, __m);}
17430b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
17440b57cec5SDimitry Andric    _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
17450b57cec5SDimitry Andric        {return __cxx_atomic_fetch_or(&this->__a_, __op, __m);}
17460b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
17470b57cec5SDimitry Andric    _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
17480b57cec5SDimitry Andric        {return __cxx_atomic_fetch_or(&this->__a_, __op, __m);}
17490b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
17500b57cec5SDimitry Andric    _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
17510b57cec5SDimitry Andric        {return __cxx_atomic_fetch_xor(&this->__a_, __op, __m);}
17520b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
17530b57cec5SDimitry Andric    _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
17540b57cec5SDimitry Andric        {return __cxx_atomic_fetch_xor(&this->__a_, __op, __m);}
17550b57cec5SDimitry Andric
17560b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
17570b57cec5SDimitry Andric    _Tp operator++(int) volatile _NOEXCEPT      {return fetch_add(_Tp(1));}
17580b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
17590b57cec5SDimitry Andric    _Tp operator++(int) _NOEXCEPT               {return fetch_add(_Tp(1));}
17600b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
17610b57cec5SDimitry Andric    _Tp operator--(int) volatile _NOEXCEPT      {return fetch_sub(_Tp(1));}
17620b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
17630b57cec5SDimitry Andric    _Tp operator--(int) _NOEXCEPT               {return fetch_sub(_Tp(1));}
17640b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
17650b57cec5SDimitry Andric    _Tp operator++() volatile _NOEXCEPT         {return fetch_add(_Tp(1)) + _Tp(1);}
17660b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
17670b57cec5SDimitry Andric    _Tp operator++() _NOEXCEPT                  {return fetch_add(_Tp(1)) + _Tp(1);}
17680b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
17690b57cec5SDimitry Andric    _Tp operator--() volatile _NOEXCEPT         {return fetch_sub(_Tp(1)) - _Tp(1);}
17700b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
17710b57cec5SDimitry Andric    _Tp operator--() _NOEXCEPT                  {return fetch_sub(_Tp(1)) - _Tp(1);}
17720b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
17730b57cec5SDimitry Andric    _Tp operator+=(_Tp __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;}
17740b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
17750b57cec5SDimitry Andric    _Tp operator+=(_Tp __op) _NOEXCEPT          {return fetch_add(__op) + __op;}
17760b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
17770b57cec5SDimitry Andric    _Tp operator-=(_Tp __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;}
17780b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
17790b57cec5SDimitry Andric    _Tp operator-=(_Tp __op) _NOEXCEPT          {return fetch_sub(__op) - __op;}
17800b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
17810b57cec5SDimitry Andric    _Tp operator&=(_Tp __op) volatile _NOEXCEPT {return fetch_and(__op) & __op;}
17820b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
17830b57cec5SDimitry Andric    _Tp operator&=(_Tp __op) _NOEXCEPT          {return fetch_and(__op) & __op;}
17840b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
17850b57cec5SDimitry Andric    _Tp operator|=(_Tp __op) volatile _NOEXCEPT {return fetch_or(__op) | __op;}
17860b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
17870b57cec5SDimitry Andric    _Tp operator|=(_Tp __op) _NOEXCEPT          {return fetch_or(__op) | __op;}
17880b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
17890b57cec5SDimitry Andric    _Tp operator^=(_Tp __op) volatile _NOEXCEPT {return fetch_xor(__op) ^ __op;}
17900b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
17910b57cec5SDimitry Andric    _Tp operator^=(_Tp __op) _NOEXCEPT          {return fetch_xor(__op) ^ __op;}
17920b57cec5SDimitry Andric};
17930b57cec5SDimitry Andric
17940b57cec5SDimitry Andric// atomic<T>
17950b57cec5SDimitry Andric
17960b57cec5SDimitry Andrictemplate <class _Tp>
17970b57cec5SDimitry Andricstruct atomic
17980b57cec5SDimitry Andric    : public __atomic_base<_Tp>
17990b57cec5SDimitry Andric{
18000b57cec5SDimitry Andric    typedef __atomic_base<_Tp> __base;
18015ffd83dbSDimitry Andric    typedef _Tp value_type;
1802e8d8bef9SDimitry Andric    typedef value_type difference_type;
1803*fe6060f1SDimitry Andric
1804*fe6060f1SDimitry Andric#if _LIBCPP_STD_VER > 17
1805*fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1806*fe6060f1SDimitry Andric    atomic() = default;
1807*fe6060f1SDimitry Andric#else
18080b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
18090b57cec5SDimitry Andric    atomic() _NOEXCEPT _LIBCPP_DEFAULT
1810*fe6060f1SDimitry Andric#endif
1811*fe6060f1SDimitry Andric
18120b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
18130b57cec5SDimitry Andric    _LIBCPP_CONSTEXPR atomic(_Tp __d) _NOEXCEPT : __base(__d) {}
18140b57cec5SDimitry Andric
18150b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
18160b57cec5SDimitry Andric    _Tp operator=(_Tp __d) volatile _NOEXCEPT
18170b57cec5SDimitry Andric        {__base::store(__d); return __d;}
18180b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
18190b57cec5SDimitry Andric    _Tp operator=(_Tp __d) _NOEXCEPT
18200b57cec5SDimitry Andric        {__base::store(__d); return __d;}
1821*fe6060f1SDimitry Andric
1822*fe6060f1SDimitry Andric    atomic& operator=(const atomic&) = delete;
1823*fe6060f1SDimitry Andric    atomic& operator=(const atomic&) volatile = delete;
18240b57cec5SDimitry Andric};
18250b57cec5SDimitry Andric
18260b57cec5SDimitry Andric// atomic<T*>
18270b57cec5SDimitry Andric
18280b57cec5SDimitry Andrictemplate <class _Tp>
18290b57cec5SDimitry Andricstruct atomic<_Tp*>
18300b57cec5SDimitry Andric    : public __atomic_base<_Tp*>
18310b57cec5SDimitry Andric{
18320b57cec5SDimitry Andric    typedef __atomic_base<_Tp*> __base;
18335ffd83dbSDimitry Andric    typedef _Tp* value_type;
1834e8d8bef9SDimitry Andric    typedef ptrdiff_t difference_type;
1835*fe6060f1SDimitry Andric
18360b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
18370b57cec5SDimitry Andric    atomic() _NOEXCEPT _LIBCPP_DEFAULT
1838*fe6060f1SDimitry Andric
18390b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
18400b57cec5SDimitry Andric    _LIBCPP_CONSTEXPR atomic(_Tp* __d) _NOEXCEPT : __base(__d) {}
18410b57cec5SDimitry Andric
18420b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
18430b57cec5SDimitry Andric    _Tp* operator=(_Tp* __d) volatile _NOEXCEPT
18440b57cec5SDimitry Andric        {__base::store(__d); return __d;}
18450b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
18460b57cec5SDimitry Andric    _Tp* operator=(_Tp* __d) _NOEXCEPT
18470b57cec5SDimitry Andric        {__base::store(__d); return __d;}
18480b57cec5SDimitry Andric
18490b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
18500b57cec5SDimitry Andric    _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst)
18510b57cec5SDimitry Andric                                                                        volatile _NOEXCEPT
18520b57cec5SDimitry Andric        {return __cxx_atomic_fetch_add(&this->__a_, __op, __m);}
18530b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
18540b57cec5SDimitry Andric    _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
18550b57cec5SDimitry Andric        {return __cxx_atomic_fetch_add(&this->__a_, __op, __m);}
18560b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
18570b57cec5SDimitry Andric    _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst)
18580b57cec5SDimitry Andric                                                                        volatile _NOEXCEPT
18590b57cec5SDimitry Andric        {return __cxx_atomic_fetch_sub(&this->__a_, __op, __m);}
18600b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
18610b57cec5SDimitry Andric    _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
18620b57cec5SDimitry Andric        {return __cxx_atomic_fetch_sub(&this->__a_, __op, __m);}
18630b57cec5SDimitry Andric
18640b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
18650b57cec5SDimitry Andric    _Tp* operator++(int) volatile _NOEXCEPT            {return fetch_add(1);}
18660b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
18670b57cec5SDimitry Andric    _Tp* operator++(int) _NOEXCEPT                     {return fetch_add(1);}
18680b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
18690b57cec5SDimitry Andric    _Tp* operator--(int) volatile _NOEXCEPT            {return fetch_sub(1);}
18700b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
18710b57cec5SDimitry Andric    _Tp* operator--(int) _NOEXCEPT                     {return fetch_sub(1);}
18720b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
18730b57cec5SDimitry Andric    _Tp* operator++() volatile _NOEXCEPT               {return fetch_add(1) + 1;}
18740b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
18750b57cec5SDimitry Andric    _Tp* operator++() _NOEXCEPT                        {return fetch_add(1) + 1;}
18760b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
18770b57cec5SDimitry Andric    _Tp* operator--() volatile _NOEXCEPT               {return fetch_sub(1) - 1;}
18780b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
18790b57cec5SDimitry Andric    _Tp* operator--() _NOEXCEPT                        {return fetch_sub(1) - 1;}
18800b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
18810b57cec5SDimitry Andric    _Tp* operator+=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;}
18820b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
18830b57cec5SDimitry Andric    _Tp* operator+=(ptrdiff_t __op) _NOEXCEPT          {return fetch_add(__op) + __op;}
18840b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
18850b57cec5SDimitry Andric    _Tp* operator-=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;}
18860b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
18870b57cec5SDimitry Andric    _Tp* operator-=(ptrdiff_t __op) _NOEXCEPT          {return fetch_sub(__op) - __op;}
1888*fe6060f1SDimitry Andric
1889*fe6060f1SDimitry Andric    atomic& operator=(const atomic&) = delete;
1890*fe6060f1SDimitry Andric    atomic& operator=(const atomic&) volatile = delete;
18910b57cec5SDimitry Andric};
18920b57cec5SDimitry Andric
18930b57cec5SDimitry Andric// atomic_is_lock_free
18940b57cec5SDimitry Andric
18950b57cec5SDimitry Andrictemplate <class _Tp>
18960b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
18970b57cec5SDimitry Andricbool
18980b57cec5SDimitry Andricatomic_is_lock_free(const volatile atomic<_Tp>* __o) _NOEXCEPT
18990b57cec5SDimitry Andric{
19000b57cec5SDimitry Andric    return __o->is_lock_free();
19010b57cec5SDimitry Andric}
19020b57cec5SDimitry Andric
19030b57cec5SDimitry Andrictemplate <class _Tp>
19040b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
19050b57cec5SDimitry Andricbool
19060b57cec5SDimitry Andricatomic_is_lock_free(const atomic<_Tp>* __o) _NOEXCEPT
19070b57cec5SDimitry Andric{
19080b57cec5SDimitry Andric    return __o->is_lock_free();
19090b57cec5SDimitry Andric}
19100b57cec5SDimitry Andric
19110b57cec5SDimitry Andric// atomic_init
19120b57cec5SDimitry Andric
19130b57cec5SDimitry Andrictemplate <class _Tp>
1914*fe6060f1SDimitry Andric_LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_INLINE_VISIBILITY
19150b57cec5SDimitry Andricvoid
1916e8d8bef9SDimitry Andricatomic_init(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
19170b57cec5SDimitry Andric{
19180b57cec5SDimitry Andric    __cxx_atomic_init(&__o->__a_, __d);
19190b57cec5SDimitry Andric}
19200b57cec5SDimitry Andric
19210b57cec5SDimitry Andrictemplate <class _Tp>
1922*fe6060f1SDimitry Andric_LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_INLINE_VISIBILITY
19230b57cec5SDimitry Andricvoid
1924e8d8bef9SDimitry Andricatomic_init(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
19250b57cec5SDimitry Andric{
19260b57cec5SDimitry Andric    __cxx_atomic_init(&__o->__a_, __d);
19270b57cec5SDimitry Andric}
19280b57cec5SDimitry Andric
19290b57cec5SDimitry Andric// atomic_store
19300b57cec5SDimitry Andric
19310b57cec5SDimitry Andrictemplate <class _Tp>
19320b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
19330b57cec5SDimitry Andricvoid
1934e8d8bef9SDimitry Andricatomic_store(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
19350b57cec5SDimitry Andric{
19360b57cec5SDimitry Andric    __o->store(__d);
19370b57cec5SDimitry Andric}
19380b57cec5SDimitry Andric
19390b57cec5SDimitry Andrictemplate <class _Tp>
19400b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
19410b57cec5SDimitry Andricvoid
1942e8d8bef9SDimitry Andricatomic_store(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
19430b57cec5SDimitry Andric{
19440b57cec5SDimitry Andric    __o->store(__d);
19450b57cec5SDimitry Andric}
19460b57cec5SDimitry Andric
19470b57cec5SDimitry Andric// atomic_store_explicit
19480b57cec5SDimitry Andric
19490b57cec5SDimitry Andrictemplate <class _Tp>
19500b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
19510b57cec5SDimitry Andricvoid
1952e8d8bef9SDimitry Andricatomic_store_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT
19530b57cec5SDimitry Andric  _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
19540b57cec5SDimitry Andric{
19550b57cec5SDimitry Andric    __o->store(__d, __m);
19560b57cec5SDimitry Andric}
19570b57cec5SDimitry Andric
19580b57cec5SDimitry Andrictemplate <class _Tp>
19590b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
19600b57cec5SDimitry Andricvoid
1961e8d8bef9SDimitry Andricatomic_store_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT
19620b57cec5SDimitry Andric  _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
19630b57cec5SDimitry Andric{
19640b57cec5SDimitry Andric    __o->store(__d, __m);
19650b57cec5SDimitry Andric}
19660b57cec5SDimitry Andric
19670b57cec5SDimitry Andric// atomic_load
19680b57cec5SDimitry Andric
19690b57cec5SDimitry Andrictemplate <class _Tp>
19700b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
19710b57cec5SDimitry Andric_Tp
19720b57cec5SDimitry Andricatomic_load(const volatile atomic<_Tp>* __o) _NOEXCEPT
19730b57cec5SDimitry Andric{
19740b57cec5SDimitry Andric    return __o->load();
19750b57cec5SDimitry Andric}
19760b57cec5SDimitry Andric
19770b57cec5SDimitry Andrictemplate <class _Tp>
19780b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
19790b57cec5SDimitry Andric_Tp
19800b57cec5SDimitry Andricatomic_load(const atomic<_Tp>* __o) _NOEXCEPT
19810b57cec5SDimitry Andric{
19820b57cec5SDimitry Andric    return __o->load();
19830b57cec5SDimitry Andric}
19840b57cec5SDimitry Andric
19850b57cec5SDimitry Andric// atomic_load_explicit
19860b57cec5SDimitry Andric
19870b57cec5SDimitry Andrictemplate <class _Tp>
19880b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
19890b57cec5SDimitry Andric_Tp
19900b57cec5SDimitry Andricatomic_load_explicit(const volatile atomic<_Tp>* __o, memory_order __m) _NOEXCEPT
19910b57cec5SDimitry Andric  _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
19920b57cec5SDimitry Andric{
19930b57cec5SDimitry Andric    return __o->load(__m);
19940b57cec5SDimitry Andric}
19950b57cec5SDimitry Andric
19960b57cec5SDimitry Andrictemplate <class _Tp>
19970b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
19980b57cec5SDimitry Andric_Tp
19990b57cec5SDimitry Andricatomic_load_explicit(const atomic<_Tp>* __o, memory_order __m) _NOEXCEPT
20000b57cec5SDimitry Andric  _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
20010b57cec5SDimitry Andric{
20020b57cec5SDimitry Andric    return __o->load(__m);
20030b57cec5SDimitry Andric}
20040b57cec5SDimitry Andric
20050b57cec5SDimitry Andric// atomic_exchange
20060b57cec5SDimitry Andric
20070b57cec5SDimitry Andrictemplate <class _Tp>
20080b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
20090b57cec5SDimitry Andric_Tp
2010e8d8bef9SDimitry Andricatomic_exchange(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
20110b57cec5SDimitry Andric{
20120b57cec5SDimitry Andric    return __o->exchange(__d);
20130b57cec5SDimitry Andric}
20140b57cec5SDimitry Andric
20150b57cec5SDimitry Andrictemplate <class _Tp>
20160b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
20170b57cec5SDimitry Andric_Tp
2018e8d8bef9SDimitry Andricatomic_exchange(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
20190b57cec5SDimitry Andric{
20200b57cec5SDimitry Andric    return __o->exchange(__d);
20210b57cec5SDimitry Andric}
20220b57cec5SDimitry Andric
20230b57cec5SDimitry Andric// atomic_exchange_explicit
20240b57cec5SDimitry Andric
20250b57cec5SDimitry Andrictemplate <class _Tp>
20260b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
20270b57cec5SDimitry Andric_Tp
2028e8d8bef9SDimitry Andricatomic_exchange_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT
20290b57cec5SDimitry Andric{
20300b57cec5SDimitry Andric    return __o->exchange(__d, __m);
20310b57cec5SDimitry Andric}
20320b57cec5SDimitry Andric
20330b57cec5SDimitry Andrictemplate <class _Tp>
20340b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
20350b57cec5SDimitry Andric_Tp
2036e8d8bef9SDimitry Andricatomic_exchange_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT
20370b57cec5SDimitry Andric{
20380b57cec5SDimitry Andric    return __o->exchange(__d, __m);
20390b57cec5SDimitry Andric}
20400b57cec5SDimitry Andric
20410b57cec5SDimitry Andric// atomic_compare_exchange_weak
20420b57cec5SDimitry Andric
20430b57cec5SDimitry Andrictemplate <class _Tp>
20440b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
20450b57cec5SDimitry Andricbool
2046e8d8bef9SDimitry Andricatomic_compare_exchange_weak(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT
20470b57cec5SDimitry Andric{
20480b57cec5SDimitry Andric    return __o->compare_exchange_weak(*__e, __d);
20490b57cec5SDimitry Andric}
20500b57cec5SDimitry Andric
20510b57cec5SDimitry Andrictemplate <class _Tp>
20520b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
20530b57cec5SDimitry Andricbool
2054e8d8bef9SDimitry Andricatomic_compare_exchange_weak(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT
20550b57cec5SDimitry Andric{
20560b57cec5SDimitry Andric    return __o->compare_exchange_weak(*__e, __d);
20570b57cec5SDimitry Andric}
20580b57cec5SDimitry Andric
20590b57cec5SDimitry Andric// atomic_compare_exchange_strong
20600b57cec5SDimitry Andric
20610b57cec5SDimitry Andrictemplate <class _Tp>
20620b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
20630b57cec5SDimitry Andricbool
2064e8d8bef9SDimitry Andricatomic_compare_exchange_strong(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT
20650b57cec5SDimitry Andric{
20660b57cec5SDimitry Andric    return __o->compare_exchange_strong(*__e, __d);
20670b57cec5SDimitry Andric}
20680b57cec5SDimitry Andric
20690b57cec5SDimitry Andrictemplate <class _Tp>
20700b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
20710b57cec5SDimitry Andricbool
2072e8d8bef9SDimitry Andricatomic_compare_exchange_strong(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT
20730b57cec5SDimitry Andric{
20740b57cec5SDimitry Andric    return __o->compare_exchange_strong(*__e, __d);
20750b57cec5SDimitry Andric}
20760b57cec5SDimitry Andric
20770b57cec5SDimitry Andric// atomic_compare_exchange_weak_explicit
20780b57cec5SDimitry Andric
20790b57cec5SDimitry Andrictemplate <class _Tp>
20800b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
20810b57cec5SDimitry Andricbool
2082e8d8bef9SDimitry Andricatomic_compare_exchange_weak_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e,
2083e8d8bef9SDimitry Andric                                      typename atomic<_Tp>::value_type __d,
20840b57cec5SDimitry Andric                                      memory_order __s, memory_order __f) _NOEXCEPT
20850b57cec5SDimitry Andric  _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
20860b57cec5SDimitry Andric{
20870b57cec5SDimitry Andric    return __o->compare_exchange_weak(*__e, __d, __s, __f);
20880b57cec5SDimitry Andric}
20890b57cec5SDimitry Andric
20900b57cec5SDimitry Andrictemplate <class _Tp>
20910b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
20920b57cec5SDimitry Andricbool
2093e8d8bef9SDimitry Andricatomic_compare_exchange_weak_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d,
20940b57cec5SDimitry Andric                                      memory_order __s, memory_order __f) _NOEXCEPT
20950b57cec5SDimitry Andric  _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
20960b57cec5SDimitry Andric{
20970b57cec5SDimitry Andric    return __o->compare_exchange_weak(*__e, __d, __s, __f);
20980b57cec5SDimitry Andric}
20990b57cec5SDimitry Andric
21000b57cec5SDimitry Andric// atomic_compare_exchange_strong_explicit
21010b57cec5SDimitry Andric
21020b57cec5SDimitry Andrictemplate <class _Tp>
21030b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
21040b57cec5SDimitry Andricbool
21050b57cec5SDimitry Andricatomic_compare_exchange_strong_explicit(volatile atomic<_Tp>* __o,
2106e8d8bef9SDimitry Andric                                        typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d,
21070b57cec5SDimitry Andric                                        memory_order __s, memory_order __f) _NOEXCEPT
21080b57cec5SDimitry Andric  _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
21090b57cec5SDimitry Andric{
21100b57cec5SDimitry Andric    return __o->compare_exchange_strong(*__e, __d, __s, __f);
21110b57cec5SDimitry Andric}
21120b57cec5SDimitry Andric
21130b57cec5SDimitry Andrictemplate <class _Tp>
21140b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
21150b57cec5SDimitry Andricbool
2116e8d8bef9SDimitry Andricatomic_compare_exchange_strong_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e,
2117e8d8bef9SDimitry Andric                                        typename atomic<_Tp>::value_type __d,
21180b57cec5SDimitry Andric                                        memory_order __s, memory_order __f) _NOEXCEPT
21190b57cec5SDimitry Andric  _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
21200b57cec5SDimitry Andric{
21210b57cec5SDimitry Andric    return __o->compare_exchange_strong(*__e, __d, __s, __f);
21220b57cec5SDimitry Andric}
21230b57cec5SDimitry Andric
21245ffd83dbSDimitry Andric// atomic_wait
21255ffd83dbSDimitry Andric
21265ffd83dbSDimitry Andrictemplate <class _Tp>
21275ffd83dbSDimitry Andric_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
21285ffd83dbSDimitry Andricvoid atomic_wait(const volatile atomic<_Tp>* __o,
21295ffd83dbSDimitry Andric                 typename atomic<_Tp>::value_type __v) _NOEXCEPT
21305ffd83dbSDimitry Andric{
21315ffd83dbSDimitry Andric    return __o->wait(__v);
21325ffd83dbSDimitry Andric}
21335ffd83dbSDimitry Andric
21345ffd83dbSDimitry Andrictemplate <class _Tp>
21355ffd83dbSDimitry Andric_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
21365ffd83dbSDimitry Andricvoid atomic_wait(const atomic<_Tp>* __o,
21375ffd83dbSDimitry Andric                 typename atomic<_Tp>::value_type __v) _NOEXCEPT
21385ffd83dbSDimitry Andric{
21395ffd83dbSDimitry Andric    return __o->wait(__v);
21405ffd83dbSDimitry Andric}
21415ffd83dbSDimitry Andric
21425ffd83dbSDimitry Andric// atomic_wait_explicit
21435ffd83dbSDimitry Andric
21445ffd83dbSDimitry Andrictemplate <class _Tp>
21455ffd83dbSDimitry Andric_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
21465ffd83dbSDimitry Andricvoid atomic_wait_explicit(const volatile atomic<_Tp>* __o,
21475ffd83dbSDimitry Andric                          typename atomic<_Tp>::value_type __v,
21485ffd83dbSDimitry Andric                          memory_order __m) _NOEXCEPT
21495ffd83dbSDimitry Andric  _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
21505ffd83dbSDimitry Andric{
21515ffd83dbSDimitry Andric    return __o->wait(__v, __m);
21525ffd83dbSDimitry Andric}
21535ffd83dbSDimitry Andric
21545ffd83dbSDimitry Andrictemplate <class _Tp>
21555ffd83dbSDimitry Andric_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
21565ffd83dbSDimitry Andricvoid atomic_wait_explicit(const atomic<_Tp>* __o,
21575ffd83dbSDimitry Andric                          typename atomic<_Tp>::value_type __v,
21585ffd83dbSDimitry Andric                          memory_order __m) _NOEXCEPT
21595ffd83dbSDimitry Andric  _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
21605ffd83dbSDimitry Andric{
21615ffd83dbSDimitry Andric    return __o->wait(__v, __m);
21625ffd83dbSDimitry Andric}
21635ffd83dbSDimitry Andric
21645ffd83dbSDimitry Andric// atomic_notify_one
21655ffd83dbSDimitry Andric
21665ffd83dbSDimitry Andrictemplate <class _Tp>
21675ffd83dbSDimitry Andric_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
21685ffd83dbSDimitry Andricvoid atomic_notify_one(volatile atomic<_Tp>* __o) _NOEXCEPT
21695ffd83dbSDimitry Andric{
21705ffd83dbSDimitry Andric    __o->notify_one();
21715ffd83dbSDimitry Andric}
21725ffd83dbSDimitry Andrictemplate <class _Tp>
21735ffd83dbSDimitry Andric_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
21745ffd83dbSDimitry Andricvoid atomic_notify_one(atomic<_Tp>* __o) _NOEXCEPT
21755ffd83dbSDimitry Andric{
21765ffd83dbSDimitry Andric    __o->notify_one();
21775ffd83dbSDimitry Andric}
21785ffd83dbSDimitry Andric
21795ffd83dbSDimitry Andric// atomic_notify_one
21805ffd83dbSDimitry Andric
21815ffd83dbSDimitry Andrictemplate <class _Tp>
21825ffd83dbSDimitry Andric_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
21835ffd83dbSDimitry Andricvoid atomic_notify_all(volatile atomic<_Tp>* __o) _NOEXCEPT
21845ffd83dbSDimitry Andric{
21855ffd83dbSDimitry Andric    __o->notify_all();
21865ffd83dbSDimitry Andric}
21875ffd83dbSDimitry Andrictemplate <class _Tp>
21885ffd83dbSDimitry Andric_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
21895ffd83dbSDimitry Andricvoid atomic_notify_all(atomic<_Tp>* __o) _NOEXCEPT
21905ffd83dbSDimitry Andric{
21915ffd83dbSDimitry Andric    __o->notify_all();
21925ffd83dbSDimitry Andric}
21935ffd83dbSDimitry Andric
21940b57cec5SDimitry Andric// atomic_fetch_add
21950b57cec5SDimitry Andric
21960b57cec5SDimitry Andrictemplate <class _Tp>
21970b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
21980b57cec5SDimitry Andrictypename enable_if
21990b57cec5SDimitry Andric<
2200e8d8bef9SDimitry Andric    is_integral<_Tp>::value && !is_same<_Tp, bool>::value && !is_const<_Tp>::value,
22010b57cec5SDimitry Andric    _Tp
22020b57cec5SDimitry Andric>::type
2203e8d8bef9SDimitry Andricatomic_fetch_add(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT
22040b57cec5SDimitry Andric{
22050b57cec5SDimitry Andric    return __o->fetch_add(__op);
22060b57cec5SDimitry Andric}
22070b57cec5SDimitry Andric
22080b57cec5SDimitry Andrictemplate <class _Tp>
22090b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
22100b57cec5SDimitry Andrictypename enable_if
22110b57cec5SDimitry Andric<
2212e8d8bef9SDimitry Andric    is_integral<_Tp>::value && !is_same<_Tp, bool>::value && !is_const<_Tp>::value,
22130b57cec5SDimitry Andric    _Tp
22140b57cec5SDimitry Andric>::type
2215e8d8bef9SDimitry Andricatomic_fetch_add(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT
22160b57cec5SDimitry Andric{
22170b57cec5SDimitry Andric    return __o->fetch_add(__op);
22180b57cec5SDimitry Andric}
22190b57cec5SDimitry Andric
22200b57cec5SDimitry Andrictemplate <class _Tp>
22210b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
22220b57cec5SDimitry Andric_Tp*
2223e8d8bef9SDimitry Andricatomic_fetch_add(volatile atomic<_Tp*>* __o, typename atomic<_Tp*>::difference_type __op) _NOEXCEPT
22240b57cec5SDimitry Andric{
22250b57cec5SDimitry Andric    return __o->fetch_add(__op);
22260b57cec5SDimitry Andric}
22270b57cec5SDimitry Andric
22280b57cec5SDimitry Andrictemplate <class _Tp>
22290b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
22300b57cec5SDimitry Andric_Tp*
2231e8d8bef9SDimitry Andricatomic_fetch_add(atomic<_Tp*>* __o, typename atomic<_Tp*>::difference_type __op) _NOEXCEPT
22320b57cec5SDimitry Andric{
22330b57cec5SDimitry Andric    return __o->fetch_add(__op);
22340b57cec5SDimitry Andric}
22350b57cec5SDimitry Andric
22360b57cec5SDimitry Andric// atomic_fetch_add_explicit
22370b57cec5SDimitry Andric
22380b57cec5SDimitry Andrictemplate <class _Tp>
22390b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
22400b57cec5SDimitry Andrictypename enable_if
22410b57cec5SDimitry Andric<
2242e8d8bef9SDimitry Andric    is_integral<_Tp>::value && !is_same<_Tp, bool>::value && !is_const<_Tp>::value,
22430b57cec5SDimitry Andric    _Tp
22440b57cec5SDimitry Andric>::type
2245e8d8bef9SDimitry Andricatomic_fetch_add_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT
22460b57cec5SDimitry Andric{
22470b57cec5SDimitry Andric    return __o->fetch_add(__op, __m);
22480b57cec5SDimitry Andric}
22490b57cec5SDimitry Andric
22500b57cec5SDimitry Andrictemplate <class _Tp>
22510b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
22520b57cec5SDimitry Andrictypename enable_if
22530b57cec5SDimitry Andric<
2254e8d8bef9SDimitry Andric    is_integral<_Tp>::value && !is_same<_Tp, bool>::value && !is_const<_Tp>::value,
22550b57cec5SDimitry Andric    _Tp
22560b57cec5SDimitry Andric>::type
2257e8d8bef9SDimitry Andricatomic_fetch_add_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT
22580b57cec5SDimitry Andric{
22590b57cec5SDimitry Andric    return __o->fetch_add(__op, __m);
22600b57cec5SDimitry Andric}
22610b57cec5SDimitry Andric
22620b57cec5SDimitry Andrictemplate <class _Tp>
22630b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
22640b57cec5SDimitry Andric_Tp*
2265e8d8bef9SDimitry Andricatomic_fetch_add_explicit(volatile atomic<_Tp*>* __o, typename atomic<_Tp*>::difference_type __op, memory_order __m) _NOEXCEPT
22660b57cec5SDimitry Andric{
22670b57cec5SDimitry Andric    return __o->fetch_add(__op, __m);
22680b57cec5SDimitry Andric}
22690b57cec5SDimitry Andric
22700b57cec5SDimitry Andrictemplate <class _Tp>
22710b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
22720b57cec5SDimitry Andric_Tp*
2273e8d8bef9SDimitry Andricatomic_fetch_add_explicit(atomic<_Tp*>* __o, typename atomic<_Tp*>::difference_type __op, memory_order __m) _NOEXCEPT
22740b57cec5SDimitry Andric{
22750b57cec5SDimitry Andric    return __o->fetch_add(__op, __m);
22760b57cec5SDimitry Andric}
22770b57cec5SDimitry Andric
22780b57cec5SDimitry Andric// atomic_fetch_sub
22790b57cec5SDimitry Andric
22800b57cec5SDimitry Andrictemplate <class _Tp>
22810b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
22820b57cec5SDimitry Andrictypename enable_if
22830b57cec5SDimitry Andric<
2284e8d8bef9SDimitry Andric    is_integral<_Tp>::value && !is_same<_Tp, bool>::value && !is_const<_Tp>::value,
22850b57cec5SDimitry Andric    _Tp
22860b57cec5SDimitry Andric>::type
2287e8d8bef9SDimitry Andricatomic_fetch_sub(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT
22880b57cec5SDimitry Andric{
22890b57cec5SDimitry Andric    return __o->fetch_sub(__op);
22900b57cec5SDimitry Andric}
22910b57cec5SDimitry Andric
22920b57cec5SDimitry Andrictemplate <class _Tp>
22930b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
22940b57cec5SDimitry Andrictypename enable_if
22950b57cec5SDimitry Andric<
2296e8d8bef9SDimitry Andric    is_integral<_Tp>::value && !is_same<_Tp, bool>::value && !is_const<_Tp>::value,
22970b57cec5SDimitry Andric    _Tp
22980b57cec5SDimitry Andric>::type
2299e8d8bef9SDimitry Andricatomic_fetch_sub(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT
23000b57cec5SDimitry Andric{
23010b57cec5SDimitry Andric    return __o->fetch_sub(__op);
23020b57cec5SDimitry Andric}
23030b57cec5SDimitry Andric
23040b57cec5SDimitry Andrictemplate <class _Tp>
23050b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
23060b57cec5SDimitry Andric_Tp*
2307e8d8bef9SDimitry Andricatomic_fetch_sub(volatile atomic<_Tp*>* __o, typename atomic<_Tp*>::difference_type __op) _NOEXCEPT
23080b57cec5SDimitry Andric{
23090b57cec5SDimitry Andric    return __o->fetch_sub(__op);
23100b57cec5SDimitry Andric}
23110b57cec5SDimitry Andric
23120b57cec5SDimitry Andrictemplate <class _Tp>
23130b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
23140b57cec5SDimitry Andric_Tp*
2315e8d8bef9SDimitry Andricatomic_fetch_sub(atomic<_Tp*>* __o, typename atomic<_Tp*>::difference_type __op) _NOEXCEPT
23160b57cec5SDimitry Andric{
23170b57cec5SDimitry Andric    return __o->fetch_sub(__op);
23180b57cec5SDimitry Andric}
23190b57cec5SDimitry Andric
23200b57cec5SDimitry Andric// atomic_fetch_sub_explicit
23210b57cec5SDimitry Andric
23220b57cec5SDimitry Andrictemplate <class _Tp>
23230b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
23240b57cec5SDimitry Andrictypename enable_if
23250b57cec5SDimitry Andric<
2326e8d8bef9SDimitry Andric    is_integral<_Tp>::value && !is_same<_Tp, bool>::value && !is_const<_Tp>::value,
23270b57cec5SDimitry Andric    _Tp
23280b57cec5SDimitry Andric>::type
2329e8d8bef9SDimitry Andricatomic_fetch_sub_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT
23300b57cec5SDimitry Andric{
23310b57cec5SDimitry Andric    return __o->fetch_sub(__op, __m);
23320b57cec5SDimitry Andric}
23330b57cec5SDimitry Andric
23340b57cec5SDimitry Andrictemplate <class _Tp>
23350b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
23360b57cec5SDimitry Andrictypename enable_if
23370b57cec5SDimitry Andric<
2338e8d8bef9SDimitry Andric    is_integral<_Tp>::value && !is_same<_Tp, bool>::value && !is_const<_Tp>::value,
23390b57cec5SDimitry Andric    _Tp
23400b57cec5SDimitry Andric>::type
2341e8d8bef9SDimitry Andricatomic_fetch_sub_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT
23420b57cec5SDimitry Andric{
23430b57cec5SDimitry Andric    return __o->fetch_sub(__op, __m);
23440b57cec5SDimitry Andric}
23450b57cec5SDimitry Andric
23460b57cec5SDimitry Andrictemplate <class _Tp>
23470b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
23480b57cec5SDimitry Andric_Tp*
2349e8d8bef9SDimitry Andricatomic_fetch_sub_explicit(volatile atomic<_Tp*>* __o, typename atomic<_Tp*>::difference_type __op, memory_order __m) _NOEXCEPT
23500b57cec5SDimitry Andric{
23510b57cec5SDimitry Andric    return __o->fetch_sub(__op, __m);
23520b57cec5SDimitry Andric}
23530b57cec5SDimitry Andric
23540b57cec5SDimitry Andrictemplate <class _Tp>
23550b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
23560b57cec5SDimitry Andric_Tp*
2357e8d8bef9SDimitry Andricatomic_fetch_sub_explicit(atomic<_Tp*>* __o, typename atomic<_Tp*>::difference_type __op, memory_order __m) _NOEXCEPT
23580b57cec5SDimitry Andric{
23590b57cec5SDimitry Andric    return __o->fetch_sub(__op, __m);
23600b57cec5SDimitry Andric}
23610b57cec5SDimitry Andric
23620b57cec5SDimitry Andric// atomic_fetch_and
23630b57cec5SDimitry Andric
23640b57cec5SDimitry Andrictemplate <class _Tp>
23650b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
23660b57cec5SDimitry Andrictypename enable_if
23670b57cec5SDimitry Andric<
23680b57cec5SDimitry Andric    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
23690b57cec5SDimitry Andric    _Tp
23700b57cec5SDimitry Andric>::type
2371e8d8bef9SDimitry Andricatomic_fetch_and(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
23720b57cec5SDimitry Andric{
23730b57cec5SDimitry Andric    return __o->fetch_and(__op);
23740b57cec5SDimitry Andric}
23750b57cec5SDimitry Andric
23760b57cec5SDimitry Andrictemplate <class _Tp>
23770b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
23780b57cec5SDimitry Andrictypename enable_if
23790b57cec5SDimitry Andric<
23800b57cec5SDimitry Andric    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
23810b57cec5SDimitry Andric    _Tp
23820b57cec5SDimitry Andric>::type
2383e8d8bef9SDimitry Andricatomic_fetch_and(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
23840b57cec5SDimitry Andric{
23850b57cec5SDimitry Andric    return __o->fetch_and(__op);
23860b57cec5SDimitry Andric}
23870b57cec5SDimitry Andric
23880b57cec5SDimitry Andric// atomic_fetch_and_explicit
23890b57cec5SDimitry Andric
23900b57cec5SDimitry Andrictemplate <class _Tp>
23910b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
23920b57cec5SDimitry Andrictypename enable_if
23930b57cec5SDimitry Andric<
23940b57cec5SDimitry Andric    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
23950b57cec5SDimitry Andric    _Tp
23960b57cec5SDimitry Andric>::type
2397e8d8bef9SDimitry Andricatomic_fetch_and_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
23980b57cec5SDimitry Andric{
23990b57cec5SDimitry Andric    return __o->fetch_and(__op, __m);
24000b57cec5SDimitry Andric}
24010b57cec5SDimitry Andric
24020b57cec5SDimitry Andrictemplate <class _Tp>
24030b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
24040b57cec5SDimitry Andrictypename enable_if
24050b57cec5SDimitry Andric<
24060b57cec5SDimitry Andric    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
24070b57cec5SDimitry Andric    _Tp
24080b57cec5SDimitry Andric>::type
2409e8d8bef9SDimitry Andricatomic_fetch_and_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
24100b57cec5SDimitry Andric{
24110b57cec5SDimitry Andric    return __o->fetch_and(__op, __m);
24120b57cec5SDimitry Andric}
24130b57cec5SDimitry Andric
24140b57cec5SDimitry Andric// atomic_fetch_or
24150b57cec5SDimitry Andric
24160b57cec5SDimitry Andrictemplate <class _Tp>
24170b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
24180b57cec5SDimitry Andrictypename enable_if
24190b57cec5SDimitry Andric<
24200b57cec5SDimitry Andric    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
24210b57cec5SDimitry Andric    _Tp
24220b57cec5SDimitry Andric>::type
2423e8d8bef9SDimitry Andricatomic_fetch_or(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
24240b57cec5SDimitry Andric{
24250b57cec5SDimitry Andric    return __o->fetch_or(__op);
24260b57cec5SDimitry Andric}
24270b57cec5SDimitry Andric
24280b57cec5SDimitry Andrictemplate <class _Tp>
24290b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
24300b57cec5SDimitry Andrictypename enable_if
24310b57cec5SDimitry Andric<
24320b57cec5SDimitry Andric    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
24330b57cec5SDimitry Andric    _Tp
24340b57cec5SDimitry Andric>::type
2435e8d8bef9SDimitry Andricatomic_fetch_or(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
24360b57cec5SDimitry Andric{
24370b57cec5SDimitry Andric    return __o->fetch_or(__op);
24380b57cec5SDimitry Andric}
24390b57cec5SDimitry Andric
24400b57cec5SDimitry Andric// atomic_fetch_or_explicit
24410b57cec5SDimitry Andric
24420b57cec5SDimitry Andrictemplate <class _Tp>
24430b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
24440b57cec5SDimitry Andrictypename enable_if
24450b57cec5SDimitry Andric<
24460b57cec5SDimitry Andric    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
24470b57cec5SDimitry Andric    _Tp
24480b57cec5SDimitry Andric>::type
2449e8d8bef9SDimitry Andricatomic_fetch_or_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
24500b57cec5SDimitry Andric{
24510b57cec5SDimitry Andric    return __o->fetch_or(__op, __m);
24520b57cec5SDimitry Andric}
24530b57cec5SDimitry Andric
24540b57cec5SDimitry Andrictemplate <class _Tp>
24550b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
24560b57cec5SDimitry Andrictypename enable_if
24570b57cec5SDimitry Andric<
24580b57cec5SDimitry Andric    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
24590b57cec5SDimitry Andric    _Tp
24600b57cec5SDimitry Andric>::type
2461e8d8bef9SDimitry Andricatomic_fetch_or_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
24620b57cec5SDimitry Andric{
24630b57cec5SDimitry Andric    return __o->fetch_or(__op, __m);
24640b57cec5SDimitry Andric}
24650b57cec5SDimitry Andric
24660b57cec5SDimitry Andric// atomic_fetch_xor
24670b57cec5SDimitry Andric
24680b57cec5SDimitry Andrictemplate <class _Tp>
24690b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
24700b57cec5SDimitry Andrictypename enable_if
24710b57cec5SDimitry Andric<
24720b57cec5SDimitry Andric    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
24730b57cec5SDimitry Andric    _Tp
24740b57cec5SDimitry Andric>::type
2475e8d8bef9SDimitry Andricatomic_fetch_xor(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
24760b57cec5SDimitry Andric{
24770b57cec5SDimitry Andric    return __o->fetch_xor(__op);
24780b57cec5SDimitry Andric}
24790b57cec5SDimitry Andric
24800b57cec5SDimitry Andrictemplate <class _Tp>
24810b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
24820b57cec5SDimitry Andrictypename enable_if
24830b57cec5SDimitry Andric<
24840b57cec5SDimitry Andric    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
24850b57cec5SDimitry Andric    _Tp
24860b57cec5SDimitry Andric>::type
2487e8d8bef9SDimitry Andricatomic_fetch_xor(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
24880b57cec5SDimitry Andric{
24890b57cec5SDimitry Andric    return __o->fetch_xor(__op);
24900b57cec5SDimitry Andric}
24910b57cec5SDimitry Andric
24920b57cec5SDimitry Andric// atomic_fetch_xor_explicit
24930b57cec5SDimitry Andric
24940b57cec5SDimitry Andrictemplate <class _Tp>
24950b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
24960b57cec5SDimitry Andrictypename enable_if
24970b57cec5SDimitry Andric<
24980b57cec5SDimitry Andric    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
24990b57cec5SDimitry Andric    _Tp
25000b57cec5SDimitry Andric>::type
2501e8d8bef9SDimitry Andricatomic_fetch_xor_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
25020b57cec5SDimitry Andric{
25030b57cec5SDimitry Andric    return __o->fetch_xor(__op, __m);
25040b57cec5SDimitry Andric}
25050b57cec5SDimitry Andric
25060b57cec5SDimitry Andrictemplate <class _Tp>
25070b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
25080b57cec5SDimitry Andrictypename enable_if
25090b57cec5SDimitry Andric<
25100b57cec5SDimitry Andric    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
25110b57cec5SDimitry Andric    _Tp
25120b57cec5SDimitry Andric>::type
2513e8d8bef9SDimitry Andricatomic_fetch_xor_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
25140b57cec5SDimitry Andric{
25150b57cec5SDimitry Andric    return __o->fetch_xor(__op, __m);
25160b57cec5SDimitry Andric}
25170b57cec5SDimitry Andric
25180b57cec5SDimitry Andric// flag type and operations
25190b57cec5SDimitry Andric
25200b57cec5SDimitry Andrictypedef struct atomic_flag
25210b57cec5SDimitry Andric{
25220b57cec5SDimitry Andric    __cxx_atomic_impl<_LIBCPP_ATOMIC_FLAG_TYPE> __a_;
25230b57cec5SDimitry Andric
25240b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
25255ffd83dbSDimitry Andric    bool test(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
25265ffd83dbSDimitry Andric        {return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m);}
25275ffd83dbSDimitry Andric    _LIBCPP_INLINE_VISIBILITY
25285ffd83dbSDimitry Andric    bool test(memory_order __m = memory_order_seq_cst) const _NOEXCEPT
25295ffd83dbSDimitry Andric        {return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m);}
25305ffd83dbSDimitry Andric
25315ffd83dbSDimitry Andric    _LIBCPP_INLINE_VISIBILITY
25320b57cec5SDimitry Andric    bool test_and_set(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
25330b57cec5SDimitry Andric        {return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);}
25340b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
25350b57cec5SDimitry Andric    bool test_and_set(memory_order __m = memory_order_seq_cst) _NOEXCEPT
25360b57cec5SDimitry Andric        {return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);}
25370b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
25380b57cec5SDimitry Andric    void clear(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
25390b57cec5SDimitry Andric        {__cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);}
25400b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
25410b57cec5SDimitry Andric    void clear(memory_order __m = memory_order_seq_cst) _NOEXCEPT
25420b57cec5SDimitry Andric        {__cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);}
25430b57cec5SDimitry Andric
25445ffd83dbSDimitry Andric    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
25455ffd83dbSDimitry Andric    void wait(bool __v, memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
25465ffd83dbSDimitry Andric        {__cxx_atomic_wait(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);}
25475ffd83dbSDimitry Andric    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
25485ffd83dbSDimitry Andric    void wait(bool __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT
25495ffd83dbSDimitry Andric        {__cxx_atomic_wait(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);}
25505ffd83dbSDimitry Andric    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
25515ffd83dbSDimitry Andric    void notify_one() volatile _NOEXCEPT
25525ffd83dbSDimitry Andric        {__cxx_atomic_notify_one(&__a_);}
25535ffd83dbSDimitry Andric    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
25545ffd83dbSDimitry Andric    void notify_one() _NOEXCEPT
25555ffd83dbSDimitry Andric        {__cxx_atomic_notify_one(&__a_);}
25565ffd83dbSDimitry Andric    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
25575ffd83dbSDimitry Andric    void notify_all() volatile _NOEXCEPT
25585ffd83dbSDimitry Andric        {__cxx_atomic_notify_all(&__a_);}
25595ffd83dbSDimitry Andric    _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
25605ffd83dbSDimitry Andric    void notify_all() _NOEXCEPT
25615ffd83dbSDimitry Andric        {__cxx_atomic_notify_all(&__a_);}
25625ffd83dbSDimitry Andric
2563*fe6060f1SDimitry Andric#if _LIBCPP_STD_VER > 17
2564*fe6060f1SDimitry Andric    _LIBCPP_INLINE_VISIBILITY constexpr
2565*fe6060f1SDimitry Andric    atomic_flag() _NOEXCEPT : __a_(false) {}
2566*fe6060f1SDimitry Andric#else
25670b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
25680b57cec5SDimitry Andric    atomic_flag() _NOEXCEPT _LIBCPP_DEFAULT
2569*fe6060f1SDimitry Andric#endif
25700b57cec5SDimitry Andric
25710b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
25720b57cec5SDimitry Andric    atomic_flag(bool __b) _NOEXCEPT : __a_(__b) {} // EXTENSION
25730b57cec5SDimitry Andric
25740b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
25750b57cec5SDimitry Andric    atomic_flag(const atomic_flag&) = delete;
25760b57cec5SDimitry Andric    atomic_flag& operator=(const atomic_flag&) = delete;
25770b57cec5SDimitry Andric    atomic_flag& operator=(const atomic_flag&) volatile = delete;
25780b57cec5SDimitry Andric#else
25790b57cec5SDimitry Andricprivate:
25805ffd83dbSDimitry Andric    _LIBCPP_INLINE_VISIBILITY
25810b57cec5SDimitry Andric    atomic_flag(const atomic_flag&);
25825ffd83dbSDimitry Andric    _LIBCPP_INLINE_VISIBILITY
25830b57cec5SDimitry Andric    atomic_flag& operator=(const atomic_flag&);
25845ffd83dbSDimitry Andric    _LIBCPP_INLINE_VISIBILITY
25850b57cec5SDimitry Andric    atomic_flag& operator=(const atomic_flag&) volatile;
25860b57cec5SDimitry Andric#endif
25870b57cec5SDimitry Andric} atomic_flag;
25880b57cec5SDimitry Andric
25895ffd83dbSDimitry Andric
25905ffd83dbSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
25915ffd83dbSDimitry Andricbool
25925ffd83dbSDimitry Andricatomic_flag_test(const volatile atomic_flag* __o) _NOEXCEPT
25935ffd83dbSDimitry Andric{
25945ffd83dbSDimitry Andric    return __o->test();
25955ffd83dbSDimitry Andric}
25965ffd83dbSDimitry Andric
25975ffd83dbSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
25985ffd83dbSDimitry Andricbool
25995ffd83dbSDimitry Andricatomic_flag_test(const atomic_flag* __o) _NOEXCEPT
26005ffd83dbSDimitry Andric{
26015ffd83dbSDimitry Andric    return __o->test();
26025ffd83dbSDimitry Andric}
26035ffd83dbSDimitry Andric
26045ffd83dbSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
26055ffd83dbSDimitry Andricbool
26065ffd83dbSDimitry Andricatomic_flag_test_explicit(const volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
26075ffd83dbSDimitry Andric{
26085ffd83dbSDimitry Andric    return __o->test(__m);
26095ffd83dbSDimitry Andric}
26105ffd83dbSDimitry Andric
26115ffd83dbSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
26125ffd83dbSDimitry Andricbool
26135ffd83dbSDimitry Andricatomic_flag_test_explicit(const atomic_flag* __o, memory_order __m) _NOEXCEPT
26145ffd83dbSDimitry Andric{
26155ffd83dbSDimitry Andric    return __o->test(__m);
26165ffd83dbSDimitry Andric}
26175ffd83dbSDimitry Andric
26180b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
26190b57cec5SDimitry Andricbool
26200b57cec5SDimitry Andricatomic_flag_test_and_set(volatile atomic_flag* __o) _NOEXCEPT
26210b57cec5SDimitry Andric{
26220b57cec5SDimitry Andric    return __o->test_and_set();
26230b57cec5SDimitry Andric}
26240b57cec5SDimitry Andric
26250b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
26260b57cec5SDimitry Andricbool
26270b57cec5SDimitry Andricatomic_flag_test_and_set(atomic_flag* __o) _NOEXCEPT
26280b57cec5SDimitry Andric{
26290b57cec5SDimitry Andric    return __o->test_and_set();
26300b57cec5SDimitry Andric}
26310b57cec5SDimitry Andric
26320b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
26330b57cec5SDimitry Andricbool
26340b57cec5SDimitry Andricatomic_flag_test_and_set_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
26350b57cec5SDimitry Andric{
26360b57cec5SDimitry Andric    return __o->test_and_set(__m);
26370b57cec5SDimitry Andric}
26380b57cec5SDimitry Andric
26390b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
26400b57cec5SDimitry Andricbool
26410b57cec5SDimitry Andricatomic_flag_test_and_set_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT
26420b57cec5SDimitry Andric{
26430b57cec5SDimitry Andric    return __o->test_and_set(__m);
26440b57cec5SDimitry Andric}
26450b57cec5SDimitry Andric
26460b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
26470b57cec5SDimitry Andricvoid
26480b57cec5SDimitry Andricatomic_flag_clear(volatile atomic_flag* __o) _NOEXCEPT
26490b57cec5SDimitry Andric{
26500b57cec5SDimitry Andric    __o->clear();
26510b57cec5SDimitry Andric}
26520b57cec5SDimitry Andric
26530b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
26540b57cec5SDimitry Andricvoid
26550b57cec5SDimitry Andricatomic_flag_clear(atomic_flag* __o) _NOEXCEPT
26560b57cec5SDimitry Andric{
26570b57cec5SDimitry Andric    __o->clear();
26580b57cec5SDimitry Andric}
26590b57cec5SDimitry Andric
26600b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
26610b57cec5SDimitry Andricvoid
26620b57cec5SDimitry Andricatomic_flag_clear_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
26630b57cec5SDimitry Andric{
26640b57cec5SDimitry Andric    __o->clear(__m);
26650b57cec5SDimitry Andric}
26660b57cec5SDimitry Andric
26670b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
26680b57cec5SDimitry Andricvoid
26690b57cec5SDimitry Andricatomic_flag_clear_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT
26700b57cec5SDimitry Andric{
26710b57cec5SDimitry Andric    __o->clear(__m);
26720b57cec5SDimitry Andric}
26730b57cec5SDimitry Andric
26745ffd83dbSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
26755ffd83dbSDimitry Andricvoid
26765ffd83dbSDimitry Andricatomic_flag_wait(const volatile atomic_flag* __o, bool __v) _NOEXCEPT
26775ffd83dbSDimitry Andric{
26785ffd83dbSDimitry Andric    __o->wait(__v);
26795ffd83dbSDimitry Andric}
26805ffd83dbSDimitry Andric
26815ffd83dbSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
26825ffd83dbSDimitry Andricvoid
26835ffd83dbSDimitry Andricatomic_flag_wait(const atomic_flag* __o, bool __v) _NOEXCEPT
26845ffd83dbSDimitry Andric{
26855ffd83dbSDimitry Andric    __o->wait(__v);
26865ffd83dbSDimitry Andric}
26875ffd83dbSDimitry Andric
26885ffd83dbSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
26895ffd83dbSDimitry Andricvoid
26905ffd83dbSDimitry Andricatomic_flag_wait_explicit(const volatile atomic_flag* __o,
26915ffd83dbSDimitry Andric                          bool __v, memory_order __m) _NOEXCEPT
26925ffd83dbSDimitry Andric{
26935ffd83dbSDimitry Andric    __o->wait(__v, __m);
26945ffd83dbSDimitry Andric}
26955ffd83dbSDimitry Andric
26965ffd83dbSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
26975ffd83dbSDimitry Andricvoid
26985ffd83dbSDimitry Andricatomic_flag_wait_explicit(const atomic_flag* __o,
26995ffd83dbSDimitry Andric                          bool __v, memory_order __m) _NOEXCEPT
27005ffd83dbSDimitry Andric{
27015ffd83dbSDimitry Andric    __o->wait(__v, __m);
27025ffd83dbSDimitry Andric}
27035ffd83dbSDimitry Andric
27045ffd83dbSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
27055ffd83dbSDimitry Andricvoid
27065ffd83dbSDimitry Andricatomic_flag_notify_one(volatile atomic_flag* __o) _NOEXCEPT
27075ffd83dbSDimitry Andric{
27085ffd83dbSDimitry Andric    __o->notify_one();
27095ffd83dbSDimitry Andric}
27105ffd83dbSDimitry Andric
27115ffd83dbSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
27125ffd83dbSDimitry Andricvoid
27135ffd83dbSDimitry Andricatomic_flag_notify_one(atomic_flag* __o) _NOEXCEPT
27145ffd83dbSDimitry Andric{
27155ffd83dbSDimitry Andric    __o->notify_one();
27165ffd83dbSDimitry Andric}
27175ffd83dbSDimitry Andric
27185ffd83dbSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
27195ffd83dbSDimitry Andricvoid
27205ffd83dbSDimitry Andricatomic_flag_notify_all(volatile atomic_flag* __o) _NOEXCEPT
27215ffd83dbSDimitry Andric{
27225ffd83dbSDimitry Andric    __o->notify_all();
27235ffd83dbSDimitry Andric}
27245ffd83dbSDimitry Andric
27255ffd83dbSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC
27265ffd83dbSDimitry Andricvoid
27275ffd83dbSDimitry Andricatomic_flag_notify_all(atomic_flag* __o) _NOEXCEPT
27285ffd83dbSDimitry Andric{
27295ffd83dbSDimitry Andric    __o->notify_all();
27305ffd83dbSDimitry Andric}
27315ffd83dbSDimitry Andric
27320b57cec5SDimitry Andric// fences
27330b57cec5SDimitry Andric
27340b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
27350b57cec5SDimitry Andricvoid
27360b57cec5SDimitry Andricatomic_thread_fence(memory_order __m) _NOEXCEPT
27370b57cec5SDimitry Andric{
27380b57cec5SDimitry Andric    __cxx_atomic_thread_fence(__m);
27390b57cec5SDimitry Andric}
27400b57cec5SDimitry Andric
27410b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
27420b57cec5SDimitry Andricvoid
27430b57cec5SDimitry Andricatomic_signal_fence(memory_order __m) _NOEXCEPT
27440b57cec5SDimitry Andric{
27450b57cec5SDimitry Andric    __cxx_atomic_signal_fence(__m);
27460b57cec5SDimitry Andric}
27470b57cec5SDimitry Andric
27480b57cec5SDimitry Andric// Atomics for standard typedef types
27490b57cec5SDimitry Andric
27500b57cec5SDimitry Andrictypedef atomic<bool>               atomic_bool;
27510b57cec5SDimitry Andrictypedef atomic<char>               atomic_char;
27520b57cec5SDimitry Andrictypedef atomic<signed char>        atomic_schar;
27530b57cec5SDimitry Andrictypedef atomic<unsigned char>      atomic_uchar;
27540b57cec5SDimitry Andrictypedef atomic<short>              atomic_short;
27550b57cec5SDimitry Andrictypedef atomic<unsigned short>     atomic_ushort;
27560b57cec5SDimitry Andrictypedef atomic<int>                atomic_int;
27570b57cec5SDimitry Andrictypedef atomic<unsigned int>       atomic_uint;
27580b57cec5SDimitry Andrictypedef atomic<long>               atomic_long;
27590b57cec5SDimitry Andrictypedef atomic<unsigned long>      atomic_ulong;
27600b57cec5SDimitry Andrictypedef atomic<long long>          atomic_llong;
27610b57cec5SDimitry Andrictypedef atomic<unsigned long long> atomic_ullong;
2762*fe6060f1SDimitry Andric#ifndef _LIBCPP_HAS_NO_CHAR8_T
2763e8d8bef9SDimitry Andrictypedef atomic<char8_t>            atomic_char8_t;
2764e8d8bef9SDimitry Andric#endif
27650b57cec5SDimitry Andrictypedef atomic<char16_t>           atomic_char16_t;
27660b57cec5SDimitry Andrictypedef atomic<char32_t>           atomic_char32_t;
27670b57cec5SDimitry Andrictypedef atomic<wchar_t>            atomic_wchar_t;
27680b57cec5SDimitry Andric
27690b57cec5SDimitry Andrictypedef atomic<int_least8_t>   atomic_int_least8_t;
27700b57cec5SDimitry Andrictypedef atomic<uint_least8_t>  atomic_uint_least8_t;
27710b57cec5SDimitry Andrictypedef atomic<int_least16_t>  atomic_int_least16_t;
27720b57cec5SDimitry Andrictypedef atomic<uint_least16_t> atomic_uint_least16_t;
27730b57cec5SDimitry Andrictypedef atomic<int_least32_t>  atomic_int_least32_t;
27740b57cec5SDimitry Andrictypedef atomic<uint_least32_t> atomic_uint_least32_t;
27750b57cec5SDimitry Andrictypedef atomic<int_least64_t>  atomic_int_least64_t;
27760b57cec5SDimitry Andrictypedef atomic<uint_least64_t> atomic_uint_least64_t;
27770b57cec5SDimitry Andric
27780b57cec5SDimitry Andrictypedef atomic<int_fast8_t>   atomic_int_fast8_t;
27790b57cec5SDimitry Andrictypedef atomic<uint_fast8_t>  atomic_uint_fast8_t;
27800b57cec5SDimitry Andrictypedef atomic<int_fast16_t>  atomic_int_fast16_t;
27810b57cec5SDimitry Andrictypedef atomic<uint_fast16_t> atomic_uint_fast16_t;
27820b57cec5SDimitry Andrictypedef atomic<int_fast32_t>  atomic_int_fast32_t;
27830b57cec5SDimitry Andrictypedef atomic<uint_fast32_t> atomic_uint_fast32_t;
27840b57cec5SDimitry Andrictypedef atomic<int_fast64_t>  atomic_int_fast64_t;
27850b57cec5SDimitry Andrictypedef atomic<uint_fast64_t> atomic_uint_fast64_t;
27860b57cec5SDimitry Andric
27870b57cec5SDimitry Andrictypedef atomic< int8_t>  atomic_int8_t;
27880b57cec5SDimitry Andrictypedef atomic<uint8_t>  atomic_uint8_t;
27890b57cec5SDimitry Andrictypedef atomic< int16_t> atomic_int16_t;
27900b57cec5SDimitry Andrictypedef atomic<uint16_t> atomic_uint16_t;
27910b57cec5SDimitry Andrictypedef atomic< int32_t> atomic_int32_t;
27920b57cec5SDimitry Andrictypedef atomic<uint32_t> atomic_uint32_t;
27930b57cec5SDimitry Andrictypedef atomic< int64_t> atomic_int64_t;
27940b57cec5SDimitry Andrictypedef atomic<uint64_t> atomic_uint64_t;
27950b57cec5SDimitry Andric
27960b57cec5SDimitry Andrictypedef atomic<intptr_t>  atomic_intptr_t;
27970b57cec5SDimitry Andrictypedef atomic<uintptr_t> atomic_uintptr_t;
27980b57cec5SDimitry Andrictypedef atomic<size_t>    atomic_size_t;
27990b57cec5SDimitry Andrictypedef atomic<ptrdiff_t> atomic_ptrdiff_t;
28000b57cec5SDimitry Andrictypedef atomic<intmax_t>  atomic_intmax_t;
28010b57cec5SDimitry Andrictypedef atomic<uintmax_t> atomic_uintmax_t;
28020b57cec5SDimitry Andric
28035ffd83dbSDimitry Andric// atomic_*_lock_free : prefer the contention type most highly, then the largest lock-free type
28045ffd83dbSDimitry Andric
28055ffd83dbSDimitry Andric#ifdef __cpp_lib_atomic_is_always_lock_free
28065ffd83dbSDimitry Andric# define _LIBCPP_CONTENTION_LOCK_FREE __atomic_always_lock_free(sizeof(__cxx_contention_t), 0)
28075ffd83dbSDimitry Andric#else
28085ffd83dbSDimitry Andric# define _LIBCPP_CONTENTION_LOCK_FREE false
28095ffd83dbSDimitry Andric#endif
28105ffd83dbSDimitry Andric
28115ffd83dbSDimitry Andric#if ATOMIC_LLONG_LOCK_FREE == 2
28125ffd83dbSDimitry Andrictypedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, long long>::type          __libcpp_signed_lock_free;
28135ffd83dbSDimitry Andrictypedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned long long>::type __libcpp_unsigned_lock_free;
28145ffd83dbSDimitry Andric#elif ATOMIC_INT_LOCK_FREE == 2
28155ffd83dbSDimitry Andrictypedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, int>::type                __libcpp_signed_lock_free;
28165ffd83dbSDimitry Andrictypedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned int>::type       __libcpp_unsigned_lock_free;
28175ffd83dbSDimitry Andric#elif ATOMIC_SHORT_LOCK_FREE == 2
28185ffd83dbSDimitry Andrictypedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, short>::type              __libcpp_signed_lock_free;
28195ffd83dbSDimitry Andrictypedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned short>::type     __libcpp_unsigned_lock_free;
28205ffd83dbSDimitry Andric#elif ATOMIC_CHAR_LOCK_FREE == 2
28215ffd83dbSDimitry Andrictypedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, char>::type               __libcpp_signed_lock_free;
28225ffd83dbSDimitry Andrictypedef conditional<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned char>::type      __libcpp_unsigned_lock_free;
28235ffd83dbSDimitry Andric#else
28245ffd83dbSDimitry Andric    // No signed/unsigned lock-free types
28255ffd83dbSDimitry Andric#endif
28265ffd83dbSDimitry Andric
28275ffd83dbSDimitry Andrictypedef atomic<__libcpp_signed_lock_free> atomic_signed_lock_free;
28285ffd83dbSDimitry Andrictypedef atomic<__libcpp_unsigned_lock_free> atomic_unsigned_lock_free;
28295ffd83dbSDimitry Andric
28300b57cec5SDimitry Andric#define ATOMIC_FLAG_INIT {false}
28310b57cec5SDimitry Andric#define ATOMIC_VAR_INIT(__v) {__v}
28320b57cec5SDimitry Andric
28330b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_STD
28340b57cec5SDimitry Andric
28350b57cec5SDimitry Andric#endif // _LIBCPP_ATOMIC
2836