146035553Spatrick// -*- C++ -*- 2*4bdff4beSrobert//===----------------------------------------------------------------------===// 346035553Spatrick// 446035553Spatrick// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 546035553Spatrick// See https://llvm.org/LICENSE.txt for license information. 646035553Spatrick// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 746035553Spatrick// 846035553Spatrick//===----------------------------------------------------------------------===// 946035553Spatrick 1046035553Spatrick#ifndef _LIBCPP_ATOMIC 1146035553Spatrick#define _LIBCPP_ATOMIC 1246035553Spatrick 1346035553Spatrick/* 1446035553Spatrick atomic synopsis 1546035553Spatrick 1646035553Spatricknamespace std 1746035553Spatrick{ 1846035553Spatrick 1976d0caaeSpatrick// feature test macro [version.syn] 2046035553Spatrick 2176d0caaeSpatrick#define __cpp_lib_atomic_is_always_lock_free 2276d0caaeSpatrick#define __cpp_lib_atomic_flag_test 2376d0caaeSpatrick#define __cpp_lib_atomic_lock_free_type_aliases 2476d0caaeSpatrick#define __cpp_lib_atomic_wait 2546035553Spatrick 2646035553Spatrick // order and consistency 2746035553Spatrick 2846035553Spatrick enum memory_order: unspecified // enum class in C++20 2946035553Spatrick { 3046035553Spatrick relaxed, 3146035553Spatrick consume, // load-consume 3246035553Spatrick acquire, // load-acquire 3346035553Spatrick release, // store-release 3446035553Spatrick acq_rel, // store-release load-acquire 3546035553Spatrick seq_cst // store-release load-acquire 3646035553Spatrick }; 3746035553Spatrick 3846035553Spatrick inline constexpr auto memory_order_relaxed = memory_order::relaxed; 3946035553Spatrick inline constexpr auto memory_order_consume = memory_order::consume; 4046035553Spatrick inline constexpr auto memory_order_acquire = memory_order::acquire; 4146035553Spatrick inline constexpr auto memory_order_release = memory_order::release; 4246035553Spatrick inline constexpr auto memory_order_acq_rel = memory_order::acq_rel; 4346035553Spatrick inline constexpr auto memory_order_seq_cst = memory_order::seq_cst; 4446035553Spatrick 4546035553Spatricktemplate <class T> T kill_dependency(T y) noexcept; 4646035553Spatrick 4746035553Spatrick// lock-free property 4846035553Spatrick 4946035553Spatrick#define ATOMIC_BOOL_LOCK_FREE unspecified 5046035553Spatrick#define ATOMIC_CHAR_LOCK_FREE unspecified 5176d0caaeSpatrick#define ATOMIC_CHAR8_T_LOCK_FREE unspecified // C++20 5246035553Spatrick#define ATOMIC_CHAR16_T_LOCK_FREE unspecified 5346035553Spatrick#define ATOMIC_CHAR32_T_LOCK_FREE unspecified 5446035553Spatrick#define ATOMIC_WCHAR_T_LOCK_FREE unspecified 5546035553Spatrick#define ATOMIC_SHORT_LOCK_FREE unspecified 5646035553Spatrick#define ATOMIC_INT_LOCK_FREE unspecified 5746035553Spatrick#define ATOMIC_LONG_LOCK_FREE unspecified 5846035553Spatrick#define ATOMIC_LLONG_LOCK_FREE unspecified 5946035553Spatrick#define ATOMIC_POINTER_LOCK_FREE unspecified 6046035553Spatrick 6146035553Spatricktemplate <class T> 6246035553Spatrickstruct atomic 6346035553Spatrick{ 64037e7968Spatrick using value_type = T; 65037e7968Spatrick 6646035553Spatrick static constexpr bool is_always_lock_free; 6746035553Spatrick bool is_lock_free() const volatile noexcept; 6846035553Spatrick bool is_lock_free() const noexcept; 69037e7968Spatrick 7076d0caaeSpatrick atomic() noexcept = default; // until C++20 7176d0caaeSpatrick constexpr atomic() noexcept(is_nothrow_default_constructible_v<T>); // since C++20 72037e7968Spatrick constexpr atomic(T desr) noexcept; 73037e7968Spatrick atomic(const atomic&) = delete; 74037e7968Spatrick atomic& operator=(const atomic&) = delete; 75037e7968Spatrick atomic& operator=(const atomic&) volatile = delete; 76037e7968Spatrick 7746035553Spatrick T load(memory_order m = memory_order_seq_cst) const volatile noexcept; 7846035553Spatrick T load(memory_order m = memory_order_seq_cst) const noexcept; 7946035553Spatrick operator T() const volatile noexcept; 8046035553Spatrick operator T() const noexcept; 81037e7968Spatrick void store(T desr, memory_order m = memory_order_seq_cst) volatile noexcept; 82037e7968Spatrick void store(T desr, memory_order m = memory_order_seq_cst) noexcept; 83037e7968Spatrick T operator=(T) volatile noexcept; 84037e7968Spatrick T operator=(T) noexcept; 85037e7968Spatrick 8646035553Spatrick T exchange(T desr, memory_order m = memory_order_seq_cst) volatile noexcept; 8746035553Spatrick T exchange(T desr, memory_order m = memory_order_seq_cst) noexcept; 8846035553Spatrick bool compare_exchange_weak(T& expc, T desr, 8946035553Spatrick memory_order s, memory_order f) volatile noexcept; 9046035553Spatrick bool compare_exchange_weak(T& expc, T desr, memory_order s, memory_order f) noexcept; 9146035553Spatrick bool compare_exchange_strong(T& expc, T desr, 9246035553Spatrick memory_order s, memory_order f) volatile noexcept; 9346035553Spatrick bool compare_exchange_strong(T& expc, T desr, 9446035553Spatrick memory_order s, memory_order f) noexcept; 9546035553Spatrick bool compare_exchange_weak(T& expc, T desr, 9646035553Spatrick memory_order m = memory_order_seq_cst) volatile noexcept; 9746035553Spatrick bool compare_exchange_weak(T& expc, T desr, 9846035553Spatrick memory_order m = memory_order_seq_cst) noexcept; 9946035553Spatrick bool compare_exchange_strong(T& expc, T desr, 10046035553Spatrick memory_order m = memory_order_seq_cst) volatile noexcept; 10146035553Spatrick bool compare_exchange_strong(T& expc, T desr, 10246035553Spatrick memory_order m = memory_order_seq_cst) noexcept; 10346035553Spatrick 104037e7968Spatrick void wait(T, memory_order = memory_order::seq_cst) const volatile noexcept; 105037e7968Spatrick void wait(T, memory_order = memory_order::seq_cst) const noexcept; 106037e7968Spatrick void notify_one() volatile noexcept; 107037e7968Spatrick void notify_one() noexcept; 108037e7968Spatrick void notify_all() volatile noexcept; 109037e7968Spatrick void notify_all() noexcept; 11046035553Spatrick}; 11146035553Spatrick 11246035553Spatricktemplate <> 11346035553Spatrickstruct atomic<integral> 11446035553Spatrick{ 115037e7968Spatrick using value_type = integral; 11676d0caaeSpatrick using difference_type = value_type; 117037e7968Spatrick 11846035553Spatrick static constexpr bool is_always_lock_free; 11946035553Spatrick bool is_lock_free() const volatile noexcept; 12046035553Spatrick bool is_lock_free() const noexcept; 121037e7968Spatrick 122037e7968Spatrick atomic() noexcept = default; 123037e7968Spatrick constexpr atomic(integral desr) noexcept; 124037e7968Spatrick atomic(const atomic&) = delete; 125037e7968Spatrick atomic& operator=(const atomic&) = delete; 126037e7968Spatrick atomic& operator=(const atomic&) volatile = delete; 127037e7968Spatrick 12846035553Spatrick integral load(memory_order m = memory_order_seq_cst) const volatile noexcept; 12946035553Spatrick integral load(memory_order m = memory_order_seq_cst) const noexcept; 13046035553Spatrick operator integral() const volatile noexcept; 13146035553Spatrick operator integral() const noexcept; 132037e7968Spatrick void store(integral desr, memory_order m = memory_order_seq_cst) volatile noexcept; 133037e7968Spatrick void store(integral desr, memory_order m = memory_order_seq_cst) noexcept; 134037e7968Spatrick integral operator=(integral desr) volatile noexcept; 135037e7968Spatrick integral operator=(integral desr) noexcept; 136037e7968Spatrick 13746035553Spatrick integral exchange(integral desr, 13846035553Spatrick memory_order m = memory_order_seq_cst) volatile noexcept; 13946035553Spatrick integral exchange(integral desr, memory_order m = memory_order_seq_cst) noexcept; 14046035553Spatrick bool compare_exchange_weak(integral& expc, integral desr, 14146035553Spatrick memory_order s, memory_order f) volatile noexcept; 14246035553Spatrick bool compare_exchange_weak(integral& expc, integral desr, 14346035553Spatrick memory_order s, memory_order f) noexcept; 14446035553Spatrick bool compare_exchange_strong(integral& expc, integral desr, 14546035553Spatrick memory_order s, memory_order f) volatile noexcept; 14646035553Spatrick bool compare_exchange_strong(integral& expc, integral desr, 14746035553Spatrick memory_order s, memory_order f) noexcept; 14846035553Spatrick bool compare_exchange_weak(integral& expc, integral desr, 14946035553Spatrick memory_order m = memory_order_seq_cst) volatile noexcept; 15046035553Spatrick bool compare_exchange_weak(integral& expc, integral desr, 15146035553Spatrick memory_order m = memory_order_seq_cst) noexcept; 15246035553Spatrick bool compare_exchange_strong(integral& expc, integral desr, 15346035553Spatrick memory_order m = memory_order_seq_cst) volatile noexcept; 15446035553Spatrick bool compare_exchange_strong(integral& expc, integral desr, 15546035553Spatrick memory_order m = memory_order_seq_cst) noexcept; 15646035553Spatrick 157037e7968Spatrick integral fetch_add(integral op, memory_order m = memory_order_seq_cst) volatile noexcept; 15846035553Spatrick integral fetch_add(integral op, memory_order m = memory_order_seq_cst) noexcept; 159037e7968Spatrick integral fetch_sub(integral op, memory_order m = memory_order_seq_cst) volatile noexcept; 16046035553Spatrick integral fetch_sub(integral op, memory_order m = memory_order_seq_cst) noexcept; 161037e7968Spatrick integral fetch_and(integral op, memory_order m = memory_order_seq_cst) volatile noexcept; 16246035553Spatrick integral fetch_and(integral op, memory_order m = memory_order_seq_cst) noexcept; 163037e7968Spatrick integral fetch_or(integral op, memory_order m = memory_order_seq_cst) volatile noexcept; 16446035553Spatrick integral fetch_or(integral op, memory_order m = memory_order_seq_cst) noexcept; 165037e7968Spatrick integral fetch_xor(integral op, memory_order m = memory_order_seq_cst) volatile noexcept; 16646035553Spatrick integral fetch_xor(integral op, memory_order m = memory_order_seq_cst) noexcept; 16746035553Spatrick 16846035553Spatrick integral operator++(int) volatile noexcept; 16946035553Spatrick integral operator++(int) noexcept; 17046035553Spatrick integral operator--(int) volatile noexcept; 17146035553Spatrick integral operator--(int) noexcept; 17246035553Spatrick integral operator++() volatile noexcept; 17346035553Spatrick integral operator++() noexcept; 17446035553Spatrick integral operator--() volatile noexcept; 17546035553Spatrick integral operator--() noexcept; 17646035553Spatrick integral operator+=(integral op) volatile noexcept; 17746035553Spatrick integral operator+=(integral op) noexcept; 17846035553Spatrick integral operator-=(integral op) volatile noexcept; 17946035553Spatrick integral operator-=(integral op) noexcept; 18046035553Spatrick integral operator&=(integral op) volatile noexcept; 18146035553Spatrick integral operator&=(integral op) noexcept; 18246035553Spatrick integral operator|=(integral op) volatile noexcept; 18346035553Spatrick integral operator|=(integral op) noexcept; 18446035553Spatrick integral operator^=(integral op) volatile noexcept; 18546035553Spatrick integral operator^=(integral op) noexcept; 186037e7968Spatrick 187037e7968Spatrick void wait(integral, memory_order = memory_order::seq_cst) const volatile noexcept; 188037e7968Spatrick void wait(integral, memory_order = memory_order::seq_cst) const noexcept; 189037e7968Spatrick void notify_one() volatile noexcept; 190037e7968Spatrick void notify_one() noexcept; 191037e7968Spatrick void notify_all() volatile noexcept; 192037e7968Spatrick void notify_all() noexcept; 19346035553Spatrick}; 19446035553Spatrick 19546035553Spatricktemplate <class T> 19646035553Spatrickstruct atomic<T*> 19746035553Spatrick{ 198037e7968Spatrick using value_type = T*; 19976d0caaeSpatrick using difference_type = ptrdiff_t; 200037e7968Spatrick 20146035553Spatrick static constexpr bool is_always_lock_free; 20246035553Spatrick bool is_lock_free() const volatile noexcept; 20346035553Spatrick bool is_lock_free() const noexcept; 204037e7968Spatrick 20576d0caaeSpatrick atomic() noexcept = default; // until C++20 20676d0caaeSpatrick constexpr atomic() noexcept; // since C++20 207037e7968Spatrick constexpr atomic(T* desr) noexcept; 208037e7968Spatrick atomic(const atomic&) = delete; 209037e7968Spatrick atomic& operator=(const atomic&) = delete; 210037e7968Spatrick atomic& operator=(const atomic&) volatile = delete; 211037e7968Spatrick 21246035553Spatrick T* load(memory_order m = memory_order_seq_cst) const volatile noexcept; 21346035553Spatrick T* load(memory_order m = memory_order_seq_cst) const noexcept; 21446035553Spatrick operator T*() const volatile noexcept; 21546035553Spatrick operator T*() const noexcept; 216037e7968Spatrick void store(T* desr, memory_order m = memory_order_seq_cst) volatile noexcept; 217037e7968Spatrick void store(T* desr, memory_order m = memory_order_seq_cst) noexcept; 218037e7968Spatrick T* operator=(T*) volatile noexcept; 219037e7968Spatrick T* operator=(T*) noexcept; 220037e7968Spatrick 22146035553Spatrick T* exchange(T* desr, memory_order m = memory_order_seq_cst) volatile noexcept; 22246035553Spatrick T* exchange(T* desr, memory_order m = memory_order_seq_cst) noexcept; 22346035553Spatrick bool compare_exchange_weak(T*& expc, T* desr, 22446035553Spatrick memory_order s, memory_order f) volatile noexcept; 22546035553Spatrick bool compare_exchange_weak(T*& expc, T* desr, 22646035553Spatrick memory_order s, memory_order f) noexcept; 22746035553Spatrick bool compare_exchange_strong(T*& expc, T* desr, 22846035553Spatrick memory_order s, memory_order f) volatile noexcept; 22946035553Spatrick bool compare_exchange_strong(T*& expc, T* desr, 23046035553Spatrick memory_order s, memory_order f) noexcept; 23146035553Spatrick bool compare_exchange_weak(T*& expc, T* desr, 23246035553Spatrick memory_order m = memory_order_seq_cst) volatile noexcept; 23346035553Spatrick bool compare_exchange_weak(T*& expc, T* desr, 23446035553Spatrick memory_order m = memory_order_seq_cst) noexcept; 23546035553Spatrick bool compare_exchange_strong(T*& expc, T* desr, 23646035553Spatrick memory_order m = memory_order_seq_cst) volatile noexcept; 23746035553Spatrick bool compare_exchange_strong(T*& expc, T* desr, 23846035553Spatrick memory_order m = memory_order_seq_cst) noexcept; 23946035553Spatrick T* fetch_add(ptrdiff_t op, memory_order m = memory_order_seq_cst) volatile noexcept; 24046035553Spatrick T* fetch_add(ptrdiff_t op, memory_order m = memory_order_seq_cst) noexcept; 24146035553Spatrick T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst) volatile noexcept; 24246035553Spatrick T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst) noexcept; 24346035553Spatrick 24446035553Spatrick T* operator++(int) volatile noexcept; 24546035553Spatrick T* operator++(int) noexcept; 24646035553Spatrick T* operator--(int) volatile noexcept; 24746035553Spatrick T* operator--(int) noexcept; 24846035553Spatrick T* operator++() volatile noexcept; 24946035553Spatrick T* operator++() noexcept; 25046035553Spatrick T* operator--() volatile noexcept; 25146035553Spatrick T* operator--() noexcept; 25246035553Spatrick T* operator+=(ptrdiff_t op) volatile noexcept; 25346035553Spatrick T* operator+=(ptrdiff_t op) noexcept; 25446035553Spatrick T* operator-=(ptrdiff_t op) volatile noexcept; 25546035553Spatrick T* operator-=(ptrdiff_t op) noexcept; 256037e7968Spatrick 257037e7968Spatrick void wait(T*, memory_order = memory_order::seq_cst) const volatile noexcept; 258037e7968Spatrick void wait(T*, memory_order = memory_order::seq_cst) const noexcept; 259037e7968Spatrick void notify_one() volatile noexcept; 260037e7968Spatrick void notify_one() noexcept; 261037e7968Spatrick void notify_all() volatile noexcept; 262037e7968Spatrick void notify_all() noexcept; 26346035553Spatrick}; 26446035553Spatrick 26546035553Spatrick 266*4bdff4beSrobert// [atomics.nonmembers], non-member functions 26746035553Spatricktemplate<class T> 268*4bdff4beSrobert bool atomic_is_lock_free(const volatile atomic<T>*) noexcept; 269*4bdff4beSroberttemplate<class T> 270*4bdff4beSrobert bool atomic_is_lock_free(const atomic<T>*) noexcept; 271*4bdff4beSroberttemplate<class T> 272*4bdff4beSrobert void atomic_store(volatile atomic<T>*, atomic<T>::value_type) noexcept; 273*4bdff4beSroberttemplate<class T> 274*4bdff4beSrobert void atomic_store(atomic<T>*, atomic<T>::value_type) noexcept; 275*4bdff4beSroberttemplate<class T> 276*4bdff4beSrobert void atomic_store_explicit(volatile atomic<T>*, atomic<T>::value_type, 277*4bdff4beSrobert memory_order) noexcept; 278*4bdff4beSroberttemplate<class T> 279*4bdff4beSrobert void atomic_store_explicit(atomic<T>*, atomic<T>::value_type, 280*4bdff4beSrobert memory_order) noexcept; 281*4bdff4beSroberttemplate<class T> 282*4bdff4beSrobert T atomic_load(const volatile atomic<T>*) noexcept; 283*4bdff4beSroberttemplate<class T> 284*4bdff4beSrobert T atomic_load(const atomic<T>*) noexcept; 285*4bdff4beSroberttemplate<class T> 286*4bdff4beSrobert T atomic_load_explicit(const volatile atomic<T>*, memory_order) noexcept; 287*4bdff4beSroberttemplate<class T> 288*4bdff4beSrobert T atomic_load_explicit(const atomic<T>*, memory_order) noexcept; 289*4bdff4beSroberttemplate<class T> 290*4bdff4beSrobert T atomic_exchange(volatile atomic<T>*, atomic<T>::value_type) noexcept; 291*4bdff4beSroberttemplate<class T> 292*4bdff4beSrobert T atomic_exchange(atomic<T>*, atomic<T>::value_type) noexcept; 293*4bdff4beSroberttemplate<class T> 294*4bdff4beSrobert T atomic_exchange_explicit(volatile atomic<T>*, atomic<T>::value_type, 295*4bdff4beSrobert memory_order) noexcept; 296*4bdff4beSroberttemplate<class T> 297*4bdff4beSrobert T atomic_exchange_explicit(atomic<T>*, atomic<T>::value_type, 298*4bdff4beSrobert memory_order) noexcept; 299*4bdff4beSroberttemplate<class T> 300*4bdff4beSrobert bool atomic_compare_exchange_weak(volatile atomic<T>*, atomic<T>::value_type*, 301*4bdff4beSrobert atomic<T>::value_type) noexcept; 302*4bdff4beSroberttemplate<class T> 303*4bdff4beSrobert bool atomic_compare_exchange_weak(atomic<T>*, atomic<T>::value_type*, 304*4bdff4beSrobert atomic<T>::value_type) noexcept; 305*4bdff4beSroberttemplate<class T> 306*4bdff4beSrobert bool atomic_compare_exchange_strong(volatile atomic<T>*, atomic<T>::value_type*, 307*4bdff4beSrobert atomic<T>::value_type) noexcept; 308*4bdff4beSroberttemplate<class T> 309*4bdff4beSrobert bool atomic_compare_exchange_strong(atomic<T>*, atomic<T>::value_type*, 310*4bdff4beSrobert atomic<T>::value_type) noexcept; 311*4bdff4beSroberttemplate<class T> 312*4bdff4beSrobert bool atomic_compare_exchange_weak_explicit(volatile atomic<T>*, atomic<T>::value_type*, 313*4bdff4beSrobert atomic<T>::value_type, 314*4bdff4beSrobert memory_order, memory_order) noexcept; 315*4bdff4beSroberttemplate<class T> 316*4bdff4beSrobert bool atomic_compare_exchange_weak_explicit(atomic<T>*, atomic<T>::value_type*, 317*4bdff4beSrobert atomic<T>::value_type, 318*4bdff4beSrobert memory_order, memory_order) noexcept; 319*4bdff4beSroberttemplate<class T> 320*4bdff4beSrobert bool atomic_compare_exchange_strong_explicit(volatile atomic<T>*, atomic<T>::value_type*, 321*4bdff4beSrobert atomic<T>::value_type, 322*4bdff4beSrobert memory_order, memory_order) noexcept; 323*4bdff4beSroberttemplate<class T> 324*4bdff4beSrobert bool atomic_compare_exchange_strong_explicit(atomic<T>*, atomic<T>::value_type*, 325*4bdff4beSrobert atomic<T>::value_type, 326*4bdff4beSrobert memory_order, memory_order) noexcept; 32746035553Spatrick 32846035553Spatricktemplate<class T> 329*4bdff4beSrobert T atomic_fetch_add(volatile atomic<T>*, atomic<T>::difference_type) noexcept; 330*4bdff4beSroberttemplate<class T> 331*4bdff4beSrobert T atomic_fetch_add(atomic<T>*, atomic<T>::difference_type) noexcept; 332*4bdff4beSroberttemplate<class T> 333*4bdff4beSrobert T atomic_fetch_add_explicit(volatile atomic<T>*, atomic<T>::difference_type, 334*4bdff4beSrobert memory_order) noexcept; 335*4bdff4beSroberttemplate<class T> 336*4bdff4beSrobert T atomic_fetch_add_explicit(atomic<T>*, atomic<T>::difference_type, 337*4bdff4beSrobert memory_order) noexcept; 338*4bdff4beSroberttemplate<class T> 339*4bdff4beSrobert T atomic_fetch_sub(volatile atomic<T>*, atomic<T>::difference_type) noexcept; 340*4bdff4beSroberttemplate<class T> 341*4bdff4beSrobert T atomic_fetch_sub(atomic<T>*, atomic<T>::difference_type) noexcept; 342*4bdff4beSroberttemplate<class T> 343*4bdff4beSrobert T atomic_fetch_sub_explicit(volatile atomic<T>*, atomic<T>::difference_type, 344*4bdff4beSrobert memory_order) noexcept; 345*4bdff4beSroberttemplate<class T> 346*4bdff4beSrobert T atomic_fetch_sub_explicit(atomic<T>*, atomic<T>::difference_type, 347*4bdff4beSrobert memory_order) noexcept; 348*4bdff4beSroberttemplate<class T> 349*4bdff4beSrobert T atomic_fetch_and(volatile atomic<T>*, atomic<T>::value_type) noexcept; 350*4bdff4beSroberttemplate<class T> 351*4bdff4beSrobert T atomic_fetch_and(atomic<T>*, atomic<T>::value_type) noexcept; 352*4bdff4beSroberttemplate<class T> 353*4bdff4beSrobert T atomic_fetch_and_explicit(volatile atomic<T>*, atomic<T>::value_type, 354*4bdff4beSrobert memory_order) noexcept; 355*4bdff4beSroberttemplate<class T> 356*4bdff4beSrobert T atomic_fetch_and_explicit(atomic<T>*, atomic<T>::value_type, 357*4bdff4beSrobert memory_order) noexcept; 358*4bdff4beSroberttemplate<class T> 359*4bdff4beSrobert T atomic_fetch_or(volatile atomic<T>*, atomic<T>::value_type) noexcept; 360*4bdff4beSroberttemplate<class T> 361*4bdff4beSrobert T atomic_fetch_or(atomic<T>*, atomic<T>::value_type) noexcept; 362*4bdff4beSroberttemplate<class T> 363*4bdff4beSrobert T atomic_fetch_or_explicit(volatile atomic<T>*, atomic<T>::value_type, 364*4bdff4beSrobert memory_order) noexcept; 365*4bdff4beSroberttemplate<class T> 366*4bdff4beSrobert T atomic_fetch_or_explicit(atomic<T>*, atomic<T>::value_type, 367*4bdff4beSrobert memory_order) noexcept; 368*4bdff4beSroberttemplate<class T> 369*4bdff4beSrobert T atomic_fetch_xor(volatile atomic<T>*, atomic<T>::value_type) noexcept; 370*4bdff4beSroberttemplate<class T> 371*4bdff4beSrobert T atomic_fetch_xor(atomic<T>*, atomic<T>::value_type) noexcept; 372*4bdff4beSroberttemplate<class T> 373*4bdff4beSrobert T atomic_fetch_xor_explicit(volatile atomic<T>*, atomic<T>::value_type, 374*4bdff4beSrobert memory_order) noexcept; 375*4bdff4beSroberttemplate<class T> 376*4bdff4beSrobert T atomic_fetch_xor_explicit(atomic<T>*, atomic<T>::value_type, 377*4bdff4beSrobert memory_order) noexcept; 37846035553Spatrick 37946035553Spatricktemplate<class T> 380*4bdff4beSrobert void atomic_wait(const volatile atomic<T>*, atomic<T>::value_type) noexcept; 38146035553Spatricktemplate<class T> 382*4bdff4beSrobert void atomic_wait(const atomic<T>*, atomic<T>::value_type) noexcept; 38346035553Spatricktemplate<class T> 384*4bdff4beSrobert void atomic_wait_explicit(const volatile atomic<T>*, atomic<T>::value_type, 385*4bdff4beSrobert memory_order) noexcept; 38646035553Spatricktemplate<class T> 387*4bdff4beSrobert void atomic_wait_explicit(const atomic<T>*, atomic<T>::value_type, 388*4bdff4beSrobert memory_order) noexcept; 38946035553Spatricktemplate<class T> 390*4bdff4beSrobert void atomic_notify_one(volatile atomic<T>*) noexcept; 39146035553Spatricktemplate<class T> 392*4bdff4beSrobert void atomic_notify_one(atomic<T>*) noexcept; 39346035553Spatricktemplate<class T> 394*4bdff4beSrobert void atomic_notify_all(volatile atomic<T>*) noexcept; 39546035553Spatricktemplate<class T> 396*4bdff4beSrobert void atomic_notify_all(atomic<T>*) noexcept; 39746035553Spatrick 39846035553Spatrick// Atomics for standard typedef types 39946035553Spatrick 40046035553Spatricktypedef atomic<bool> atomic_bool; 40146035553Spatricktypedef atomic<char> atomic_char; 40246035553Spatricktypedef atomic<signed char> atomic_schar; 40346035553Spatricktypedef atomic<unsigned char> atomic_uchar; 40446035553Spatricktypedef atomic<short> atomic_short; 40546035553Spatricktypedef atomic<unsigned short> atomic_ushort; 40646035553Spatricktypedef atomic<int> atomic_int; 40746035553Spatricktypedef atomic<unsigned int> atomic_uint; 40846035553Spatricktypedef atomic<long> atomic_long; 40946035553Spatricktypedef atomic<unsigned long> atomic_ulong; 41046035553Spatricktypedef atomic<long long> atomic_llong; 41146035553Spatricktypedef atomic<unsigned long long> atomic_ullong; 41276d0caaeSpatricktypedef atomic<char8_t> atomic_char8_t; // C++20 41346035553Spatricktypedef atomic<char16_t> atomic_char16_t; 41446035553Spatricktypedef atomic<char32_t> atomic_char32_t; 41546035553Spatricktypedef atomic<wchar_t> atomic_wchar_t; 41646035553Spatrick 41746035553Spatricktypedef atomic<int_least8_t> atomic_int_least8_t; 41846035553Spatricktypedef atomic<uint_least8_t> atomic_uint_least8_t; 41946035553Spatricktypedef atomic<int_least16_t> atomic_int_least16_t; 42046035553Spatricktypedef atomic<uint_least16_t> atomic_uint_least16_t; 42146035553Spatricktypedef atomic<int_least32_t> atomic_int_least32_t; 42246035553Spatricktypedef atomic<uint_least32_t> atomic_uint_least32_t; 42346035553Spatricktypedef atomic<int_least64_t> atomic_int_least64_t; 42446035553Spatricktypedef atomic<uint_least64_t> atomic_uint_least64_t; 42546035553Spatrick 42646035553Spatricktypedef atomic<int_fast8_t> atomic_int_fast8_t; 42746035553Spatricktypedef atomic<uint_fast8_t> atomic_uint_fast8_t; 42846035553Spatricktypedef atomic<int_fast16_t> atomic_int_fast16_t; 42946035553Spatricktypedef atomic<uint_fast16_t> atomic_uint_fast16_t; 43046035553Spatricktypedef atomic<int_fast32_t> atomic_int_fast32_t; 43146035553Spatricktypedef atomic<uint_fast32_t> atomic_uint_fast32_t; 43246035553Spatricktypedef atomic<int_fast64_t> atomic_int_fast64_t; 43346035553Spatricktypedef atomic<uint_fast64_t> atomic_uint_fast64_t; 43446035553Spatrick 43546035553Spatricktypedef atomic<int8_t> atomic_int8_t; 43646035553Spatricktypedef atomic<uint8_t> atomic_uint8_t; 43746035553Spatricktypedef atomic<int16_t> atomic_int16_t; 43846035553Spatricktypedef atomic<uint16_t> atomic_uint16_t; 43946035553Spatricktypedef atomic<int32_t> atomic_int32_t; 44046035553Spatricktypedef atomic<uint32_t> atomic_uint32_t; 44146035553Spatricktypedef atomic<int64_t> atomic_int64_t; 44246035553Spatricktypedef atomic<uint64_t> atomic_uint64_t; 44346035553Spatrick 44446035553Spatricktypedef atomic<intptr_t> atomic_intptr_t; 44546035553Spatricktypedef atomic<uintptr_t> atomic_uintptr_t; 44646035553Spatricktypedef atomic<size_t> atomic_size_t; 44746035553Spatricktypedef atomic<ptrdiff_t> atomic_ptrdiff_t; 44846035553Spatricktypedef atomic<intmax_t> atomic_intmax_t; 44946035553Spatricktypedef atomic<uintmax_t> atomic_uintmax_t; 45046035553Spatrick 451037e7968Spatrick// flag type and operations 452037e7968Spatrick 453037e7968Spatricktypedef struct atomic_flag 454037e7968Spatrick{ 45576d0caaeSpatrick atomic_flag() noexcept = default; // until C++20 45676d0caaeSpatrick constexpr atomic_flag() noexcept; // since C++20 457037e7968Spatrick atomic_flag(const atomic_flag&) = delete; 458037e7968Spatrick atomic_flag& operator=(const atomic_flag&) = delete; 459037e7968Spatrick atomic_flag& operator=(const atomic_flag&) volatile = delete; 460037e7968Spatrick 461037e7968Spatrick bool test(memory_order m = memory_order_seq_cst) volatile noexcept; 462037e7968Spatrick bool test(memory_order m = memory_order_seq_cst) noexcept; 463037e7968Spatrick bool test_and_set(memory_order m = memory_order_seq_cst) volatile noexcept; 464037e7968Spatrick bool test_and_set(memory_order m = memory_order_seq_cst) noexcept; 465037e7968Spatrick void clear(memory_order m = memory_order_seq_cst) volatile noexcept; 466037e7968Spatrick void clear(memory_order m = memory_order_seq_cst) noexcept; 467037e7968Spatrick 468037e7968Spatrick void wait(bool, memory_order = memory_order::seq_cst) const volatile noexcept; 469037e7968Spatrick void wait(bool, memory_order = memory_order::seq_cst) const noexcept; 470037e7968Spatrick void notify_one() volatile noexcept; 471037e7968Spatrick void notify_one() noexcept; 472037e7968Spatrick void notify_all() volatile noexcept; 473037e7968Spatrick void notify_all() noexcept; 474037e7968Spatrick} atomic_flag; 475037e7968Spatrick 476037e7968Spatrickbool atomic_flag_test(volatile atomic_flag* obj) noexcept; 477037e7968Spatrickbool atomic_flag_test(atomic_flag* obj) noexcept; 478037e7968Spatrickbool atomic_flag_test_explicit(volatile atomic_flag* obj, 479037e7968Spatrick memory_order m) noexcept; 480037e7968Spatrickbool atomic_flag_test_explicit(atomic_flag* obj, memory_order m) noexcept; 481037e7968Spatrickbool atomic_flag_test_and_set(volatile atomic_flag* obj) noexcept; 482037e7968Spatrickbool atomic_flag_test_and_set(atomic_flag* obj) noexcept; 483037e7968Spatrickbool atomic_flag_test_and_set_explicit(volatile atomic_flag* obj, 484037e7968Spatrick memory_order m) noexcept; 485037e7968Spatrickbool atomic_flag_test_and_set_explicit(atomic_flag* obj, memory_order m) noexcept; 486037e7968Spatrickvoid atomic_flag_clear(volatile atomic_flag* obj) noexcept; 487037e7968Spatrickvoid atomic_flag_clear(atomic_flag* obj) noexcept; 488037e7968Spatrickvoid atomic_flag_clear_explicit(volatile atomic_flag* obj, memory_order m) noexcept; 489037e7968Spatrickvoid atomic_flag_clear_explicit(atomic_flag* obj, memory_order m) noexcept; 490037e7968Spatrick 491037e7968Spatrickvoid atomic_wait(const volatile atomic_flag* obj, T old) noexcept; 492037e7968Spatrickvoid atomic_wait(const atomic_flag* obj, T old) noexcept; 493037e7968Spatrickvoid atomic_wait_explicit(const volatile atomic_flag* obj, T old, memory_order m) noexcept; 494037e7968Spatrickvoid atomic_wait_explicit(const atomic_flag* obj, T old, memory_order m) noexcept; 495037e7968Spatrickvoid atomic_one(volatile atomic_flag* obj) noexcept; 496037e7968Spatrickvoid atomic_one(atomic_flag* obj) noexcept; 497037e7968Spatrickvoid atomic_all(volatile atomic_flag* obj) noexcept; 498037e7968Spatrickvoid atomic_all(atomic_flag* obj) noexcept; 499037e7968Spatrick 50046035553Spatrick// fences 50146035553Spatrick 50246035553Spatrickvoid atomic_thread_fence(memory_order m) noexcept; 50346035553Spatrickvoid atomic_signal_fence(memory_order m) noexcept; 50446035553Spatrick 505037e7968Spatrick// deprecated 506037e7968Spatrick 507037e7968Spatricktemplate <class T> 508*4bdff4beSrobert void atomic_init(volatile atomic<T>* obj, atomic<T>::value_type desr) noexcept; 509037e7968Spatrick 510037e7968Spatricktemplate <class T> 511*4bdff4beSrobert void atomic_init(atomic<T>* obj, atomic<T>::value_type desr) noexcept; 512037e7968Spatrick 513037e7968Spatrick#define ATOMIC_VAR_INIT(value) see below 514037e7968Spatrick 515037e7968Spatrick#define ATOMIC_FLAG_INIT see below 516037e7968Spatrick 51746035553Spatrick} // std 51846035553Spatrick 51946035553Spatrick*/ 52046035553Spatrick 521*4bdff4beSrobert#include <__assert> // all public C++ headers provide the assertion handler 52276d0caaeSpatrick#include <__availability> 523*4bdff4beSrobert#include <__chrono/duration.h> 52446035553Spatrick#include <__config> 525*4bdff4beSrobert#include <__thread/poll_with_backoff.h> 526*4bdff4beSrobert#include <__thread/timed_backoff_policy.h> 527*4bdff4beSrobert#include <__type_traits/conditional.h> 528*4bdff4beSrobert#include <__type_traits/decay.h> 529*4bdff4beSrobert#include <__type_traits/is_assignable.h> 530*4bdff4beSrobert#include <__type_traits/is_function.h> 531*4bdff4beSrobert#include <__type_traits/is_nothrow_default_constructible.h> 532*4bdff4beSrobert#include <__type_traits/is_same.h> 533*4bdff4beSrobert#include <__type_traits/is_trivially_copyable.h> 534*4bdff4beSrobert#include <__type_traits/remove_const.h> 535*4bdff4beSrobert#include <__type_traits/remove_pointer.h> 536*4bdff4beSrobert#include <__type_traits/underlying_type.h> 53746035553Spatrick#include <cstddef> 53846035553Spatrick#include <cstdint> 539037e7968Spatrick#include <cstring> 54046035553Spatrick#include <version> 54146035553Spatrick 542*4bdff4beSrobert#ifndef _LIBCPP_HAS_NO_THREADS 543*4bdff4beSrobert# include <__threading_support> 544*4bdff4beSrobert#endif 545*4bdff4beSrobert 54646035553Spatrick#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 54746035553Spatrick# pragma GCC system_header 54846035553Spatrick#endif 54946035553Spatrick 55046035553Spatrick#ifdef _LIBCPP_HAS_NO_ATOMIC_HEADER 55146035553Spatrick# error <atomic> is not implemented 55246035553Spatrick#endif 55346035553Spatrick#ifdef kill_dependency 554*4bdff4beSrobert# error <atomic> is incompatible with <stdatomic.h> before C++23. Please compile with -std=c++23. 55546035553Spatrick#endif 55646035553Spatrick 55746035553Spatrick#define _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) \ 55846035553Spatrick _LIBCPP_DIAGNOSE_WARNING(__m == memory_order_consume || \ 55946035553Spatrick __m == memory_order_acquire || \ 56046035553Spatrick __m == memory_order_acq_rel, \ 56146035553Spatrick "memory order argument to atomic operation is invalid") 56246035553Spatrick 56346035553Spatrick#define _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) \ 56446035553Spatrick _LIBCPP_DIAGNOSE_WARNING(__m == memory_order_release || \ 56546035553Spatrick __m == memory_order_acq_rel, \ 56646035553Spatrick "memory order argument to atomic operation is invalid") 56746035553Spatrick 56846035553Spatrick#define _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__m, __f) \ 56946035553Spatrick _LIBCPP_DIAGNOSE_WARNING(__f == memory_order_release || \ 57046035553Spatrick __f == memory_order_acq_rel, \ 57146035553Spatrick "memory order argument to atomic operation is invalid") 57246035553Spatrick 57346035553Spatrick_LIBCPP_BEGIN_NAMESPACE_STD 57446035553Spatrick 57546035553Spatrick// Figure out what the underlying type for `memory_order` would be if it were 57646035553Spatrick// declared as an unscoped enum (accounting for -fshort-enums). Use this result 57746035553Spatrick// to pin the underlying type in C++20. 57846035553Spatrickenum __legacy_memory_order { 57946035553Spatrick __mo_relaxed, 58046035553Spatrick __mo_consume, 58146035553Spatrick __mo_acquire, 58246035553Spatrick __mo_release, 58346035553Spatrick __mo_acq_rel, 58446035553Spatrick __mo_seq_cst 58546035553Spatrick}; 58646035553Spatrick 58746035553Spatricktypedef underlying_type<__legacy_memory_order>::type __memory_order_underlying_t; 58846035553Spatrick 58946035553Spatrick#if _LIBCPP_STD_VER > 17 59046035553Spatrick 59146035553Spatrickenum class memory_order : __memory_order_underlying_t { 59246035553Spatrick relaxed = __mo_relaxed, 59346035553Spatrick consume = __mo_consume, 59446035553Spatrick acquire = __mo_acquire, 59546035553Spatrick release = __mo_release, 59646035553Spatrick acq_rel = __mo_acq_rel, 59746035553Spatrick seq_cst = __mo_seq_cst 59846035553Spatrick}; 59946035553Spatrick 60046035553Spatrickinline constexpr auto memory_order_relaxed = memory_order::relaxed; 60146035553Spatrickinline constexpr auto memory_order_consume = memory_order::consume; 60246035553Spatrickinline constexpr auto memory_order_acquire = memory_order::acquire; 60346035553Spatrickinline constexpr auto memory_order_release = memory_order::release; 60446035553Spatrickinline constexpr auto memory_order_acq_rel = memory_order::acq_rel; 60546035553Spatrickinline constexpr auto memory_order_seq_cst = memory_order::seq_cst; 60646035553Spatrick 60746035553Spatrick#else 60846035553Spatrick 60946035553Spatricktypedef enum memory_order { 61046035553Spatrick memory_order_relaxed = __mo_relaxed, 61146035553Spatrick memory_order_consume = __mo_consume, 61246035553Spatrick memory_order_acquire = __mo_acquire, 61346035553Spatrick memory_order_release = __mo_release, 61446035553Spatrick memory_order_acq_rel = __mo_acq_rel, 61546035553Spatrick memory_order_seq_cst = __mo_seq_cst, 61646035553Spatrick} memory_order; 61746035553Spatrick 61846035553Spatrick#endif // _LIBCPP_STD_VER > 17 61946035553Spatrick 620037e7968Spatricktemplate <typename _Tp> _LIBCPP_INLINE_VISIBILITY 621037e7968Spatrickbool __cxx_nonatomic_compare_equal(_Tp const& __lhs, _Tp const& __rhs) { 62276d0caaeSpatrick return _VSTD::memcmp(&__lhs, &__rhs, sizeof(_Tp)) == 0; 623037e7968Spatrick} 624037e7968Spatrick 62546035553Spatrickstatic_assert((is_same<underlying_type<memory_order>::type, __memory_order_underlying_t>::value), 62646035553Spatrick "unexpected underlying type for std::memory_order"); 62746035553Spatrick 62846035553Spatrick#if defined(_LIBCPP_HAS_GCC_ATOMIC_IMP) || \ 62946035553Spatrick defined(_LIBCPP_ATOMIC_ONLY_USE_BUILTINS) 63046035553Spatrick 63146035553Spatrick// [atomics.types.generic]p1 guarantees _Tp is trivially copyable. Because 63246035553Spatrick// the default operator= in an object is not volatile, a byte-by-byte copy 63346035553Spatrick// is required. 63446035553Spatricktemplate <typename _Tp, typename _Tv> _LIBCPP_INLINE_VISIBILITY 63546035553Spatricktypename enable_if<is_assignable<_Tp&, _Tv>::value>::type 63646035553Spatrick__cxx_atomic_assign_volatile(_Tp& __a_value, _Tv const& __val) { 63746035553Spatrick __a_value = __val; 63846035553Spatrick} 63946035553Spatricktemplate <typename _Tp, typename _Tv> _LIBCPP_INLINE_VISIBILITY 64046035553Spatricktypename enable_if<is_assignable<_Tp&, _Tv>::value>::type 64146035553Spatrick__cxx_atomic_assign_volatile(_Tp volatile& __a_value, _Tv volatile const& __val) { 64246035553Spatrick volatile char* __to = reinterpret_cast<volatile char*>(&__a_value); 64346035553Spatrick volatile char* __end = __to + sizeof(_Tp); 64446035553Spatrick volatile const char* __from = reinterpret_cast<volatile const char*>(&__val); 64546035553Spatrick while (__to != __end) 64646035553Spatrick *__to++ = *__from++; 64746035553Spatrick} 64846035553Spatrick 64946035553Spatrick#endif 65046035553Spatrick 65146035553Spatrick#if defined(_LIBCPP_HAS_GCC_ATOMIC_IMP) 65246035553Spatrick 65346035553Spatricktemplate <typename _Tp> 65446035553Spatrickstruct __cxx_atomic_base_impl { 65546035553Spatrick 65646035553Spatrick _LIBCPP_INLINE_VISIBILITY 65746035553Spatrick#ifndef _LIBCPP_CXX03_LANG 65846035553Spatrick __cxx_atomic_base_impl() _NOEXCEPT = default; 65946035553Spatrick#else 66046035553Spatrick __cxx_atomic_base_impl() _NOEXCEPT : __a_value() {} 66146035553Spatrick#endif // _LIBCPP_CXX03_LANG 66246035553Spatrick _LIBCPP_CONSTEXPR explicit __cxx_atomic_base_impl(_Tp value) _NOEXCEPT 66346035553Spatrick : __a_value(value) {} 66446035553Spatrick _Tp __a_value; 66546035553Spatrick}; 66646035553Spatrick 66746035553Spatrick_LIBCPP_INLINE_VISIBILITY inline _LIBCPP_CONSTEXPR int __to_gcc_order(memory_order __order) { 66846035553Spatrick // Avoid switch statement to make this a constexpr. 66946035553Spatrick return __order == memory_order_relaxed ? __ATOMIC_RELAXED: 67046035553Spatrick (__order == memory_order_acquire ? __ATOMIC_ACQUIRE: 67146035553Spatrick (__order == memory_order_release ? __ATOMIC_RELEASE: 67246035553Spatrick (__order == memory_order_seq_cst ? __ATOMIC_SEQ_CST: 67346035553Spatrick (__order == memory_order_acq_rel ? __ATOMIC_ACQ_REL: 67446035553Spatrick __ATOMIC_CONSUME)))); 67546035553Spatrick} 67646035553Spatrick 67746035553Spatrick_LIBCPP_INLINE_VISIBILITY inline _LIBCPP_CONSTEXPR int __to_gcc_failure_order(memory_order __order) { 67846035553Spatrick // Avoid switch statement to make this a constexpr. 67946035553Spatrick return __order == memory_order_relaxed ? __ATOMIC_RELAXED: 68046035553Spatrick (__order == memory_order_acquire ? __ATOMIC_ACQUIRE: 68146035553Spatrick (__order == memory_order_release ? __ATOMIC_RELAXED: 68246035553Spatrick (__order == memory_order_seq_cst ? __ATOMIC_SEQ_CST: 68346035553Spatrick (__order == memory_order_acq_rel ? __ATOMIC_ACQUIRE: 68446035553Spatrick __ATOMIC_CONSUME)))); 68546035553Spatrick} 68646035553Spatrick 68746035553Spatricktemplate <typename _Tp> 68846035553Spatrick_LIBCPP_INLINE_VISIBILITY 68946035553Spatrickvoid __cxx_atomic_init(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __val) { 69046035553Spatrick __cxx_atomic_assign_volatile(__a->__a_value, __val); 69146035553Spatrick} 69246035553Spatrick 69346035553Spatricktemplate <typename _Tp> 69446035553Spatrick_LIBCPP_INLINE_VISIBILITY 69546035553Spatrickvoid __cxx_atomic_init(__cxx_atomic_base_impl<_Tp>* __a, _Tp __val) { 69646035553Spatrick __a->__a_value = __val; 69746035553Spatrick} 69846035553Spatrick 69946035553Spatrick_LIBCPP_INLINE_VISIBILITY inline 70046035553Spatrickvoid __cxx_atomic_thread_fence(memory_order __order) { 70146035553Spatrick __atomic_thread_fence(__to_gcc_order(__order)); 70246035553Spatrick} 70346035553Spatrick 70446035553Spatrick_LIBCPP_INLINE_VISIBILITY inline 70546035553Spatrickvoid __cxx_atomic_signal_fence(memory_order __order) { 70646035553Spatrick __atomic_signal_fence(__to_gcc_order(__order)); 70746035553Spatrick} 70846035553Spatrick 70946035553Spatricktemplate <typename _Tp> 71046035553Spatrick_LIBCPP_INLINE_VISIBILITY 71146035553Spatrickvoid __cxx_atomic_store(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __val, 71246035553Spatrick memory_order __order) { 71346035553Spatrick __atomic_store(&__a->__a_value, &__val, 71446035553Spatrick __to_gcc_order(__order)); 71546035553Spatrick} 71646035553Spatrick 71746035553Spatricktemplate <typename _Tp> 71846035553Spatrick_LIBCPP_INLINE_VISIBILITY 71946035553Spatrickvoid __cxx_atomic_store(__cxx_atomic_base_impl<_Tp>* __a, _Tp __val, 72046035553Spatrick memory_order __order) { 72146035553Spatrick __atomic_store(&__a->__a_value, &__val, 72246035553Spatrick __to_gcc_order(__order)); 72346035553Spatrick} 72446035553Spatrick 72546035553Spatricktemplate <typename _Tp> 72646035553Spatrick_LIBCPP_INLINE_VISIBILITY 72746035553Spatrick_Tp __cxx_atomic_load(const volatile __cxx_atomic_base_impl<_Tp>* __a, 72846035553Spatrick memory_order __order) { 72946035553Spatrick _Tp __ret; 73046035553Spatrick __atomic_load(&__a->__a_value, &__ret, 73146035553Spatrick __to_gcc_order(__order)); 73246035553Spatrick return __ret; 73346035553Spatrick} 73446035553Spatrick 73546035553Spatricktemplate <typename _Tp> 73646035553Spatrick_LIBCPP_INLINE_VISIBILITY 73746035553Spatrick_Tp __cxx_atomic_load(const __cxx_atomic_base_impl<_Tp>* __a, memory_order __order) { 73846035553Spatrick _Tp __ret; 73946035553Spatrick __atomic_load(&__a->__a_value, &__ret, 74046035553Spatrick __to_gcc_order(__order)); 74146035553Spatrick return __ret; 74246035553Spatrick} 74346035553Spatrick 74446035553Spatricktemplate <typename _Tp> 74546035553Spatrick_LIBCPP_INLINE_VISIBILITY 74646035553Spatrick_Tp __cxx_atomic_exchange(volatile __cxx_atomic_base_impl<_Tp>* __a, 74746035553Spatrick _Tp __value, memory_order __order) { 74846035553Spatrick _Tp __ret; 74946035553Spatrick __atomic_exchange(&__a->__a_value, &__value, &__ret, 75046035553Spatrick __to_gcc_order(__order)); 75146035553Spatrick return __ret; 75246035553Spatrick} 75346035553Spatrick 75446035553Spatricktemplate <typename _Tp> 75546035553Spatrick_LIBCPP_INLINE_VISIBILITY 75646035553Spatrick_Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp>* __a, _Tp __value, 75746035553Spatrick memory_order __order) { 75846035553Spatrick _Tp __ret; 75946035553Spatrick __atomic_exchange(&__a->__a_value, &__value, &__ret, 76046035553Spatrick __to_gcc_order(__order)); 76146035553Spatrick return __ret; 76246035553Spatrick} 76346035553Spatrick 76446035553Spatricktemplate <typename _Tp> 76546035553Spatrick_LIBCPP_INLINE_VISIBILITY 76646035553Spatrickbool __cxx_atomic_compare_exchange_strong( 76746035553Spatrick volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, 76846035553Spatrick memory_order __success, memory_order __failure) { 76946035553Spatrick return __atomic_compare_exchange(&__a->__a_value, __expected, &__value, 77046035553Spatrick false, 77146035553Spatrick __to_gcc_order(__success), 77246035553Spatrick __to_gcc_failure_order(__failure)); 77346035553Spatrick} 77446035553Spatrick 77546035553Spatricktemplate <typename _Tp> 77646035553Spatrick_LIBCPP_INLINE_VISIBILITY 77746035553Spatrickbool __cxx_atomic_compare_exchange_strong( 77846035553Spatrick __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success, 77946035553Spatrick memory_order __failure) { 78046035553Spatrick return __atomic_compare_exchange(&__a->__a_value, __expected, &__value, 78146035553Spatrick false, 78246035553Spatrick __to_gcc_order(__success), 78346035553Spatrick __to_gcc_failure_order(__failure)); 78446035553Spatrick} 78546035553Spatrick 78646035553Spatricktemplate <typename _Tp> 78746035553Spatrick_LIBCPP_INLINE_VISIBILITY 78846035553Spatrickbool __cxx_atomic_compare_exchange_weak( 78946035553Spatrick volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, 79046035553Spatrick memory_order __success, memory_order __failure) { 79146035553Spatrick return __atomic_compare_exchange(&__a->__a_value, __expected, &__value, 79246035553Spatrick true, 79346035553Spatrick __to_gcc_order(__success), 79446035553Spatrick __to_gcc_failure_order(__failure)); 79546035553Spatrick} 79646035553Spatrick 79746035553Spatricktemplate <typename _Tp> 79846035553Spatrick_LIBCPP_INLINE_VISIBILITY 79946035553Spatrickbool __cxx_atomic_compare_exchange_weak( 80046035553Spatrick __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success, 80146035553Spatrick memory_order __failure) { 80246035553Spatrick return __atomic_compare_exchange(&__a->__a_value, __expected, &__value, 80346035553Spatrick true, 80446035553Spatrick __to_gcc_order(__success), 80546035553Spatrick __to_gcc_failure_order(__failure)); 80646035553Spatrick} 80746035553Spatrick 80846035553Spatricktemplate <typename _Tp> 80946035553Spatrickstruct __skip_amt { enum {value = 1}; }; 81046035553Spatrick 81146035553Spatricktemplate <typename _Tp> 81246035553Spatrickstruct __skip_amt<_Tp*> { enum {value = sizeof(_Tp)}; }; 81346035553Spatrick 81446035553Spatrick// FIXME: Haven't figured out what the spec says about using arrays with 81546035553Spatrick// atomic_fetch_add. Force a failure rather than creating bad behavior. 81646035553Spatricktemplate <typename _Tp> 81746035553Spatrickstruct __skip_amt<_Tp[]> { }; 81846035553Spatricktemplate <typename _Tp, int n> 81946035553Spatrickstruct __skip_amt<_Tp[n]> { }; 82046035553Spatrick 82146035553Spatricktemplate <typename _Tp, typename _Td> 82246035553Spatrick_LIBCPP_INLINE_VISIBILITY 82346035553Spatrick_Tp __cxx_atomic_fetch_add(volatile __cxx_atomic_base_impl<_Tp>* __a, 82446035553Spatrick _Td __delta, memory_order __order) { 82546035553Spatrick return __atomic_fetch_add(&__a->__a_value, __delta * __skip_amt<_Tp>::value, 82646035553Spatrick __to_gcc_order(__order)); 82746035553Spatrick} 82846035553Spatrick 82946035553Spatricktemplate <typename _Tp, typename _Td> 83046035553Spatrick_LIBCPP_INLINE_VISIBILITY 83146035553Spatrick_Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp>* __a, _Td __delta, 83246035553Spatrick memory_order __order) { 83346035553Spatrick return __atomic_fetch_add(&__a->__a_value, __delta * __skip_amt<_Tp>::value, 83446035553Spatrick __to_gcc_order(__order)); 83546035553Spatrick} 83646035553Spatrick 83746035553Spatricktemplate <typename _Tp, typename _Td> 83846035553Spatrick_LIBCPP_INLINE_VISIBILITY 83946035553Spatrick_Tp __cxx_atomic_fetch_sub(volatile __cxx_atomic_base_impl<_Tp>* __a, 84046035553Spatrick _Td __delta, memory_order __order) { 84146035553Spatrick return __atomic_fetch_sub(&__a->__a_value, __delta * __skip_amt<_Tp>::value, 84246035553Spatrick __to_gcc_order(__order)); 84346035553Spatrick} 84446035553Spatrick 84546035553Spatricktemplate <typename _Tp, typename _Td> 84646035553Spatrick_LIBCPP_INLINE_VISIBILITY 84746035553Spatrick_Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp>* __a, _Td __delta, 84846035553Spatrick memory_order __order) { 84946035553Spatrick return __atomic_fetch_sub(&__a->__a_value, __delta * __skip_amt<_Tp>::value, 85046035553Spatrick __to_gcc_order(__order)); 85146035553Spatrick} 85246035553Spatrick 85346035553Spatricktemplate <typename _Tp> 85446035553Spatrick_LIBCPP_INLINE_VISIBILITY 85546035553Spatrick_Tp __cxx_atomic_fetch_and(volatile __cxx_atomic_base_impl<_Tp>* __a, 85646035553Spatrick _Tp __pattern, memory_order __order) { 85746035553Spatrick return __atomic_fetch_and(&__a->__a_value, __pattern, 85846035553Spatrick __to_gcc_order(__order)); 85946035553Spatrick} 86046035553Spatrick 86146035553Spatricktemplate <typename _Tp> 86246035553Spatrick_LIBCPP_INLINE_VISIBILITY 86346035553Spatrick_Tp __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp>* __a, 86446035553Spatrick _Tp __pattern, memory_order __order) { 86546035553Spatrick return __atomic_fetch_and(&__a->__a_value, __pattern, 86646035553Spatrick __to_gcc_order(__order)); 86746035553Spatrick} 86846035553Spatrick 86946035553Spatricktemplate <typename _Tp> 87046035553Spatrick_LIBCPP_INLINE_VISIBILITY 87146035553Spatrick_Tp __cxx_atomic_fetch_or(volatile __cxx_atomic_base_impl<_Tp>* __a, 87246035553Spatrick _Tp __pattern, memory_order __order) { 87346035553Spatrick return __atomic_fetch_or(&__a->__a_value, __pattern, 87446035553Spatrick __to_gcc_order(__order)); 87546035553Spatrick} 87646035553Spatrick 87746035553Spatricktemplate <typename _Tp> 87846035553Spatrick_LIBCPP_INLINE_VISIBILITY 87946035553Spatrick_Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern, 88046035553Spatrick memory_order __order) { 88146035553Spatrick return __atomic_fetch_or(&__a->__a_value, __pattern, 88246035553Spatrick __to_gcc_order(__order)); 88346035553Spatrick} 88446035553Spatrick 88546035553Spatricktemplate <typename _Tp> 88646035553Spatrick_LIBCPP_INLINE_VISIBILITY 88746035553Spatrick_Tp __cxx_atomic_fetch_xor(volatile __cxx_atomic_base_impl<_Tp>* __a, 88846035553Spatrick _Tp __pattern, memory_order __order) { 88946035553Spatrick return __atomic_fetch_xor(&__a->__a_value, __pattern, 89046035553Spatrick __to_gcc_order(__order)); 89146035553Spatrick} 89246035553Spatrick 89346035553Spatricktemplate <typename _Tp> 89446035553Spatrick_LIBCPP_INLINE_VISIBILITY 89546035553Spatrick_Tp __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern, 89646035553Spatrick memory_order __order) { 89746035553Spatrick return __atomic_fetch_xor(&__a->__a_value, __pattern, 89846035553Spatrick __to_gcc_order(__order)); 89946035553Spatrick} 90046035553Spatrick 90146035553Spatrick#define __cxx_atomic_is_lock_free(__s) __atomic_is_lock_free(__s, 0) 90246035553Spatrick 90346035553Spatrick#elif defined(_LIBCPP_HAS_C_ATOMIC_IMP) 90446035553Spatrick 90546035553Spatricktemplate <typename _Tp> 90646035553Spatrickstruct __cxx_atomic_base_impl { 90746035553Spatrick 90846035553Spatrick _LIBCPP_INLINE_VISIBILITY 90946035553Spatrick#ifndef _LIBCPP_CXX03_LANG 91046035553Spatrick __cxx_atomic_base_impl() _NOEXCEPT = default; 91146035553Spatrick#else 91246035553Spatrick __cxx_atomic_base_impl() _NOEXCEPT : __a_value() {} 91346035553Spatrick#endif // _LIBCPP_CXX03_LANG 914*4bdff4beSrobert _LIBCPP_CONSTEXPR explicit __cxx_atomic_base_impl(_Tp __value) _NOEXCEPT 915*4bdff4beSrobert : __a_value(__value) {} 91646035553Spatrick _LIBCPP_DISABLE_EXTENSION_WARNING _Atomic(_Tp) __a_value; 91746035553Spatrick}; 91846035553Spatrick 91946035553Spatrick#define __cxx_atomic_is_lock_free(__s) __c11_atomic_is_lock_free(__s) 92046035553Spatrick 92146035553Spatrick_LIBCPP_INLINE_VISIBILITY inline 92246035553Spatrickvoid __cxx_atomic_thread_fence(memory_order __order) _NOEXCEPT { 92346035553Spatrick __c11_atomic_thread_fence(static_cast<__memory_order_underlying_t>(__order)); 92446035553Spatrick} 92546035553Spatrick 92646035553Spatrick_LIBCPP_INLINE_VISIBILITY inline 92746035553Spatrickvoid __cxx_atomic_signal_fence(memory_order __order) _NOEXCEPT { 92846035553Spatrick __c11_atomic_signal_fence(static_cast<__memory_order_underlying_t>(__order)); 92946035553Spatrick} 93046035553Spatrick 93146035553Spatricktemplate<class _Tp> 93246035553Spatrick_LIBCPP_INLINE_VISIBILITY 93346035553Spatrickvoid __cxx_atomic_init(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __val) _NOEXCEPT { 93446035553Spatrick __c11_atomic_init(&__a->__a_value, __val); 93546035553Spatrick} 93646035553Spatricktemplate<class _Tp> 93746035553Spatrick_LIBCPP_INLINE_VISIBILITY 93846035553Spatrickvoid __cxx_atomic_init(__cxx_atomic_base_impl<_Tp> * __a, _Tp __val) _NOEXCEPT { 93946035553Spatrick __c11_atomic_init(&__a->__a_value, __val); 94046035553Spatrick} 94146035553Spatrick 94246035553Spatricktemplate<class _Tp> 94346035553Spatrick_LIBCPP_INLINE_VISIBILITY 94446035553Spatrickvoid __cxx_atomic_store(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __val, memory_order __order) _NOEXCEPT { 94546035553Spatrick __c11_atomic_store(&__a->__a_value, __val, static_cast<__memory_order_underlying_t>(__order)); 94646035553Spatrick} 94746035553Spatricktemplate<class _Tp> 94846035553Spatrick_LIBCPP_INLINE_VISIBILITY 94946035553Spatrickvoid __cxx_atomic_store(__cxx_atomic_base_impl<_Tp> * __a, _Tp __val, memory_order __order) _NOEXCEPT { 95046035553Spatrick __c11_atomic_store(&__a->__a_value, __val, static_cast<__memory_order_underlying_t>(__order)); 95146035553Spatrick} 95246035553Spatrick 95346035553Spatricktemplate<class _Tp> 95446035553Spatrick_LIBCPP_INLINE_VISIBILITY 95546035553Spatrick_Tp __cxx_atomic_load(__cxx_atomic_base_impl<_Tp> const volatile* __a, memory_order __order) _NOEXCEPT { 956*4bdff4beSrobert using __ptr_type = __remove_const_t<decltype(__a->__a_value)>*; 95746035553Spatrick return __c11_atomic_load(const_cast<__ptr_type>(&__a->__a_value), static_cast<__memory_order_underlying_t>(__order)); 95846035553Spatrick} 95946035553Spatricktemplate<class _Tp> 96046035553Spatrick_LIBCPP_INLINE_VISIBILITY 96146035553Spatrick_Tp __cxx_atomic_load(__cxx_atomic_base_impl<_Tp> const* __a, memory_order __order) _NOEXCEPT { 962*4bdff4beSrobert using __ptr_type = __remove_const_t<decltype(__a->__a_value)>*; 96346035553Spatrick return __c11_atomic_load(const_cast<__ptr_type>(&__a->__a_value), static_cast<__memory_order_underlying_t>(__order)); 96446035553Spatrick} 96546035553Spatrick 96646035553Spatricktemplate<class _Tp> 96746035553Spatrick_LIBCPP_INLINE_VISIBILITY 96846035553Spatrick_Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __value, memory_order __order) _NOEXCEPT { 96946035553Spatrick return __c11_atomic_exchange(&__a->__a_value, __value, static_cast<__memory_order_underlying_t>(__order)); 97046035553Spatrick} 97146035553Spatricktemplate<class _Tp> 97246035553Spatrick_LIBCPP_INLINE_VISIBILITY 97346035553Spatrick_Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp> * __a, _Tp __value, memory_order __order) _NOEXCEPT { 97446035553Spatrick return __c11_atomic_exchange(&__a->__a_value, __value, static_cast<__memory_order_underlying_t>(__order)); 97546035553Spatrick} 97646035553Spatrick 97776d0caaeSpatrick_LIBCPP_INLINE_VISIBILITY inline _LIBCPP_CONSTEXPR memory_order __to_failure_order(memory_order __order) { 97876d0caaeSpatrick // Avoid switch statement to make this a constexpr. 97976d0caaeSpatrick return __order == memory_order_release ? memory_order_relaxed: 98076d0caaeSpatrick (__order == memory_order_acq_rel ? memory_order_acquire: 98176d0caaeSpatrick __order); 98276d0caaeSpatrick} 98376d0caaeSpatrick 98446035553Spatricktemplate<class _Tp> 98546035553Spatrick_LIBCPP_INLINE_VISIBILITY 98646035553Spatrickbool __cxx_atomic_compare_exchange_strong(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT { 98776d0caaeSpatrick 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))); 98846035553Spatrick} 98946035553Spatricktemplate<class _Tp> 99046035553Spatrick_LIBCPP_INLINE_VISIBILITY 99146035553Spatrickbool __cxx_atomic_compare_exchange_strong(__cxx_atomic_base_impl<_Tp> * __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT { 99276d0caaeSpatrick 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))); 99346035553Spatrick} 99446035553Spatrick 99546035553Spatricktemplate<class _Tp> 99646035553Spatrick_LIBCPP_INLINE_VISIBILITY 99746035553Spatrickbool __cxx_atomic_compare_exchange_weak(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT { 99876d0caaeSpatrick 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))); 99946035553Spatrick} 100046035553Spatricktemplate<class _Tp> 100146035553Spatrick_LIBCPP_INLINE_VISIBILITY 100246035553Spatrickbool __cxx_atomic_compare_exchange_weak(__cxx_atomic_base_impl<_Tp> * __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT { 100376d0caaeSpatrick 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))); 100446035553Spatrick} 100546035553Spatrick 100646035553Spatricktemplate<class _Tp> 100746035553Spatrick_LIBCPP_INLINE_VISIBILITY 100846035553Spatrick_Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __delta, memory_order __order) _NOEXCEPT { 100946035553Spatrick return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order)); 101046035553Spatrick} 101146035553Spatricktemplate<class _Tp> 101246035553Spatrick_LIBCPP_INLINE_VISIBILITY 101346035553Spatrick_Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp> * __a, _Tp __delta, memory_order __order) _NOEXCEPT { 101446035553Spatrick return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order)); 101546035553Spatrick} 101646035553Spatrick 101746035553Spatricktemplate<class _Tp> 101846035553Spatrick_LIBCPP_INLINE_VISIBILITY 101946035553Spatrick_Tp* __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp*> volatile* __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT { 102046035553Spatrick return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order)); 102146035553Spatrick} 102246035553Spatricktemplate<class _Tp> 102346035553Spatrick_LIBCPP_INLINE_VISIBILITY 102446035553Spatrick_Tp* __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp*> * __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT { 102546035553Spatrick return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order)); 102646035553Spatrick} 102746035553Spatrick 102846035553Spatricktemplate<class _Tp> 102946035553Spatrick_LIBCPP_INLINE_VISIBILITY 103046035553Spatrick_Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __delta, memory_order __order) _NOEXCEPT { 103146035553Spatrick return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order)); 103246035553Spatrick} 103346035553Spatricktemplate<class _Tp> 103446035553Spatrick_LIBCPP_INLINE_VISIBILITY 103546035553Spatrick_Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp> * __a, _Tp __delta, memory_order __order) _NOEXCEPT { 103646035553Spatrick return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order)); 103746035553Spatrick} 103846035553Spatricktemplate<class _Tp> 103946035553Spatrick_LIBCPP_INLINE_VISIBILITY 104046035553Spatrick_Tp* __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp*> volatile* __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT { 104146035553Spatrick return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order)); 104246035553Spatrick} 104346035553Spatricktemplate<class _Tp> 104446035553Spatrick_LIBCPP_INLINE_VISIBILITY 104546035553Spatrick_Tp* __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp*> * __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT { 104646035553Spatrick return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order)); 104746035553Spatrick} 104846035553Spatrick 104946035553Spatricktemplate<class _Tp> 105046035553Spatrick_LIBCPP_INLINE_VISIBILITY 105146035553Spatrick_Tp __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT { 105246035553Spatrick return __c11_atomic_fetch_and(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order)); 105346035553Spatrick} 105446035553Spatricktemplate<class _Tp> 105546035553Spatrick_LIBCPP_INLINE_VISIBILITY 105646035553Spatrick_Tp __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, memory_order __order) _NOEXCEPT { 105746035553Spatrick return __c11_atomic_fetch_and(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order)); 105846035553Spatrick} 105946035553Spatrick 106046035553Spatricktemplate<class _Tp> 106146035553Spatrick_LIBCPP_INLINE_VISIBILITY 106246035553Spatrick_Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT { 106346035553Spatrick return __c11_atomic_fetch_or(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order)); 106446035553Spatrick} 106546035553Spatricktemplate<class _Tp> 106646035553Spatrick_LIBCPP_INLINE_VISIBILITY 106746035553Spatrick_Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, memory_order __order) _NOEXCEPT { 106846035553Spatrick return __c11_atomic_fetch_or(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order)); 106946035553Spatrick} 107046035553Spatrick 107146035553Spatricktemplate<class _Tp> 107246035553Spatrick_LIBCPP_INLINE_VISIBILITY 107346035553Spatrick_Tp __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT { 107446035553Spatrick return __c11_atomic_fetch_xor(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order)); 107546035553Spatrick} 107646035553Spatricktemplate<class _Tp> 107746035553Spatrick_LIBCPP_INLINE_VISIBILITY 107846035553Spatrick_Tp __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, memory_order __order) _NOEXCEPT { 107946035553Spatrick return __c11_atomic_fetch_xor(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order)); 108046035553Spatrick} 108146035553Spatrick 108246035553Spatrick#endif // _LIBCPP_HAS_GCC_ATOMIC_IMP, _LIBCPP_HAS_C_ATOMIC_IMP 108346035553Spatrick 108446035553Spatricktemplate <class _Tp> 108546035553Spatrick_LIBCPP_INLINE_VISIBILITY 108646035553Spatrick_Tp kill_dependency(_Tp __y) _NOEXCEPT 108746035553Spatrick{ 108846035553Spatrick return __y; 108946035553Spatrick} 109046035553Spatrick 109146035553Spatrick#if defined(__CLANG_ATOMIC_BOOL_LOCK_FREE) 109246035553Spatrick# define ATOMIC_BOOL_LOCK_FREE __CLANG_ATOMIC_BOOL_LOCK_FREE 109346035553Spatrick# define ATOMIC_CHAR_LOCK_FREE __CLANG_ATOMIC_CHAR_LOCK_FREE 109476d0caaeSpatrick#ifndef _LIBCPP_HAS_NO_CHAR8_T 109576d0caaeSpatrick# define ATOMIC_CHAR8_T_LOCK_FREE __CLANG_ATOMIC_CHAR8_T_LOCK_FREE 109676d0caaeSpatrick#endif 109746035553Spatrick# define ATOMIC_CHAR16_T_LOCK_FREE __CLANG_ATOMIC_CHAR16_T_LOCK_FREE 109846035553Spatrick# define ATOMIC_CHAR32_T_LOCK_FREE __CLANG_ATOMIC_CHAR32_T_LOCK_FREE 109946035553Spatrick# define ATOMIC_WCHAR_T_LOCK_FREE __CLANG_ATOMIC_WCHAR_T_LOCK_FREE 110046035553Spatrick# define ATOMIC_SHORT_LOCK_FREE __CLANG_ATOMIC_SHORT_LOCK_FREE 110146035553Spatrick# define ATOMIC_INT_LOCK_FREE __CLANG_ATOMIC_INT_LOCK_FREE 110246035553Spatrick# define ATOMIC_LONG_LOCK_FREE __CLANG_ATOMIC_LONG_LOCK_FREE 110346035553Spatrick# define ATOMIC_LLONG_LOCK_FREE __CLANG_ATOMIC_LLONG_LOCK_FREE 110446035553Spatrick# define ATOMIC_POINTER_LOCK_FREE __CLANG_ATOMIC_POINTER_LOCK_FREE 110546035553Spatrick#elif defined(__GCC_ATOMIC_BOOL_LOCK_FREE) 110646035553Spatrick# define ATOMIC_BOOL_LOCK_FREE __GCC_ATOMIC_BOOL_LOCK_FREE 110746035553Spatrick# define ATOMIC_CHAR_LOCK_FREE __GCC_ATOMIC_CHAR_LOCK_FREE 110876d0caaeSpatrick#ifndef _LIBCPP_HAS_NO_CHAR8_T 110976d0caaeSpatrick# define ATOMIC_CHAR8_T_LOCK_FREE __GCC_ATOMIC_CHAR8_T_LOCK_FREE 111076d0caaeSpatrick#endif 111146035553Spatrick# define ATOMIC_CHAR16_T_LOCK_FREE __GCC_ATOMIC_CHAR16_T_LOCK_FREE 111246035553Spatrick# define ATOMIC_CHAR32_T_LOCK_FREE __GCC_ATOMIC_CHAR32_T_LOCK_FREE 111346035553Spatrick# define ATOMIC_WCHAR_T_LOCK_FREE __GCC_ATOMIC_WCHAR_T_LOCK_FREE 111446035553Spatrick# define ATOMIC_SHORT_LOCK_FREE __GCC_ATOMIC_SHORT_LOCK_FREE 111546035553Spatrick# define ATOMIC_INT_LOCK_FREE __GCC_ATOMIC_INT_LOCK_FREE 111646035553Spatrick# define ATOMIC_LONG_LOCK_FREE __GCC_ATOMIC_LONG_LOCK_FREE 111746035553Spatrick# define ATOMIC_LLONG_LOCK_FREE __GCC_ATOMIC_LLONG_LOCK_FREE 111846035553Spatrick# define ATOMIC_POINTER_LOCK_FREE __GCC_ATOMIC_POINTER_LOCK_FREE 111946035553Spatrick#endif 112046035553Spatrick 1121*4bdff4beSroberttemplate <class _Tp> 1122*4bdff4beSrobertstruct __libcpp_is_always_lock_free { 1123*4bdff4beSrobert // __atomic_always_lock_free is available in all Standard modes 1124*4bdff4beSrobert static const bool __value = __atomic_always_lock_free(sizeof(_Tp), 0); 1125*4bdff4beSrobert}; 1126*4bdff4beSrobert 112746035553Spatrick#ifdef _LIBCPP_ATOMIC_ONLY_USE_BUILTINS 112846035553Spatrick 112946035553Spatricktemplate<typename _Tp> 113046035553Spatrickstruct __cxx_atomic_lock_impl { 113146035553Spatrick 113246035553Spatrick _LIBCPP_INLINE_VISIBILITY 113346035553Spatrick __cxx_atomic_lock_impl() _NOEXCEPT 113446035553Spatrick : __a_value(), __a_lock(0) {} 113546035553Spatrick _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR explicit 113646035553Spatrick __cxx_atomic_lock_impl(_Tp value) _NOEXCEPT 113746035553Spatrick : __a_value(value), __a_lock(0) {} 113846035553Spatrick 113946035553Spatrick _Tp __a_value; 114046035553Spatrick mutable __cxx_atomic_base_impl<_LIBCPP_ATOMIC_FLAG_TYPE> __a_lock; 114146035553Spatrick 114246035553Spatrick _LIBCPP_INLINE_VISIBILITY void __lock() const volatile { 114346035553Spatrick while(1 == __cxx_atomic_exchange(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(true), memory_order_acquire)) 114446035553Spatrick /*spin*/; 114546035553Spatrick } 114646035553Spatrick _LIBCPP_INLINE_VISIBILITY void __lock() const { 114746035553Spatrick while(1 == __cxx_atomic_exchange(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(true), memory_order_acquire)) 114846035553Spatrick /*spin*/; 114946035553Spatrick } 115046035553Spatrick _LIBCPP_INLINE_VISIBILITY void __unlock() const volatile { 115146035553Spatrick __cxx_atomic_store(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(false), memory_order_release); 115246035553Spatrick } 115346035553Spatrick _LIBCPP_INLINE_VISIBILITY void __unlock() const { 115446035553Spatrick __cxx_atomic_store(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(false), memory_order_release); 115546035553Spatrick } 115646035553Spatrick _LIBCPP_INLINE_VISIBILITY _Tp __read() const volatile { 115746035553Spatrick __lock(); 115846035553Spatrick _Tp __old; 115946035553Spatrick __cxx_atomic_assign_volatile(__old, __a_value); 116046035553Spatrick __unlock(); 116146035553Spatrick return __old; 116246035553Spatrick } 116346035553Spatrick _LIBCPP_INLINE_VISIBILITY _Tp __read() const { 116446035553Spatrick __lock(); 116546035553Spatrick _Tp __old = __a_value; 116646035553Spatrick __unlock(); 116746035553Spatrick return __old; 116846035553Spatrick } 116946035553Spatrick}; 117046035553Spatrick 117146035553Spatricktemplate <typename _Tp> 117246035553Spatrick_LIBCPP_INLINE_VISIBILITY 117346035553Spatrickvoid __cxx_atomic_init(volatile __cxx_atomic_lock_impl<_Tp>* __a, _Tp __val) { 117446035553Spatrick __cxx_atomic_assign_volatile(__a->__a_value, __val); 117546035553Spatrick} 117646035553Spatricktemplate <typename _Tp> 117746035553Spatrick_LIBCPP_INLINE_VISIBILITY 117846035553Spatrickvoid __cxx_atomic_init(__cxx_atomic_lock_impl<_Tp>* __a, _Tp __val) { 117946035553Spatrick __a->__a_value = __val; 118046035553Spatrick} 118146035553Spatrick 118246035553Spatricktemplate <typename _Tp> 118346035553Spatrick_LIBCPP_INLINE_VISIBILITY 118446035553Spatrickvoid __cxx_atomic_store(volatile __cxx_atomic_lock_impl<_Tp>* __a, _Tp __val, memory_order) { 118546035553Spatrick __a->__lock(); 118646035553Spatrick __cxx_atomic_assign_volatile(__a->__a_value, __val); 118746035553Spatrick __a->__unlock(); 118846035553Spatrick} 118946035553Spatricktemplate <typename _Tp> 119046035553Spatrick_LIBCPP_INLINE_VISIBILITY 119146035553Spatrickvoid __cxx_atomic_store(__cxx_atomic_lock_impl<_Tp>* __a, _Tp __val, memory_order) { 119246035553Spatrick __a->__lock(); 119346035553Spatrick __a->__a_value = __val; 119446035553Spatrick __a->__unlock(); 119546035553Spatrick} 119646035553Spatrick 119746035553Spatricktemplate <typename _Tp> 119846035553Spatrick_LIBCPP_INLINE_VISIBILITY 119946035553Spatrick_Tp __cxx_atomic_load(const volatile __cxx_atomic_lock_impl<_Tp>* __a, memory_order) { 120046035553Spatrick return __a->__read(); 120146035553Spatrick} 120246035553Spatricktemplate <typename _Tp> 120346035553Spatrick_LIBCPP_INLINE_VISIBILITY 120446035553Spatrick_Tp __cxx_atomic_load(const __cxx_atomic_lock_impl<_Tp>* __a, memory_order) { 120546035553Spatrick return __a->__read(); 120646035553Spatrick} 120746035553Spatrick 120846035553Spatricktemplate <typename _Tp> 120946035553Spatrick_LIBCPP_INLINE_VISIBILITY 121046035553Spatrick_Tp __cxx_atomic_exchange(volatile __cxx_atomic_lock_impl<_Tp>* __a, _Tp __value, memory_order) { 121146035553Spatrick __a->__lock(); 121246035553Spatrick _Tp __old; 121346035553Spatrick __cxx_atomic_assign_volatile(__old, __a->__a_value); 121446035553Spatrick __cxx_atomic_assign_volatile(__a->__a_value, __value); 121546035553Spatrick __a->__unlock(); 121646035553Spatrick return __old; 121746035553Spatrick} 121846035553Spatricktemplate <typename _Tp> 121946035553Spatrick_LIBCPP_INLINE_VISIBILITY 122046035553Spatrick_Tp __cxx_atomic_exchange(__cxx_atomic_lock_impl<_Tp>* __a, _Tp __value, memory_order) { 122146035553Spatrick __a->__lock(); 122246035553Spatrick _Tp __old = __a->__a_value; 122346035553Spatrick __a->__a_value = __value; 122446035553Spatrick __a->__unlock(); 122546035553Spatrick return __old; 122646035553Spatrick} 122746035553Spatrick 122846035553Spatricktemplate <typename _Tp> 122946035553Spatrick_LIBCPP_INLINE_VISIBILITY 123046035553Spatrickbool __cxx_atomic_compare_exchange_strong(volatile __cxx_atomic_lock_impl<_Tp>* __a, 123146035553Spatrick _Tp* __expected, _Tp __value, memory_order, memory_order) { 1232037e7968Spatrick _Tp __temp; 123376d0caaeSpatrick __a->__lock(); 1234037e7968Spatrick __cxx_atomic_assign_volatile(__temp, __a->__a_value); 123576d0caaeSpatrick bool __ret = (_VSTD::memcmp(&__temp, __expected, sizeof(_Tp)) == 0); 123646035553Spatrick if(__ret) 123746035553Spatrick __cxx_atomic_assign_volatile(__a->__a_value, __value); 123846035553Spatrick else 123946035553Spatrick __cxx_atomic_assign_volatile(*__expected, __a->__a_value); 124046035553Spatrick __a->__unlock(); 124146035553Spatrick return __ret; 124246035553Spatrick} 124346035553Spatricktemplate <typename _Tp> 124446035553Spatrick_LIBCPP_INLINE_VISIBILITY 124546035553Spatrickbool __cxx_atomic_compare_exchange_strong(__cxx_atomic_lock_impl<_Tp>* __a, 124646035553Spatrick _Tp* __expected, _Tp __value, memory_order, memory_order) { 124746035553Spatrick __a->__lock(); 124876d0caaeSpatrick bool __ret = (_VSTD::memcmp(&__a->__a_value, __expected, sizeof(_Tp)) == 0); 124946035553Spatrick if(__ret) 125076d0caaeSpatrick _VSTD::memcpy(&__a->__a_value, &__value, sizeof(_Tp)); 125146035553Spatrick else 125276d0caaeSpatrick _VSTD::memcpy(__expected, &__a->__a_value, sizeof(_Tp)); 125346035553Spatrick __a->__unlock(); 125446035553Spatrick return __ret; 125546035553Spatrick} 125646035553Spatrick 125746035553Spatricktemplate <typename _Tp> 125846035553Spatrick_LIBCPP_INLINE_VISIBILITY 125946035553Spatrickbool __cxx_atomic_compare_exchange_weak(volatile __cxx_atomic_lock_impl<_Tp>* __a, 126046035553Spatrick _Tp* __expected, _Tp __value, memory_order, memory_order) { 1261037e7968Spatrick _Tp __temp; 126276d0caaeSpatrick __a->__lock(); 1263037e7968Spatrick __cxx_atomic_assign_volatile(__temp, __a->__a_value); 126476d0caaeSpatrick bool __ret = (_VSTD::memcmp(&__temp, __expected, sizeof(_Tp)) == 0); 126546035553Spatrick if(__ret) 126646035553Spatrick __cxx_atomic_assign_volatile(__a->__a_value, __value); 126746035553Spatrick else 126846035553Spatrick __cxx_atomic_assign_volatile(*__expected, __a->__a_value); 126946035553Spatrick __a->__unlock(); 127046035553Spatrick return __ret; 127146035553Spatrick} 127246035553Spatricktemplate <typename _Tp> 127346035553Spatrick_LIBCPP_INLINE_VISIBILITY 127446035553Spatrickbool __cxx_atomic_compare_exchange_weak(__cxx_atomic_lock_impl<_Tp>* __a, 127546035553Spatrick _Tp* __expected, _Tp __value, memory_order, memory_order) { 127646035553Spatrick __a->__lock(); 127776d0caaeSpatrick bool __ret = (_VSTD::memcmp(&__a->__a_value, __expected, sizeof(_Tp)) == 0); 127846035553Spatrick if(__ret) 127976d0caaeSpatrick _VSTD::memcpy(&__a->__a_value, &__value, sizeof(_Tp)); 128046035553Spatrick else 128176d0caaeSpatrick _VSTD::memcpy(__expected, &__a->__a_value, sizeof(_Tp)); 128246035553Spatrick __a->__unlock(); 128346035553Spatrick return __ret; 128446035553Spatrick} 128546035553Spatrick 128646035553Spatricktemplate <typename _Tp, typename _Td> 128746035553Spatrick_LIBCPP_INLINE_VISIBILITY 128846035553Spatrick_Tp __cxx_atomic_fetch_add(volatile __cxx_atomic_lock_impl<_Tp>* __a, 128946035553Spatrick _Td __delta, memory_order) { 129046035553Spatrick __a->__lock(); 129146035553Spatrick _Tp __old; 129246035553Spatrick __cxx_atomic_assign_volatile(__old, __a->__a_value); 129346035553Spatrick __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old + __delta)); 129446035553Spatrick __a->__unlock(); 129546035553Spatrick return __old; 129646035553Spatrick} 129746035553Spatricktemplate <typename _Tp, typename _Td> 129846035553Spatrick_LIBCPP_INLINE_VISIBILITY 129946035553Spatrick_Tp __cxx_atomic_fetch_add(__cxx_atomic_lock_impl<_Tp>* __a, 130046035553Spatrick _Td __delta, memory_order) { 130146035553Spatrick __a->__lock(); 130246035553Spatrick _Tp __old = __a->__a_value; 130346035553Spatrick __a->__a_value += __delta; 130446035553Spatrick __a->__unlock(); 130546035553Spatrick return __old; 130646035553Spatrick} 130746035553Spatrick 130846035553Spatricktemplate <typename _Tp, typename _Td> 130946035553Spatrick_LIBCPP_INLINE_VISIBILITY 131046035553Spatrick_Tp* __cxx_atomic_fetch_add(volatile __cxx_atomic_lock_impl<_Tp*>* __a, 131146035553Spatrick ptrdiff_t __delta, memory_order) { 131246035553Spatrick __a->__lock(); 131346035553Spatrick _Tp* __old; 131446035553Spatrick __cxx_atomic_assign_volatile(__old, __a->__a_value); 131546035553Spatrick __cxx_atomic_assign_volatile(__a->__a_value, __old + __delta); 131646035553Spatrick __a->__unlock(); 131746035553Spatrick return __old; 131846035553Spatrick} 131946035553Spatricktemplate <typename _Tp, typename _Td> 132046035553Spatrick_LIBCPP_INLINE_VISIBILITY 132146035553Spatrick_Tp* __cxx_atomic_fetch_add(__cxx_atomic_lock_impl<_Tp*>* __a, 132246035553Spatrick ptrdiff_t __delta, memory_order) { 132346035553Spatrick __a->__lock(); 132446035553Spatrick _Tp* __old = __a->__a_value; 132546035553Spatrick __a->__a_value += __delta; 132646035553Spatrick __a->__unlock(); 132746035553Spatrick return __old; 132846035553Spatrick} 132946035553Spatrick 133046035553Spatricktemplate <typename _Tp, typename _Td> 133146035553Spatrick_LIBCPP_INLINE_VISIBILITY 133246035553Spatrick_Tp __cxx_atomic_fetch_sub(volatile __cxx_atomic_lock_impl<_Tp>* __a, 133346035553Spatrick _Td __delta, memory_order) { 133446035553Spatrick __a->__lock(); 133546035553Spatrick _Tp __old; 133646035553Spatrick __cxx_atomic_assign_volatile(__old, __a->__a_value); 133746035553Spatrick __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old - __delta)); 133846035553Spatrick __a->__unlock(); 133946035553Spatrick return __old; 134046035553Spatrick} 134146035553Spatricktemplate <typename _Tp, typename _Td> 134246035553Spatrick_LIBCPP_INLINE_VISIBILITY 134346035553Spatrick_Tp __cxx_atomic_fetch_sub(__cxx_atomic_lock_impl<_Tp>* __a, 134446035553Spatrick _Td __delta, memory_order) { 134546035553Spatrick __a->__lock(); 134646035553Spatrick _Tp __old = __a->__a_value; 134746035553Spatrick __a->__a_value -= __delta; 134846035553Spatrick __a->__unlock(); 134946035553Spatrick return __old; 135046035553Spatrick} 135146035553Spatrick 135246035553Spatricktemplate <typename _Tp> 135346035553Spatrick_LIBCPP_INLINE_VISIBILITY 135446035553Spatrick_Tp __cxx_atomic_fetch_and(volatile __cxx_atomic_lock_impl<_Tp>* __a, 135546035553Spatrick _Tp __pattern, memory_order) { 135646035553Spatrick __a->__lock(); 135746035553Spatrick _Tp __old; 135846035553Spatrick __cxx_atomic_assign_volatile(__old, __a->__a_value); 135946035553Spatrick __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old & __pattern)); 136046035553Spatrick __a->__unlock(); 136146035553Spatrick return __old; 136246035553Spatrick} 136346035553Spatricktemplate <typename _Tp> 136446035553Spatrick_LIBCPP_INLINE_VISIBILITY 136546035553Spatrick_Tp __cxx_atomic_fetch_and(__cxx_atomic_lock_impl<_Tp>* __a, 136646035553Spatrick _Tp __pattern, memory_order) { 136746035553Spatrick __a->__lock(); 136846035553Spatrick _Tp __old = __a->__a_value; 136946035553Spatrick __a->__a_value &= __pattern; 137046035553Spatrick __a->__unlock(); 137146035553Spatrick return __old; 137246035553Spatrick} 137346035553Spatrick 137446035553Spatricktemplate <typename _Tp> 137546035553Spatrick_LIBCPP_INLINE_VISIBILITY 137646035553Spatrick_Tp __cxx_atomic_fetch_or(volatile __cxx_atomic_lock_impl<_Tp>* __a, 137746035553Spatrick _Tp __pattern, memory_order) { 137846035553Spatrick __a->__lock(); 137946035553Spatrick _Tp __old; 138046035553Spatrick __cxx_atomic_assign_volatile(__old, __a->__a_value); 138146035553Spatrick __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old | __pattern)); 138246035553Spatrick __a->__unlock(); 138346035553Spatrick return __old; 138446035553Spatrick} 138546035553Spatricktemplate <typename _Tp> 138646035553Spatrick_LIBCPP_INLINE_VISIBILITY 138746035553Spatrick_Tp __cxx_atomic_fetch_or(__cxx_atomic_lock_impl<_Tp>* __a, 138846035553Spatrick _Tp __pattern, memory_order) { 138946035553Spatrick __a->__lock(); 139046035553Spatrick _Tp __old = __a->__a_value; 139146035553Spatrick __a->__a_value |= __pattern; 139246035553Spatrick __a->__unlock(); 139346035553Spatrick return __old; 139446035553Spatrick} 139546035553Spatrick 139646035553Spatricktemplate <typename _Tp> 139746035553Spatrick_LIBCPP_INLINE_VISIBILITY 139846035553Spatrick_Tp __cxx_atomic_fetch_xor(volatile __cxx_atomic_lock_impl<_Tp>* __a, 139946035553Spatrick _Tp __pattern, memory_order) { 140046035553Spatrick __a->__lock(); 140146035553Spatrick _Tp __old; 140246035553Spatrick __cxx_atomic_assign_volatile(__old, __a->__a_value); 140346035553Spatrick __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old ^ __pattern)); 140446035553Spatrick __a->__unlock(); 140546035553Spatrick return __old; 140646035553Spatrick} 140746035553Spatricktemplate <typename _Tp> 140846035553Spatrick_LIBCPP_INLINE_VISIBILITY 140946035553Spatrick_Tp __cxx_atomic_fetch_xor(__cxx_atomic_lock_impl<_Tp>* __a, 141046035553Spatrick _Tp __pattern, memory_order) { 141146035553Spatrick __a->__lock(); 141246035553Spatrick _Tp __old = __a->__a_value; 141346035553Spatrick __a->__a_value ^= __pattern; 141446035553Spatrick __a->__unlock(); 141546035553Spatrick return __old; 141646035553Spatrick} 141746035553Spatrick 141846035553Spatricktemplate <typename _Tp, 1419*4bdff4beSrobert typename _Base = typename conditional<__libcpp_is_always_lock_free<_Tp>::__value, 142046035553Spatrick __cxx_atomic_base_impl<_Tp>, 142146035553Spatrick __cxx_atomic_lock_impl<_Tp> >::type> 142246035553Spatrick#else 142346035553Spatricktemplate <typename _Tp, 142446035553Spatrick typename _Base = __cxx_atomic_base_impl<_Tp> > 142546035553Spatrick#endif //_LIBCPP_ATOMIC_ONLY_USE_BUILTINS 142646035553Spatrickstruct __cxx_atomic_impl : public _Base { 142746035553Spatrick static_assert(is_trivially_copyable<_Tp>::value, 1428*4bdff4beSrobert "std::atomic<T> requires that 'T' be a trivially copyable type"); 142946035553Spatrick 1430*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY __cxx_atomic_impl() _NOEXCEPT = default; 1431*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR explicit __cxx_atomic_impl(_Tp __value) _NOEXCEPT 1432*4bdff4beSrobert : _Base(__value) {} 143346035553Spatrick}; 143446035553Spatrick 1435*4bdff4beSrobert#if defined(__linux__) || (defined(_AIX) && !defined(__64BIT__)) 1436037e7968Spatrick using __cxx_contention_t = int32_t; 1437037e7968Spatrick#else 1438037e7968Spatrick using __cxx_contention_t = int64_t; 1439*4bdff4beSrobert#endif // __linux__ || (_AIX && !__64BIT__) 1440037e7968Spatrick 1441037e7968Spatrickusing __cxx_atomic_contention_t = __cxx_atomic_impl<__cxx_contention_t>; 1442037e7968Spatrick 1443*4bdff4beSrobert#ifndef _LIBCPP_HAS_NO_THREADS 1444037e7968Spatrick 1445037e7968Spatrick_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_one(void const volatile*); 1446037e7968Spatrick_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_all(void const volatile*); 1447037e7968Spatrick_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t __libcpp_atomic_monitor(void const volatile*); 1448037e7968Spatrick_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __libcpp_atomic_wait(void const volatile*, __cxx_contention_t); 1449037e7968Spatrick 1450037e7968Spatrick_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_one(__cxx_atomic_contention_t const volatile*); 1451037e7968Spatrick_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_all(__cxx_atomic_contention_t const volatile*); 1452037e7968Spatrick_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI __cxx_contention_t __libcpp_atomic_monitor(__cxx_atomic_contention_t const volatile*); 1453037e7968Spatrick_LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __libcpp_atomic_wait(__cxx_atomic_contention_t const volatile*, __cxx_contention_t); 1454037e7968Spatrick 1455037e7968Spatricktemplate <class _Atp, class _Fn> 1456037e7968Spatrickstruct __libcpp_atomic_wait_backoff_impl { 1457037e7968Spatrick _Atp* __a; 1458037e7968Spatrick _Fn __test_fn; 1459037e7968Spatrick _LIBCPP_AVAILABILITY_SYNC 1460037e7968Spatrick _LIBCPP_INLINE_VISIBILITY bool operator()(chrono::nanoseconds __elapsed) const 1461037e7968Spatrick { 1462037e7968Spatrick if(__elapsed > chrono::microseconds(64)) 1463037e7968Spatrick { 1464*4bdff4beSrobert auto const __monitor = std::__libcpp_atomic_monitor(__a); 1465037e7968Spatrick if(__test_fn()) 1466037e7968Spatrick return true; 1467*4bdff4beSrobert std::__libcpp_atomic_wait(__a, __monitor); 1468037e7968Spatrick } 1469037e7968Spatrick else if(__elapsed > chrono::microseconds(4)) 1470037e7968Spatrick __libcpp_thread_yield(); 1471037e7968Spatrick else 147276d0caaeSpatrick {} // poll 1473037e7968Spatrick return false; 1474037e7968Spatrick } 1475037e7968Spatrick}; 1476037e7968Spatrick 1477037e7968Spatricktemplate <class _Atp, class _Fn> 1478037e7968Spatrick_LIBCPP_AVAILABILITY_SYNC 1479037e7968Spatrick_LIBCPP_INLINE_VISIBILITY bool __cxx_atomic_wait(_Atp* __a, _Fn && __test_fn) 1480037e7968Spatrick{ 1481037e7968Spatrick __libcpp_atomic_wait_backoff_impl<_Atp, typename decay<_Fn>::type> __backoff_fn = {__a, __test_fn}; 1482*4bdff4beSrobert return std::__libcpp_thread_poll_with_backoff(__test_fn, __backoff_fn); 1483037e7968Spatrick} 1484037e7968Spatrick 1485*4bdff4beSrobert#else // _LIBCPP_HAS_NO_THREADS 1486037e7968Spatrick 1487037e7968Spatricktemplate <class _Tp> 1488037e7968Spatrick_LIBCPP_INLINE_VISIBILITY void __cxx_atomic_notify_all(__cxx_atomic_impl<_Tp> const volatile*) { } 1489037e7968Spatricktemplate <class _Tp> 1490037e7968Spatrick_LIBCPP_INLINE_VISIBILITY void __cxx_atomic_notify_one(__cxx_atomic_impl<_Tp> const volatile*) { } 1491037e7968Spatricktemplate <class _Atp, class _Fn> 1492037e7968Spatrick_LIBCPP_INLINE_VISIBILITY bool __cxx_atomic_wait(_Atp*, _Fn && __test_fn) 1493037e7968Spatrick{ 1494*4bdff4beSrobert return __libcpp_thread_poll_with_backoff(__test_fn, __spinning_backoff_policy()); 1495037e7968Spatrick} 1496037e7968Spatrick 1497*4bdff4beSrobert#endif // _LIBCPP_HAS_NO_THREADS 1498037e7968Spatrick 1499037e7968Spatricktemplate <class _Atp, class _Tp> 1500037e7968Spatrickstruct __cxx_atomic_wait_test_fn_impl { 1501037e7968Spatrick _Atp* __a; 1502037e7968Spatrick _Tp __val; 1503037e7968Spatrick memory_order __order; 1504037e7968Spatrick _LIBCPP_INLINE_VISIBILITY bool operator()() const 1505037e7968Spatrick { 1506*4bdff4beSrobert return !std::__cxx_nonatomic_compare_equal(std::__cxx_atomic_load(__a, __order), __val); 1507037e7968Spatrick } 1508037e7968Spatrick}; 1509037e7968Spatrick 1510037e7968Spatricktemplate <class _Atp, class _Tp> 1511037e7968Spatrick_LIBCPP_AVAILABILITY_SYNC 1512037e7968Spatrick_LIBCPP_INLINE_VISIBILITY bool __cxx_atomic_wait(_Atp* __a, _Tp const __val, memory_order __order) 1513037e7968Spatrick{ 1514037e7968Spatrick __cxx_atomic_wait_test_fn_impl<_Atp, _Tp> __test_fn = {__a, __val, __order}; 1515*4bdff4beSrobert return std::__cxx_atomic_wait(__a, __test_fn); 1516037e7968Spatrick} 1517037e7968Spatrick 151846035553Spatrick// general atomic<T> 151946035553Spatrick 152046035553Spatricktemplate <class _Tp, bool = is_integral<_Tp>::value && !is_same<_Tp, bool>::value> 152146035553Spatrickstruct __atomic_base // false 152246035553Spatrick{ 152346035553Spatrick mutable __cxx_atomic_impl<_Tp> __a_; 152446035553Spatrick 152546035553Spatrick#if defined(__cpp_lib_atomic_is_always_lock_free) 1526*4bdff4beSrobert static _LIBCPP_CONSTEXPR bool is_always_lock_free = __libcpp_is_always_lock_free<__cxx_atomic_impl<_Tp> >::__value; 152746035553Spatrick#endif 152846035553Spatrick 152946035553Spatrick _LIBCPP_INLINE_VISIBILITY 153046035553Spatrick bool is_lock_free() const volatile _NOEXCEPT 153146035553Spatrick {return __cxx_atomic_is_lock_free(sizeof(_Tp));} 153246035553Spatrick _LIBCPP_INLINE_VISIBILITY 153346035553Spatrick bool is_lock_free() const _NOEXCEPT 153446035553Spatrick {return static_cast<__atomic_base const volatile*>(this)->is_lock_free();} 153546035553Spatrick _LIBCPP_INLINE_VISIBILITY 153646035553Spatrick void store(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT 153746035553Spatrick _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) 1538*4bdff4beSrobert {std::__cxx_atomic_store(&__a_, __d, __m);} 153946035553Spatrick _LIBCPP_INLINE_VISIBILITY 154046035553Spatrick void store(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT 154146035553Spatrick _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) 1542*4bdff4beSrobert {std::__cxx_atomic_store(&__a_, __d, __m);} 154346035553Spatrick _LIBCPP_INLINE_VISIBILITY 154446035553Spatrick _Tp load(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT 154546035553Spatrick _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) 1546*4bdff4beSrobert {return std::__cxx_atomic_load(&__a_, __m);} 154746035553Spatrick _LIBCPP_INLINE_VISIBILITY 154846035553Spatrick _Tp load(memory_order __m = memory_order_seq_cst) const _NOEXCEPT 154946035553Spatrick _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) 1550*4bdff4beSrobert {return std::__cxx_atomic_load(&__a_, __m);} 155146035553Spatrick _LIBCPP_INLINE_VISIBILITY 155246035553Spatrick operator _Tp() const volatile _NOEXCEPT {return load();} 155346035553Spatrick _LIBCPP_INLINE_VISIBILITY 155446035553Spatrick operator _Tp() const _NOEXCEPT {return load();} 155546035553Spatrick _LIBCPP_INLINE_VISIBILITY 155646035553Spatrick _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT 1557*4bdff4beSrobert {return std::__cxx_atomic_exchange(&__a_, __d, __m);} 155846035553Spatrick _LIBCPP_INLINE_VISIBILITY 155946035553Spatrick _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT 1560*4bdff4beSrobert {return std::__cxx_atomic_exchange(&__a_, __d, __m);} 156146035553Spatrick _LIBCPP_INLINE_VISIBILITY 156246035553Spatrick bool compare_exchange_weak(_Tp& __e, _Tp __d, 156346035553Spatrick memory_order __s, memory_order __f) volatile _NOEXCEPT 156446035553Spatrick _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) 1565*4bdff4beSrobert {return std::__cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);} 156646035553Spatrick _LIBCPP_INLINE_VISIBILITY 156746035553Spatrick bool compare_exchange_weak(_Tp& __e, _Tp __d, 156846035553Spatrick memory_order __s, memory_order __f) _NOEXCEPT 156946035553Spatrick _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) 1570*4bdff4beSrobert {return std::__cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);} 157146035553Spatrick _LIBCPP_INLINE_VISIBILITY 157246035553Spatrick bool compare_exchange_strong(_Tp& __e, _Tp __d, 157346035553Spatrick memory_order __s, memory_order __f) volatile _NOEXCEPT 157446035553Spatrick _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) 1575*4bdff4beSrobert {return std::__cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);} 157646035553Spatrick _LIBCPP_INLINE_VISIBILITY 157746035553Spatrick bool compare_exchange_strong(_Tp& __e, _Tp __d, 157846035553Spatrick memory_order __s, memory_order __f) _NOEXCEPT 157946035553Spatrick _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) 1580*4bdff4beSrobert {return std::__cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);} 158146035553Spatrick _LIBCPP_INLINE_VISIBILITY 158246035553Spatrick bool compare_exchange_weak(_Tp& __e, _Tp __d, 158346035553Spatrick memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT 1584*4bdff4beSrobert {return std::__cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);} 158546035553Spatrick _LIBCPP_INLINE_VISIBILITY 158646035553Spatrick bool compare_exchange_weak(_Tp& __e, _Tp __d, 158746035553Spatrick memory_order __m = memory_order_seq_cst) _NOEXCEPT 1588*4bdff4beSrobert {return std::__cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);} 158946035553Spatrick _LIBCPP_INLINE_VISIBILITY 159046035553Spatrick bool compare_exchange_strong(_Tp& __e, _Tp __d, 159146035553Spatrick memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT 1592*4bdff4beSrobert {return std::__cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);} 159346035553Spatrick _LIBCPP_INLINE_VISIBILITY 159446035553Spatrick bool compare_exchange_strong(_Tp& __e, _Tp __d, 159546035553Spatrick memory_order __m = memory_order_seq_cst) _NOEXCEPT 1596*4bdff4beSrobert {return std::__cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);} 159746035553Spatrick 1598037e7968Spatrick _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void wait(_Tp __v, memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT 1599*4bdff4beSrobert {std::__cxx_atomic_wait(&__a_, __v, __m);} 1600037e7968Spatrick _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void wait(_Tp __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT 1601*4bdff4beSrobert {std::__cxx_atomic_wait(&__a_, __v, __m);} 1602037e7968Spatrick _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_one() volatile _NOEXCEPT 1603*4bdff4beSrobert {std::__cxx_atomic_notify_one(&__a_);} 1604037e7968Spatrick _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_one() _NOEXCEPT 1605*4bdff4beSrobert {std::__cxx_atomic_notify_one(&__a_);} 1606037e7968Spatrick _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_all() volatile _NOEXCEPT 1607*4bdff4beSrobert {std::__cxx_atomic_notify_all(&__a_);} 1608037e7968Spatrick _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY void notify_all() _NOEXCEPT 1609*4bdff4beSrobert {std::__cxx_atomic_notify_all(&__a_);} 1610037e7968Spatrick 161176d0caaeSpatrick#if _LIBCPP_STD_VER > 17 161276d0caaeSpatrick _LIBCPP_INLINE_VISIBILITY constexpr 161376d0caaeSpatrick __atomic_base() noexcept(is_nothrow_default_constructible_v<_Tp>) : __a_(_Tp()) {} 161476d0caaeSpatrick#else 161546035553Spatrick _LIBCPP_INLINE_VISIBILITY 1616*4bdff4beSrobert __atomic_base() _NOEXCEPT = default; 161776d0caaeSpatrick#endif 161846035553Spatrick 161946035553Spatrick _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 162046035553Spatrick __atomic_base(_Tp __d) _NOEXCEPT : __a_(__d) {} 162146035553Spatrick 162246035553Spatrick __atomic_base(const __atomic_base&) = delete; 162346035553Spatrick}; 162446035553Spatrick 162546035553Spatrick#if defined(__cpp_lib_atomic_is_always_lock_free) 162646035553Spatricktemplate <class _Tp, bool __b> 162746035553Spatrick_LIBCPP_CONSTEXPR bool __atomic_base<_Tp, __b>::is_always_lock_free; 162846035553Spatrick#endif 162946035553Spatrick 163046035553Spatrick// atomic<Integral> 163146035553Spatrick 163246035553Spatricktemplate <class _Tp> 163346035553Spatrickstruct __atomic_base<_Tp, true> 163446035553Spatrick : public __atomic_base<_Tp, false> 163546035553Spatrick{ 163646035553Spatrick typedef __atomic_base<_Tp, false> __base; 163776d0caaeSpatrick 1638*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20 1639*4bdff4beSrobert __atomic_base() _NOEXCEPT = default; 164076d0caaeSpatrick 164146035553Spatrick _LIBCPP_INLINE_VISIBILITY 164246035553Spatrick _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __base(__d) {} 164346035553Spatrick 164446035553Spatrick _LIBCPP_INLINE_VISIBILITY 164546035553Spatrick _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT 1646*4bdff4beSrobert {return std::__cxx_atomic_fetch_add(&this->__a_, __op, __m);} 164746035553Spatrick _LIBCPP_INLINE_VISIBILITY 164846035553Spatrick _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT 1649*4bdff4beSrobert {return std::__cxx_atomic_fetch_add(&this->__a_, __op, __m);} 165046035553Spatrick _LIBCPP_INLINE_VISIBILITY 165146035553Spatrick _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT 1652*4bdff4beSrobert {return std::__cxx_atomic_fetch_sub(&this->__a_, __op, __m);} 165346035553Spatrick _LIBCPP_INLINE_VISIBILITY 165446035553Spatrick _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT 1655*4bdff4beSrobert {return std::__cxx_atomic_fetch_sub(&this->__a_, __op, __m);} 165646035553Spatrick _LIBCPP_INLINE_VISIBILITY 165746035553Spatrick _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT 1658*4bdff4beSrobert {return std::__cxx_atomic_fetch_and(&this->__a_, __op, __m);} 165946035553Spatrick _LIBCPP_INLINE_VISIBILITY 166046035553Spatrick _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT 1661*4bdff4beSrobert {return std::__cxx_atomic_fetch_and(&this->__a_, __op, __m);} 166246035553Spatrick _LIBCPP_INLINE_VISIBILITY 166346035553Spatrick _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT 1664*4bdff4beSrobert {return std::__cxx_atomic_fetch_or(&this->__a_, __op, __m);} 166546035553Spatrick _LIBCPP_INLINE_VISIBILITY 166646035553Spatrick _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT 1667*4bdff4beSrobert {return std::__cxx_atomic_fetch_or(&this->__a_, __op, __m);} 166846035553Spatrick _LIBCPP_INLINE_VISIBILITY 166946035553Spatrick _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT 1670*4bdff4beSrobert {return std::__cxx_atomic_fetch_xor(&this->__a_, __op, __m);} 167146035553Spatrick _LIBCPP_INLINE_VISIBILITY 167246035553Spatrick _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT 1673*4bdff4beSrobert {return std::__cxx_atomic_fetch_xor(&this->__a_, __op, __m);} 167446035553Spatrick 167546035553Spatrick _LIBCPP_INLINE_VISIBILITY 167646035553Spatrick _Tp operator++(int) volatile _NOEXCEPT {return fetch_add(_Tp(1));} 167746035553Spatrick _LIBCPP_INLINE_VISIBILITY 167846035553Spatrick _Tp operator++(int) _NOEXCEPT {return fetch_add(_Tp(1));} 167946035553Spatrick _LIBCPP_INLINE_VISIBILITY 168046035553Spatrick _Tp operator--(int) volatile _NOEXCEPT {return fetch_sub(_Tp(1));} 168146035553Spatrick _LIBCPP_INLINE_VISIBILITY 168246035553Spatrick _Tp operator--(int) _NOEXCEPT {return fetch_sub(_Tp(1));} 168346035553Spatrick _LIBCPP_INLINE_VISIBILITY 168446035553Spatrick _Tp operator++() volatile _NOEXCEPT {return fetch_add(_Tp(1)) + _Tp(1);} 168546035553Spatrick _LIBCPP_INLINE_VISIBILITY 168646035553Spatrick _Tp operator++() _NOEXCEPT {return fetch_add(_Tp(1)) + _Tp(1);} 168746035553Spatrick _LIBCPP_INLINE_VISIBILITY 168846035553Spatrick _Tp operator--() volatile _NOEXCEPT {return fetch_sub(_Tp(1)) - _Tp(1);} 168946035553Spatrick _LIBCPP_INLINE_VISIBILITY 169046035553Spatrick _Tp operator--() _NOEXCEPT {return fetch_sub(_Tp(1)) - _Tp(1);} 169146035553Spatrick _LIBCPP_INLINE_VISIBILITY 169246035553Spatrick _Tp operator+=(_Tp __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;} 169346035553Spatrick _LIBCPP_INLINE_VISIBILITY 169446035553Spatrick _Tp operator+=(_Tp __op) _NOEXCEPT {return fetch_add(__op) + __op;} 169546035553Spatrick _LIBCPP_INLINE_VISIBILITY 169646035553Spatrick _Tp operator-=(_Tp __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;} 169746035553Spatrick _LIBCPP_INLINE_VISIBILITY 169846035553Spatrick _Tp operator-=(_Tp __op) _NOEXCEPT {return fetch_sub(__op) - __op;} 169946035553Spatrick _LIBCPP_INLINE_VISIBILITY 170046035553Spatrick _Tp operator&=(_Tp __op) volatile _NOEXCEPT {return fetch_and(__op) & __op;} 170146035553Spatrick _LIBCPP_INLINE_VISIBILITY 170246035553Spatrick _Tp operator&=(_Tp __op) _NOEXCEPT {return fetch_and(__op) & __op;} 170346035553Spatrick _LIBCPP_INLINE_VISIBILITY 170446035553Spatrick _Tp operator|=(_Tp __op) volatile _NOEXCEPT {return fetch_or(__op) | __op;} 170546035553Spatrick _LIBCPP_INLINE_VISIBILITY 170646035553Spatrick _Tp operator|=(_Tp __op) _NOEXCEPT {return fetch_or(__op) | __op;} 170746035553Spatrick _LIBCPP_INLINE_VISIBILITY 170846035553Spatrick _Tp operator^=(_Tp __op) volatile _NOEXCEPT {return fetch_xor(__op) ^ __op;} 170946035553Spatrick _LIBCPP_INLINE_VISIBILITY 171046035553Spatrick _Tp operator^=(_Tp __op) _NOEXCEPT {return fetch_xor(__op) ^ __op;} 171146035553Spatrick}; 171246035553Spatrick 171346035553Spatrick// atomic<T> 171446035553Spatrick 171546035553Spatricktemplate <class _Tp> 171646035553Spatrickstruct atomic 171746035553Spatrick : public __atomic_base<_Tp> 171846035553Spatrick{ 171946035553Spatrick typedef __atomic_base<_Tp> __base; 1720037e7968Spatrick typedef _Tp value_type; 172176d0caaeSpatrick typedef value_type difference_type; 172276d0caaeSpatrick 172376d0caaeSpatrick#if _LIBCPP_STD_VER > 17 172476d0caaeSpatrick _LIBCPP_INLINE_VISIBILITY 172576d0caaeSpatrick atomic() = default; 172676d0caaeSpatrick#else 172746035553Spatrick _LIBCPP_INLINE_VISIBILITY 1728*4bdff4beSrobert atomic() _NOEXCEPT = default; 172976d0caaeSpatrick#endif 173076d0caaeSpatrick 173146035553Spatrick _LIBCPP_INLINE_VISIBILITY 173246035553Spatrick _LIBCPP_CONSTEXPR atomic(_Tp __d) _NOEXCEPT : __base(__d) {} 173346035553Spatrick 173446035553Spatrick _LIBCPP_INLINE_VISIBILITY 173546035553Spatrick _Tp operator=(_Tp __d) volatile _NOEXCEPT 173646035553Spatrick {__base::store(__d); return __d;} 173746035553Spatrick _LIBCPP_INLINE_VISIBILITY 173846035553Spatrick _Tp operator=(_Tp __d) _NOEXCEPT 173946035553Spatrick {__base::store(__d); return __d;} 174076d0caaeSpatrick 174176d0caaeSpatrick atomic& operator=(const atomic&) = delete; 174276d0caaeSpatrick atomic& operator=(const atomic&) volatile = delete; 174346035553Spatrick}; 174446035553Spatrick 174546035553Spatrick// atomic<T*> 174646035553Spatrick 174746035553Spatricktemplate <class _Tp> 174846035553Spatrickstruct atomic<_Tp*> 174946035553Spatrick : public __atomic_base<_Tp*> 175046035553Spatrick{ 175146035553Spatrick typedef __atomic_base<_Tp*> __base; 1752037e7968Spatrick typedef _Tp* value_type; 175376d0caaeSpatrick typedef ptrdiff_t difference_type; 175476d0caaeSpatrick 175546035553Spatrick _LIBCPP_INLINE_VISIBILITY 1756*4bdff4beSrobert atomic() _NOEXCEPT = default; 175776d0caaeSpatrick 175846035553Spatrick _LIBCPP_INLINE_VISIBILITY 175946035553Spatrick _LIBCPP_CONSTEXPR atomic(_Tp* __d) _NOEXCEPT : __base(__d) {} 176046035553Spatrick 176146035553Spatrick _LIBCPP_INLINE_VISIBILITY 176246035553Spatrick _Tp* operator=(_Tp* __d) volatile _NOEXCEPT 176346035553Spatrick {__base::store(__d); return __d;} 176446035553Spatrick _LIBCPP_INLINE_VISIBILITY 176546035553Spatrick _Tp* operator=(_Tp* __d) _NOEXCEPT 176646035553Spatrick {__base::store(__d); return __d;} 176746035553Spatrick 176846035553Spatrick _LIBCPP_INLINE_VISIBILITY 1769*4bdff4beSrobert _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT { 1770*4bdff4beSrobert // __atomic_fetch_add accepts function pointers, guard against them. 1771*4bdff4beSrobert static_assert(!is_function<__remove_pointer_t<_Tp> >::value, "Pointer to function isn't allowed"); 1772*4bdff4beSrobert return std::__cxx_atomic_fetch_add(&this->__a_, __op, __m); 1773*4bdff4beSrobert } 1774*4bdff4beSrobert 177546035553Spatrick _LIBCPP_INLINE_VISIBILITY 1776*4bdff4beSrobert _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT { 1777*4bdff4beSrobert // __atomic_fetch_add accepts function pointers, guard against them. 1778*4bdff4beSrobert static_assert(!is_function<__remove_pointer_t<_Tp> >::value, "Pointer to function isn't allowed"); 1779*4bdff4beSrobert return std::__cxx_atomic_fetch_add(&this->__a_, __op, __m); 1780*4bdff4beSrobert } 1781*4bdff4beSrobert 178246035553Spatrick _LIBCPP_INLINE_VISIBILITY 1783*4bdff4beSrobert _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT { 1784*4bdff4beSrobert // __atomic_fetch_add accepts function pointers, guard against them. 1785*4bdff4beSrobert static_assert(!is_function<__remove_pointer_t<_Tp> >::value, "Pointer to function isn't allowed"); 1786*4bdff4beSrobert return std::__cxx_atomic_fetch_sub(&this->__a_, __op, __m); 1787*4bdff4beSrobert } 1788*4bdff4beSrobert 178946035553Spatrick _LIBCPP_INLINE_VISIBILITY 1790*4bdff4beSrobert _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT { 1791*4bdff4beSrobert // __atomic_fetch_add accepts function pointers, guard against them. 1792*4bdff4beSrobert static_assert(!is_function<__remove_pointer_t<_Tp> >::value, "Pointer to function isn't allowed"); 1793*4bdff4beSrobert return std::__cxx_atomic_fetch_sub(&this->__a_, __op, __m); 1794*4bdff4beSrobert } 179546035553Spatrick 179646035553Spatrick _LIBCPP_INLINE_VISIBILITY 179746035553Spatrick _Tp* operator++(int) volatile _NOEXCEPT {return fetch_add(1);} 179846035553Spatrick _LIBCPP_INLINE_VISIBILITY 179946035553Spatrick _Tp* operator++(int) _NOEXCEPT {return fetch_add(1);} 180046035553Spatrick _LIBCPP_INLINE_VISIBILITY 180146035553Spatrick _Tp* operator--(int) volatile _NOEXCEPT {return fetch_sub(1);} 180246035553Spatrick _LIBCPP_INLINE_VISIBILITY 180346035553Spatrick _Tp* operator--(int) _NOEXCEPT {return fetch_sub(1);} 180446035553Spatrick _LIBCPP_INLINE_VISIBILITY 180546035553Spatrick _Tp* operator++() volatile _NOEXCEPT {return fetch_add(1) + 1;} 180646035553Spatrick _LIBCPP_INLINE_VISIBILITY 180746035553Spatrick _Tp* operator++() _NOEXCEPT {return fetch_add(1) + 1;} 180846035553Spatrick _LIBCPP_INLINE_VISIBILITY 180946035553Spatrick _Tp* operator--() volatile _NOEXCEPT {return fetch_sub(1) - 1;} 181046035553Spatrick _LIBCPP_INLINE_VISIBILITY 181146035553Spatrick _Tp* operator--() _NOEXCEPT {return fetch_sub(1) - 1;} 181246035553Spatrick _LIBCPP_INLINE_VISIBILITY 181346035553Spatrick _Tp* operator+=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;} 181446035553Spatrick _LIBCPP_INLINE_VISIBILITY 181546035553Spatrick _Tp* operator+=(ptrdiff_t __op) _NOEXCEPT {return fetch_add(__op) + __op;} 181646035553Spatrick _LIBCPP_INLINE_VISIBILITY 181746035553Spatrick _Tp* operator-=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;} 181846035553Spatrick _LIBCPP_INLINE_VISIBILITY 181946035553Spatrick _Tp* operator-=(ptrdiff_t __op) _NOEXCEPT {return fetch_sub(__op) - __op;} 182076d0caaeSpatrick 182176d0caaeSpatrick atomic& operator=(const atomic&) = delete; 182276d0caaeSpatrick atomic& operator=(const atomic&) volatile = delete; 182346035553Spatrick}; 182446035553Spatrick 182546035553Spatrick// atomic_is_lock_free 182646035553Spatrick 182746035553Spatricktemplate <class _Tp> 182846035553Spatrick_LIBCPP_INLINE_VISIBILITY 182946035553Spatrickbool 183046035553Spatrickatomic_is_lock_free(const volatile atomic<_Tp>* __o) _NOEXCEPT 183146035553Spatrick{ 183246035553Spatrick return __o->is_lock_free(); 183346035553Spatrick} 183446035553Spatrick 183546035553Spatricktemplate <class _Tp> 183646035553Spatrick_LIBCPP_INLINE_VISIBILITY 183746035553Spatrickbool 183846035553Spatrickatomic_is_lock_free(const atomic<_Tp>* __o) _NOEXCEPT 183946035553Spatrick{ 184046035553Spatrick return __o->is_lock_free(); 184146035553Spatrick} 184246035553Spatrick 184346035553Spatrick// atomic_init 184446035553Spatrick 184546035553Spatricktemplate <class _Tp> 184676d0caaeSpatrick_LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_INLINE_VISIBILITY 184746035553Spatrickvoid 184876d0caaeSpatrickatomic_init(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT 184946035553Spatrick{ 1850*4bdff4beSrobert std::__cxx_atomic_init(&__o->__a_, __d); 185146035553Spatrick} 185246035553Spatrick 185346035553Spatricktemplate <class _Tp> 185476d0caaeSpatrick_LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_INLINE_VISIBILITY 185546035553Spatrickvoid 185676d0caaeSpatrickatomic_init(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT 185746035553Spatrick{ 1858*4bdff4beSrobert std::__cxx_atomic_init(&__o->__a_, __d); 185946035553Spatrick} 186046035553Spatrick 186146035553Spatrick// atomic_store 186246035553Spatrick 186346035553Spatricktemplate <class _Tp> 186446035553Spatrick_LIBCPP_INLINE_VISIBILITY 186546035553Spatrickvoid 186676d0caaeSpatrickatomic_store(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT 186746035553Spatrick{ 186846035553Spatrick __o->store(__d); 186946035553Spatrick} 187046035553Spatrick 187146035553Spatricktemplate <class _Tp> 187246035553Spatrick_LIBCPP_INLINE_VISIBILITY 187346035553Spatrickvoid 187476d0caaeSpatrickatomic_store(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT 187546035553Spatrick{ 187646035553Spatrick __o->store(__d); 187746035553Spatrick} 187846035553Spatrick 187946035553Spatrick// atomic_store_explicit 188046035553Spatrick 188146035553Spatricktemplate <class _Tp> 188246035553Spatrick_LIBCPP_INLINE_VISIBILITY 188346035553Spatrickvoid 188476d0caaeSpatrickatomic_store_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT 188546035553Spatrick _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) 188646035553Spatrick{ 188746035553Spatrick __o->store(__d, __m); 188846035553Spatrick} 188946035553Spatrick 189046035553Spatricktemplate <class _Tp> 189146035553Spatrick_LIBCPP_INLINE_VISIBILITY 189246035553Spatrickvoid 189376d0caaeSpatrickatomic_store_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT 189446035553Spatrick _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) 189546035553Spatrick{ 189646035553Spatrick __o->store(__d, __m); 189746035553Spatrick} 189846035553Spatrick 189946035553Spatrick// atomic_load 190046035553Spatrick 190146035553Spatricktemplate <class _Tp> 190246035553Spatrick_LIBCPP_INLINE_VISIBILITY 190346035553Spatrick_Tp 190446035553Spatrickatomic_load(const volatile atomic<_Tp>* __o) _NOEXCEPT 190546035553Spatrick{ 190646035553Spatrick return __o->load(); 190746035553Spatrick} 190846035553Spatrick 190946035553Spatricktemplate <class _Tp> 191046035553Spatrick_LIBCPP_INLINE_VISIBILITY 191146035553Spatrick_Tp 191246035553Spatrickatomic_load(const atomic<_Tp>* __o) _NOEXCEPT 191346035553Spatrick{ 191446035553Spatrick return __o->load(); 191546035553Spatrick} 191646035553Spatrick 191746035553Spatrick// atomic_load_explicit 191846035553Spatrick 191946035553Spatricktemplate <class _Tp> 192046035553Spatrick_LIBCPP_INLINE_VISIBILITY 192146035553Spatrick_Tp 192246035553Spatrickatomic_load_explicit(const volatile atomic<_Tp>* __o, memory_order __m) _NOEXCEPT 192346035553Spatrick _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) 192446035553Spatrick{ 192546035553Spatrick return __o->load(__m); 192646035553Spatrick} 192746035553Spatrick 192846035553Spatricktemplate <class _Tp> 192946035553Spatrick_LIBCPP_INLINE_VISIBILITY 193046035553Spatrick_Tp 193146035553Spatrickatomic_load_explicit(const atomic<_Tp>* __o, memory_order __m) _NOEXCEPT 193246035553Spatrick _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) 193346035553Spatrick{ 193446035553Spatrick return __o->load(__m); 193546035553Spatrick} 193646035553Spatrick 193746035553Spatrick// atomic_exchange 193846035553Spatrick 193946035553Spatricktemplate <class _Tp> 194046035553Spatrick_LIBCPP_INLINE_VISIBILITY 194146035553Spatrick_Tp 194276d0caaeSpatrickatomic_exchange(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT 194346035553Spatrick{ 194446035553Spatrick return __o->exchange(__d); 194546035553Spatrick} 194646035553Spatrick 194746035553Spatricktemplate <class _Tp> 194846035553Spatrick_LIBCPP_INLINE_VISIBILITY 194946035553Spatrick_Tp 195076d0caaeSpatrickatomic_exchange(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT 195146035553Spatrick{ 195246035553Spatrick return __o->exchange(__d); 195346035553Spatrick} 195446035553Spatrick 195546035553Spatrick// atomic_exchange_explicit 195646035553Spatrick 195746035553Spatricktemplate <class _Tp> 195846035553Spatrick_LIBCPP_INLINE_VISIBILITY 195946035553Spatrick_Tp 196076d0caaeSpatrickatomic_exchange_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT 196146035553Spatrick{ 196246035553Spatrick return __o->exchange(__d, __m); 196346035553Spatrick} 196446035553Spatrick 196546035553Spatricktemplate <class _Tp> 196646035553Spatrick_LIBCPP_INLINE_VISIBILITY 196746035553Spatrick_Tp 196876d0caaeSpatrickatomic_exchange_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT 196946035553Spatrick{ 197046035553Spatrick return __o->exchange(__d, __m); 197146035553Spatrick} 197246035553Spatrick 197346035553Spatrick// atomic_compare_exchange_weak 197446035553Spatrick 197546035553Spatricktemplate <class _Tp> 197646035553Spatrick_LIBCPP_INLINE_VISIBILITY 197746035553Spatrickbool 197876d0caaeSpatrickatomic_compare_exchange_weak(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT 197946035553Spatrick{ 198046035553Spatrick return __o->compare_exchange_weak(*__e, __d); 198146035553Spatrick} 198246035553Spatrick 198346035553Spatricktemplate <class _Tp> 198446035553Spatrick_LIBCPP_INLINE_VISIBILITY 198546035553Spatrickbool 198676d0caaeSpatrickatomic_compare_exchange_weak(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT 198746035553Spatrick{ 198846035553Spatrick return __o->compare_exchange_weak(*__e, __d); 198946035553Spatrick} 199046035553Spatrick 199146035553Spatrick// atomic_compare_exchange_strong 199246035553Spatrick 199346035553Spatricktemplate <class _Tp> 199446035553Spatrick_LIBCPP_INLINE_VISIBILITY 199546035553Spatrickbool 199676d0caaeSpatrickatomic_compare_exchange_strong(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT 199746035553Spatrick{ 199846035553Spatrick return __o->compare_exchange_strong(*__e, __d); 199946035553Spatrick} 200046035553Spatrick 200146035553Spatricktemplate <class _Tp> 200246035553Spatrick_LIBCPP_INLINE_VISIBILITY 200346035553Spatrickbool 200476d0caaeSpatrickatomic_compare_exchange_strong(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT 200546035553Spatrick{ 200646035553Spatrick return __o->compare_exchange_strong(*__e, __d); 200746035553Spatrick} 200846035553Spatrick 200946035553Spatrick// atomic_compare_exchange_weak_explicit 201046035553Spatrick 201146035553Spatricktemplate <class _Tp> 201246035553Spatrick_LIBCPP_INLINE_VISIBILITY 201346035553Spatrickbool 201476d0caaeSpatrickatomic_compare_exchange_weak_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, 201576d0caaeSpatrick typename atomic<_Tp>::value_type __d, 201646035553Spatrick memory_order __s, memory_order __f) _NOEXCEPT 201746035553Spatrick _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) 201846035553Spatrick{ 201946035553Spatrick return __o->compare_exchange_weak(*__e, __d, __s, __f); 202046035553Spatrick} 202146035553Spatrick 202246035553Spatricktemplate <class _Tp> 202346035553Spatrick_LIBCPP_INLINE_VISIBILITY 202446035553Spatrickbool 202576d0caaeSpatrickatomic_compare_exchange_weak_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d, 202646035553Spatrick memory_order __s, memory_order __f) _NOEXCEPT 202746035553Spatrick _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) 202846035553Spatrick{ 202946035553Spatrick return __o->compare_exchange_weak(*__e, __d, __s, __f); 203046035553Spatrick} 203146035553Spatrick 203246035553Spatrick// atomic_compare_exchange_strong_explicit 203346035553Spatrick 203446035553Spatricktemplate <class _Tp> 203546035553Spatrick_LIBCPP_INLINE_VISIBILITY 203646035553Spatrickbool 203746035553Spatrickatomic_compare_exchange_strong_explicit(volatile atomic<_Tp>* __o, 203876d0caaeSpatrick typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d, 203946035553Spatrick memory_order __s, memory_order __f) _NOEXCEPT 204046035553Spatrick _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) 204146035553Spatrick{ 204246035553Spatrick return __o->compare_exchange_strong(*__e, __d, __s, __f); 204346035553Spatrick} 204446035553Spatrick 204546035553Spatricktemplate <class _Tp> 204646035553Spatrick_LIBCPP_INLINE_VISIBILITY 204746035553Spatrickbool 204876d0caaeSpatrickatomic_compare_exchange_strong_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, 204976d0caaeSpatrick typename atomic<_Tp>::value_type __d, 205046035553Spatrick memory_order __s, memory_order __f) _NOEXCEPT 205146035553Spatrick _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) 205246035553Spatrick{ 205346035553Spatrick return __o->compare_exchange_strong(*__e, __d, __s, __f); 205446035553Spatrick} 205546035553Spatrick 2056037e7968Spatrick// atomic_wait 2057037e7968Spatrick 2058037e7968Spatricktemplate <class _Tp> 2059037e7968Spatrick_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY 2060037e7968Spatrickvoid atomic_wait(const volatile atomic<_Tp>* __o, 2061037e7968Spatrick typename atomic<_Tp>::value_type __v) _NOEXCEPT 2062037e7968Spatrick{ 2063037e7968Spatrick return __o->wait(__v); 2064037e7968Spatrick} 2065037e7968Spatrick 2066037e7968Spatricktemplate <class _Tp> 2067037e7968Spatrick_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY 2068037e7968Spatrickvoid atomic_wait(const atomic<_Tp>* __o, 2069037e7968Spatrick typename atomic<_Tp>::value_type __v) _NOEXCEPT 2070037e7968Spatrick{ 2071037e7968Spatrick return __o->wait(__v); 2072037e7968Spatrick} 2073037e7968Spatrick 2074037e7968Spatrick// atomic_wait_explicit 2075037e7968Spatrick 2076037e7968Spatricktemplate <class _Tp> 2077037e7968Spatrick_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY 2078037e7968Spatrickvoid atomic_wait_explicit(const volatile atomic<_Tp>* __o, 2079037e7968Spatrick typename atomic<_Tp>::value_type __v, 2080037e7968Spatrick memory_order __m) _NOEXCEPT 2081037e7968Spatrick _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) 2082037e7968Spatrick{ 2083037e7968Spatrick return __o->wait(__v, __m); 2084037e7968Spatrick} 2085037e7968Spatrick 2086037e7968Spatricktemplate <class _Tp> 2087037e7968Spatrick_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY 2088037e7968Spatrickvoid atomic_wait_explicit(const atomic<_Tp>* __o, 2089037e7968Spatrick typename atomic<_Tp>::value_type __v, 2090037e7968Spatrick memory_order __m) _NOEXCEPT 2091037e7968Spatrick _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) 2092037e7968Spatrick{ 2093037e7968Spatrick return __o->wait(__v, __m); 2094037e7968Spatrick} 2095037e7968Spatrick 2096037e7968Spatrick// atomic_notify_one 2097037e7968Spatrick 2098037e7968Spatricktemplate <class _Tp> 2099037e7968Spatrick_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY 2100037e7968Spatrickvoid atomic_notify_one(volatile atomic<_Tp>* __o) _NOEXCEPT 2101037e7968Spatrick{ 2102037e7968Spatrick __o->notify_one(); 2103037e7968Spatrick} 2104037e7968Spatricktemplate <class _Tp> 2105037e7968Spatrick_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY 2106037e7968Spatrickvoid atomic_notify_one(atomic<_Tp>* __o) _NOEXCEPT 2107037e7968Spatrick{ 2108037e7968Spatrick __o->notify_one(); 2109037e7968Spatrick} 2110037e7968Spatrick 2111*4bdff4beSrobert// atomic_notify_all 2112037e7968Spatrick 2113037e7968Spatricktemplate <class _Tp> 2114037e7968Spatrick_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY 2115037e7968Spatrickvoid atomic_notify_all(volatile atomic<_Tp>* __o) _NOEXCEPT 2116037e7968Spatrick{ 2117037e7968Spatrick __o->notify_all(); 2118037e7968Spatrick} 2119037e7968Spatricktemplate <class _Tp> 2120037e7968Spatrick_LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY 2121037e7968Spatrickvoid atomic_notify_all(atomic<_Tp>* __o) _NOEXCEPT 2122037e7968Spatrick{ 2123037e7968Spatrick __o->notify_all(); 2124037e7968Spatrick} 2125037e7968Spatrick 212646035553Spatrick// atomic_fetch_add 212746035553Spatrick 212846035553Spatricktemplate <class _Tp> 212946035553Spatrick_LIBCPP_INLINE_VISIBILITY 213046035553Spatrick_Tp 213176d0caaeSpatrickatomic_fetch_add(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT 213246035553Spatrick{ 213346035553Spatrick return __o->fetch_add(__op); 213446035553Spatrick} 213546035553Spatrick 213646035553Spatricktemplate <class _Tp> 213746035553Spatrick_LIBCPP_INLINE_VISIBILITY 213846035553Spatrick_Tp 213976d0caaeSpatrickatomic_fetch_add(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT 214046035553Spatrick{ 214146035553Spatrick return __o->fetch_add(__op); 214246035553Spatrick} 214346035553Spatrick 214446035553Spatrick// atomic_fetch_add_explicit 214546035553Spatrick 214646035553Spatricktemplate <class _Tp> 214746035553Spatrick_LIBCPP_INLINE_VISIBILITY 2148*4bdff4beSrobert_Tp atomic_fetch_add_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT 214946035553Spatrick{ 215046035553Spatrick return __o->fetch_add(__op, __m); 215146035553Spatrick} 215246035553Spatrick 215346035553Spatricktemplate <class _Tp> 215446035553Spatrick_LIBCPP_INLINE_VISIBILITY 2155*4bdff4beSrobert_Tp atomic_fetch_add_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT 215646035553Spatrick{ 215746035553Spatrick return __o->fetch_add(__op, __m); 215846035553Spatrick} 215946035553Spatrick 216046035553Spatrick// atomic_fetch_sub 216146035553Spatrick 216246035553Spatricktemplate <class _Tp> 216346035553Spatrick_LIBCPP_INLINE_VISIBILITY 2164*4bdff4beSrobert_Tp atomic_fetch_sub(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT 216546035553Spatrick{ 216646035553Spatrick return __o->fetch_sub(__op); 216746035553Spatrick} 216846035553Spatrick 216946035553Spatricktemplate <class _Tp> 217046035553Spatrick_LIBCPP_INLINE_VISIBILITY 2171*4bdff4beSrobert_Tp atomic_fetch_sub(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT 217246035553Spatrick{ 217346035553Spatrick return __o->fetch_sub(__op); 217446035553Spatrick} 217546035553Spatrick 217646035553Spatrick// atomic_fetch_sub_explicit 217746035553Spatrick 217846035553Spatricktemplate <class _Tp> 217946035553Spatrick_LIBCPP_INLINE_VISIBILITY 2180*4bdff4beSrobert_Tp atomic_fetch_sub_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT 218146035553Spatrick{ 218246035553Spatrick return __o->fetch_sub(__op, __m); 218346035553Spatrick} 218446035553Spatrick 218546035553Spatricktemplate <class _Tp> 218646035553Spatrick_LIBCPP_INLINE_VISIBILITY 2187*4bdff4beSrobert_Tp atomic_fetch_sub_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT 218846035553Spatrick{ 218946035553Spatrick return __o->fetch_sub(__op, __m); 219046035553Spatrick} 219146035553Spatrick 219246035553Spatrick// atomic_fetch_and 219346035553Spatrick 219446035553Spatricktemplate <class _Tp> 219546035553Spatrick_LIBCPP_INLINE_VISIBILITY 219646035553Spatricktypename enable_if 219746035553Spatrick< 219846035553Spatrick is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 219946035553Spatrick _Tp 220046035553Spatrick>::type 220176d0caaeSpatrickatomic_fetch_and(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT 220246035553Spatrick{ 220346035553Spatrick return __o->fetch_and(__op); 220446035553Spatrick} 220546035553Spatrick 220646035553Spatricktemplate <class _Tp> 220746035553Spatrick_LIBCPP_INLINE_VISIBILITY 220846035553Spatricktypename enable_if 220946035553Spatrick< 221046035553Spatrick is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 221146035553Spatrick _Tp 221246035553Spatrick>::type 221376d0caaeSpatrickatomic_fetch_and(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT 221446035553Spatrick{ 221546035553Spatrick return __o->fetch_and(__op); 221646035553Spatrick} 221746035553Spatrick 221846035553Spatrick// atomic_fetch_and_explicit 221946035553Spatrick 222046035553Spatricktemplate <class _Tp> 222146035553Spatrick_LIBCPP_INLINE_VISIBILITY 222246035553Spatricktypename enable_if 222346035553Spatrick< 222446035553Spatrick is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 222546035553Spatrick _Tp 222646035553Spatrick>::type 222776d0caaeSpatrickatomic_fetch_and_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT 222846035553Spatrick{ 222946035553Spatrick return __o->fetch_and(__op, __m); 223046035553Spatrick} 223146035553Spatrick 223246035553Spatricktemplate <class _Tp> 223346035553Spatrick_LIBCPP_INLINE_VISIBILITY 223446035553Spatricktypename enable_if 223546035553Spatrick< 223646035553Spatrick is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 223746035553Spatrick _Tp 223846035553Spatrick>::type 223976d0caaeSpatrickatomic_fetch_and_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT 224046035553Spatrick{ 224146035553Spatrick return __o->fetch_and(__op, __m); 224246035553Spatrick} 224346035553Spatrick 224446035553Spatrick// atomic_fetch_or 224546035553Spatrick 224646035553Spatricktemplate <class _Tp> 224746035553Spatrick_LIBCPP_INLINE_VISIBILITY 224846035553Spatricktypename enable_if 224946035553Spatrick< 225046035553Spatrick is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 225146035553Spatrick _Tp 225246035553Spatrick>::type 225376d0caaeSpatrickatomic_fetch_or(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT 225446035553Spatrick{ 225546035553Spatrick return __o->fetch_or(__op); 225646035553Spatrick} 225746035553Spatrick 225846035553Spatricktemplate <class _Tp> 225946035553Spatrick_LIBCPP_INLINE_VISIBILITY 226046035553Spatricktypename enable_if 226146035553Spatrick< 226246035553Spatrick is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 226346035553Spatrick _Tp 226446035553Spatrick>::type 226576d0caaeSpatrickatomic_fetch_or(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT 226646035553Spatrick{ 226746035553Spatrick return __o->fetch_or(__op); 226846035553Spatrick} 226946035553Spatrick 227046035553Spatrick// atomic_fetch_or_explicit 227146035553Spatrick 227246035553Spatricktemplate <class _Tp> 227346035553Spatrick_LIBCPP_INLINE_VISIBILITY 227446035553Spatricktypename enable_if 227546035553Spatrick< 227646035553Spatrick is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 227746035553Spatrick _Tp 227846035553Spatrick>::type 227976d0caaeSpatrickatomic_fetch_or_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT 228046035553Spatrick{ 228146035553Spatrick return __o->fetch_or(__op, __m); 228246035553Spatrick} 228346035553Spatrick 228446035553Spatricktemplate <class _Tp> 228546035553Spatrick_LIBCPP_INLINE_VISIBILITY 228646035553Spatricktypename enable_if 228746035553Spatrick< 228846035553Spatrick is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 228946035553Spatrick _Tp 229046035553Spatrick>::type 229176d0caaeSpatrickatomic_fetch_or_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT 229246035553Spatrick{ 229346035553Spatrick return __o->fetch_or(__op, __m); 229446035553Spatrick} 229546035553Spatrick 229646035553Spatrick// atomic_fetch_xor 229746035553Spatrick 229846035553Spatricktemplate <class _Tp> 229946035553Spatrick_LIBCPP_INLINE_VISIBILITY 230046035553Spatricktypename enable_if 230146035553Spatrick< 230246035553Spatrick is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 230346035553Spatrick _Tp 230446035553Spatrick>::type 230576d0caaeSpatrickatomic_fetch_xor(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT 230646035553Spatrick{ 230746035553Spatrick return __o->fetch_xor(__op); 230846035553Spatrick} 230946035553Spatrick 231046035553Spatricktemplate <class _Tp> 231146035553Spatrick_LIBCPP_INLINE_VISIBILITY 231246035553Spatricktypename enable_if 231346035553Spatrick< 231446035553Spatrick is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 231546035553Spatrick _Tp 231646035553Spatrick>::type 231776d0caaeSpatrickatomic_fetch_xor(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT 231846035553Spatrick{ 231946035553Spatrick return __o->fetch_xor(__op); 232046035553Spatrick} 232146035553Spatrick 232246035553Spatrick// atomic_fetch_xor_explicit 232346035553Spatrick 232446035553Spatricktemplate <class _Tp> 232546035553Spatrick_LIBCPP_INLINE_VISIBILITY 232646035553Spatricktypename enable_if 232746035553Spatrick< 232846035553Spatrick is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 232946035553Spatrick _Tp 233046035553Spatrick>::type 233176d0caaeSpatrickatomic_fetch_xor_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT 233246035553Spatrick{ 233346035553Spatrick return __o->fetch_xor(__op, __m); 233446035553Spatrick} 233546035553Spatrick 233646035553Spatricktemplate <class _Tp> 233746035553Spatrick_LIBCPP_INLINE_VISIBILITY 233846035553Spatricktypename enable_if 233946035553Spatrick< 234046035553Spatrick is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 234146035553Spatrick _Tp 234246035553Spatrick>::type 234376d0caaeSpatrickatomic_fetch_xor_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT 234446035553Spatrick{ 234546035553Spatrick return __o->fetch_xor(__op, __m); 234646035553Spatrick} 234746035553Spatrick 234846035553Spatrick// flag type and operations 234946035553Spatrick 235046035553Spatricktypedef struct atomic_flag 235146035553Spatrick{ 235246035553Spatrick __cxx_atomic_impl<_LIBCPP_ATOMIC_FLAG_TYPE> __a_; 235346035553Spatrick 235446035553Spatrick _LIBCPP_INLINE_VISIBILITY 2355037e7968Spatrick bool test(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT 2356037e7968Spatrick {return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m);} 2357037e7968Spatrick _LIBCPP_INLINE_VISIBILITY 2358037e7968Spatrick bool test(memory_order __m = memory_order_seq_cst) const _NOEXCEPT 2359037e7968Spatrick {return _LIBCPP_ATOMIC_FLAG_TYPE(true) == __cxx_atomic_load(&__a_, __m);} 2360037e7968Spatrick 2361037e7968Spatrick _LIBCPP_INLINE_VISIBILITY 236246035553Spatrick bool test_and_set(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT 236346035553Spatrick {return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);} 236446035553Spatrick _LIBCPP_INLINE_VISIBILITY 236546035553Spatrick bool test_and_set(memory_order __m = memory_order_seq_cst) _NOEXCEPT 236646035553Spatrick {return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);} 236746035553Spatrick _LIBCPP_INLINE_VISIBILITY 236846035553Spatrick void clear(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT 236946035553Spatrick {__cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);} 237046035553Spatrick _LIBCPP_INLINE_VISIBILITY 237146035553Spatrick void clear(memory_order __m = memory_order_seq_cst) _NOEXCEPT 237246035553Spatrick {__cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);} 237346035553Spatrick 2374037e7968Spatrick _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY 2375037e7968Spatrick void wait(bool __v, memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT 2376037e7968Spatrick {__cxx_atomic_wait(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);} 2377037e7968Spatrick _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY 2378037e7968Spatrick void wait(bool __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT 2379037e7968Spatrick {__cxx_atomic_wait(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(__v), __m);} 2380037e7968Spatrick _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY 2381037e7968Spatrick void notify_one() volatile _NOEXCEPT 2382037e7968Spatrick {__cxx_atomic_notify_one(&__a_);} 2383037e7968Spatrick _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY 2384037e7968Spatrick void notify_one() _NOEXCEPT 2385037e7968Spatrick {__cxx_atomic_notify_one(&__a_);} 2386037e7968Spatrick _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY 2387037e7968Spatrick void notify_all() volatile _NOEXCEPT 2388037e7968Spatrick {__cxx_atomic_notify_all(&__a_);} 2389037e7968Spatrick _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY 2390037e7968Spatrick void notify_all() _NOEXCEPT 2391037e7968Spatrick {__cxx_atomic_notify_all(&__a_);} 2392037e7968Spatrick 239376d0caaeSpatrick#if _LIBCPP_STD_VER > 17 239476d0caaeSpatrick _LIBCPP_INLINE_VISIBILITY constexpr 239576d0caaeSpatrick atomic_flag() _NOEXCEPT : __a_(false) {} 239676d0caaeSpatrick#else 239746035553Spatrick _LIBCPP_INLINE_VISIBILITY 2398*4bdff4beSrobert atomic_flag() _NOEXCEPT = default; 239976d0caaeSpatrick#endif 240046035553Spatrick 240146035553Spatrick _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 240246035553Spatrick atomic_flag(bool __b) _NOEXCEPT : __a_(__b) {} // EXTENSION 240346035553Spatrick 240446035553Spatrick atomic_flag(const atomic_flag&) = delete; 240546035553Spatrick atomic_flag& operator=(const atomic_flag&) = delete; 240646035553Spatrick atomic_flag& operator=(const atomic_flag&) volatile = delete; 2407*4bdff4beSrobert 240846035553Spatrick} atomic_flag; 240946035553Spatrick 2410037e7968Spatrick 2411037e7968Spatrickinline _LIBCPP_INLINE_VISIBILITY 2412037e7968Spatrickbool 2413037e7968Spatrickatomic_flag_test(const volatile atomic_flag* __o) _NOEXCEPT 2414037e7968Spatrick{ 2415037e7968Spatrick return __o->test(); 2416037e7968Spatrick} 2417037e7968Spatrick 2418037e7968Spatrickinline _LIBCPP_INLINE_VISIBILITY 2419037e7968Spatrickbool 2420037e7968Spatrickatomic_flag_test(const atomic_flag* __o) _NOEXCEPT 2421037e7968Spatrick{ 2422037e7968Spatrick return __o->test(); 2423037e7968Spatrick} 2424037e7968Spatrick 2425037e7968Spatrickinline _LIBCPP_INLINE_VISIBILITY 2426037e7968Spatrickbool 2427037e7968Spatrickatomic_flag_test_explicit(const volatile atomic_flag* __o, memory_order __m) _NOEXCEPT 2428037e7968Spatrick{ 2429037e7968Spatrick return __o->test(__m); 2430037e7968Spatrick} 2431037e7968Spatrick 2432037e7968Spatrickinline _LIBCPP_INLINE_VISIBILITY 2433037e7968Spatrickbool 2434037e7968Spatrickatomic_flag_test_explicit(const atomic_flag* __o, memory_order __m) _NOEXCEPT 2435037e7968Spatrick{ 2436037e7968Spatrick return __o->test(__m); 2437037e7968Spatrick} 2438037e7968Spatrick 243946035553Spatrickinline _LIBCPP_INLINE_VISIBILITY 244046035553Spatrickbool 244146035553Spatrickatomic_flag_test_and_set(volatile atomic_flag* __o) _NOEXCEPT 244246035553Spatrick{ 244346035553Spatrick return __o->test_and_set(); 244446035553Spatrick} 244546035553Spatrick 244646035553Spatrickinline _LIBCPP_INLINE_VISIBILITY 244746035553Spatrickbool 244846035553Spatrickatomic_flag_test_and_set(atomic_flag* __o) _NOEXCEPT 244946035553Spatrick{ 245046035553Spatrick return __o->test_and_set(); 245146035553Spatrick} 245246035553Spatrick 245346035553Spatrickinline _LIBCPP_INLINE_VISIBILITY 245446035553Spatrickbool 245546035553Spatrickatomic_flag_test_and_set_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT 245646035553Spatrick{ 245746035553Spatrick return __o->test_and_set(__m); 245846035553Spatrick} 245946035553Spatrick 246046035553Spatrickinline _LIBCPP_INLINE_VISIBILITY 246146035553Spatrickbool 246246035553Spatrickatomic_flag_test_and_set_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT 246346035553Spatrick{ 246446035553Spatrick return __o->test_and_set(__m); 246546035553Spatrick} 246646035553Spatrick 246746035553Spatrickinline _LIBCPP_INLINE_VISIBILITY 246846035553Spatrickvoid 246946035553Spatrickatomic_flag_clear(volatile atomic_flag* __o) _NOEXCEPT 247046035553Spatrick{ 247146035553Spatrick __o->clear(); 247246035553Spatrick} 247346035553Spatrick 247446035553Spatrickinline _LIBCPP_INLINE_VISIBILITY 247546035553Spatrickvoid 247646035553Spatrickatomic_flag_clear(atomic_flag* __o) _NOEXCEPT 247746035553Spatrick{ 247846035553Spatrick __o->clear(); 247946035553Spatrick} 248046035553Spatrick 248146035553Spatrickinline _LIBCPP_INLINE_VISIBILITY 248246035553Spatrickvoid 248346035553Spatrickatomic_flag_clear_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT 248446035553Spatrick{ 248546035553Spatrick __o->clear(__m); 248646035553Spatrick} 248746035553Spatrick 248846035553Spatrickinline _LIBCPP_INLINE_VISIBILITY 248946035553Spatrickvoid 249046035553Spatrickatomic_flag_clear_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT 249146035553Spatrick{ 249246035553Spatrick __o->clear(__m); 249346035553Spatrick} 249446035553Spatrick 2495037e7968Spatrickinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC 2496037e7968Spatrickvoid 2497037e7968Spatrickatomic_flag_wait(const volatile atomic_flag* __o, bool __v) _NOEXCEPT 2498037e7968Spatrick{ 2499037e7968Spatrick __o->wait(__v); 2500037e7968Spatrick} 2501037e7968Spatrick 2502037e7968Spatrickinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC 2503037e7968Spatrickvoid 2504037e7968Spatrickatomic_flag_wait(const atomic_flag* __o, bool __v) _NOEXCEPT 2505037e7968Spatrick{ 2506037e7968Spatrick __o->wait(__v); 2507037e7968Spatrick} 2508037e7968Spatrick 2509037e7968Spatrickinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC 2510037e7968Spatrickvoid 2511037e7968Spatrickatomic_flag_wait_explicit(const volatile atomic_flag* __o, 2512037e7968Spatrick bool __v, memory_order __m) _NOEXCEPT 2513037e7968Spatrick{ 2514037e7968Spatrick __o->wait(__v, __m); 2515037e7968Spatrick} 2516037e7968Spatrick 2517037e7968Spatrickinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC 2518037e7968Spatrickvoid 2519037e7968Spatrickatomic_flag_wait_explicit(const atomic_flag* __o, 2520037e7968Spatrick bool __v, memory_order __m) _NOEXCEPT 2521037e7968Spatrick{ 2522037e7968Spatrick __o->wait(__v, __m); 2523037e7968Spatrick} 2524037e7968Spatrick 2525037e7968Spatrickinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC 2526037e7968Spatrickvoid 2527037e7968Spatrickatomic_flag_notify_one(volatile atomic_flag* __o) _NOEXCEPT 2528037e7968Spatrick{ 2529037e7968Spatrick __o->notify_one(); 2530037e7968Spatrick} 2531037e7968Spatrick 2532037e7968Spatrickinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC 2533037e7968Spatrickvoid 2534037e7968Spatrickatomic_flag_notify_one(atomic_flag* __o) _NOEXCEPT 2535037e7968Spatrick{ 2536037e7968Spatrick __o->notify_one(); 2537037e7968Spatrick} 2538037e7968Spatrick 2539037e7968Spatrickinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC 2540037e7968Spatrickvoid 2541037e7968Spatrickatomic_flag_notify_all(volatile atomic_flag* __o) _NOEXCEPT 2542037e7968Spatrick{ 2543037e7968Spatrick __o->notify_all(); 2544037e7968Spatrick} 2545037e7968Spatrick 2546037e7968Spatrickinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_SYNC 2547037e7968Spatrickvoid 2548037e7968Spatrickatomic_flag_notify_all(atomic_flag* __o) _NOEXCEPT 2549037e7968Spatrick{ 2550037e7968Spatrick __o->notify_all(); 2551037e7968Spatrick} 2552037e7968Spatrick 255346035553Spatrick// fences 255446035553Spatrick 255546035553Spatrickinline _LIBCPP_INLINE_VISIBILITY 255646035553Spatrickvoid 255746035553Spatrickatomic_thread_fence(memory_order __m) _NOEXCEPT 255846035553Spatrick{ 255946035553Spatrick __cxx_atomic_thread_fence(__m); 256046035553Spatrick} 256146035553Spatrick 256246035553Spatrickinline _LIBCPP_INLINE_VISIBILITY 256346035553Spatrickvoid 256446035553Spatrickatomic_signal_fence(memory_order __m) _NOEXCEPT 256546035553Spatrick{ 256646035553Spatrick __cxx_atomic_signal_fence(__m); 256746035553Spatrick} 256846035553Spatrick 256946035553Spatrick// Atomics for standard typedef types 257046035553Spatrick 257146035553Spatricktypedef atomic<bool> atomic_bool; 257246035553Spatricktypedef atomic<char> atomic_char; 257346035553Spatricktypedef atomic<signed char> atomic_schar; 257446035553Spatricktypedef atomic<unsigned char> atomic_uchar; 257546035553Spatricktypedef atomic<short> atomic_short; 257646035553Spatricktypedef atomic<unsigned short> atomic_ushort; 257746035553Spatricktypedef atomic<int> atomic_int; 257846035553Spatricktypedef atomic<unsigned int> atomic_uint; 257946035553Spatricktypedef atomic<long> atomic_long; 258046035553Spatricktypedef atomic<unsigned long> atomic_ulong; 258146035553Spatricktypedef atomic<long long> atomic_llong; 258246035553Spatricktypedef atomic<unsigned long long> atomic_ullong; 258376d0caaeSpatrick#ifndef _LIBCPP_HAS_NO_CHAR8_T 258476d0caaeSpatricktypedef atomic<char8_t> atomic_char8_t; 258576d0caaeSpatrick#endif 258646035553Spatricktypedef atomic<char16_t> atomic_char16_t; 258746035553Spatricktypedef atomic<char32_t> atomic_char32_t; 2588*4bdff4beSrobert#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 258946035553Spatricktypedef atomic<wchar_t> atomic_wchar_t; 2590*4bdff4beSrobert#endif 259146035553Spatrick 259246035553Spatricktypedef atomic<int_least8_t> atomic_int_least8_t; 259346035553Spatricktypedef atomic<uint_least8_t> atomic_uint_least8_t; 259446035553Spatricktypedef atomic<int_least16_t> atomic_int_least16_t; 259546035553Spatricktypedef atomic<uint_least16_t> atomic_uint_least16_t; 259646035553Spatricktypedef atomic<int_least32_t> atomic_int_least32_t; 259746035553Spatricktypedef atomic<uint_least32_t> atomic_uint_least32_t; 259846035553Spatricktypedef atomic<int_least64_t> atomic_int_least64_t; 259946035553Spatricktypedef atomic<uint_least64_t> atomic_uint_least64_t; 260046035553Spatrick 260146035553Spatricktypedef atomic<int_fast8_t> atomic_int_fast8_t; 260246035553Spatricktypedef atomic<uint_fast8_t> atomic_uint_fast8_t; 260346035553Spatricktypedef atomic<int_fast16_t> atomic_int_fast16_t; 260446035553Spatricktypedef atomic<uint_fast16_t> atomic_uint_fast16_t; 260546035553Spatricktypedef atomic<int_fast32_t> atomic_int_fast32_t; 260646035553Spatricktypedef atomic<uint_fast32_t> atomic_uint_fast32_t; 260746035553Spatricktypedef atomic<int_fast64_t> atomic_int_fast64_t; 260846035553Spatricktypedef atomic<uint_fast64_t> atomic_uint_fast64_t; 260946035553Spatrick 261046035553Spatricktypedef atomic< int8_t> atomic_int8_t; 261146035553Spatricktypedef atomic<uint8_t> atomic_uint8_t; 261246035553Spatricktypedef atomic< int16_t> atomic_int16_t; 261346035553Spatricktypedef atomic<uint16_t> atomic_uint16_t; 261446035553Spatricktypedef atomic< int32_t> atomic_int32_t; 261546035553Spatricktypedef atomic<uint32_t> atomic_uint32_t; 261646035553Spatricktypedef atomic< int64_t> atomic_int64_t; 261746035553Spatricktypedef atomic<uint64_t> atomic_uint64_t; 261846035553Spatrick 261946035553Spatricktypedef atomic<intptr_t> atomic_intptr_t; 262046035553Spatricktypedef atomic<uintptr_t> atomic_uintptr_t; 262146035553Spatricktypedef atomic<size_t> atomic_size_t; 262246035553Spatricktypedef atomic<ptrdiff_t> atomic_ptrdiff_t; 262346035553Spatricktypedef atomic<intmax_t> atomic_intmax_t; 262446035553Spatricktypedef atomic<uintmax_t> atomic_uintmax_t; 262546035553Spatrick 2626037e7968Spatrick// atomic_*_lock_free : prefer the contention type most highly, then the largest lock-free type 2627037e7968Spatrick 2628037e7968Spatrick#ifdef __cpp_lib_atomic_is_always_lock_free 2629*4bdff4beSrobert# define _LIBCPP_CONTENTION_LOCK_FREE ::std::__libcpp_is_always_lock_free<__cxx_contention_t>::__value 2630037e7968Spatrick#else 2631037e7968Spatrick# define _LIBCPP_CONTENTION_LOCK_FREE false 2632037e7968Spatrick#endif 2633037e7968Spatrick 2634037e7968Spatrick#if ATOMIC_LLONG_LOCK_FREE == 2 2635*4bdff4beSroberttypedef __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, long long> __libcpp_signed_lock_free; 2636*4bdff4beSroberttypedef __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned long long> __libcpp_unsigned_lock_free; 2637037e7968Spatrick#elif ATOMIC_INT_LOCK_FREE == 2 2638*4bdff4beSroberttypedef __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, int> __libcpp_signed_lock_free; 2639*4bdff4beSroberttypedef __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned int> __libcpp_unsigned_lock_free; 2640037e7968Spatrick#elif ATOMIC_SHORT_LOCK_FREE == 2 2641*4bdff4beSroberttypedef __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, short> __libcpp_signed_lock_free; 2642*4bdff4beSroberttypedef __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned short> __libcpp_unsigned_lock_free; 2643037e7968Spatrick#elif ATOMIC_CHAR_LOCK_FREE == 2 2644*4bdff4beSroberttypedef __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, char> __libcpp_signed_lock_free; 2645*4bdff4beSroberttypedef __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned char> __libcpp_unsigned_lock_free; 2646037e7968Spatrick#else 2647037e7968Spatrick // No signed/unsigned lock-free types 2648*4bdff4beSrobert#define _LIBCPP_NO_LOCK_FREE_TYPES 2649037e7968Spatrick#endif 2650037e7968Spatrick 2651*4bdff4beSrobert#if !defined(_LIBCPP_NO_LOCK_FREE_TYPES) 2652037e7968Spatricktypedef atomic<__libcpp_signed_lock_free> atomic_signed_lock_free; 2653037e7968Spatricktypedef atomic<__libcpp_unsigned_lock_free> atomic_unsigned_lock_free; 2654*4bdff4beSrobert#endif 2655037e7968Spatrick 265646035553Spatrick#define ATOMIC_FLAG_INIT {false} 265746035553Spatrick#define ATOMIC_VAR_INIT(__v) {__v} 265846035553Spatrick 2659*4bdff4beSrobert#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_DISABLE_DEPRECATION_WARNINGS) 2660*4bdff4beSrobert# if defined(_LIBCPP_CLANG_VER) && _LIBCPP_CLANG_VER >= 1400 2661*4bdff4beSrobert# pragma clang deprecated(ATOMIC_VAR_INIT) 2662*4bdff4beSrobert# endif 2663*4bdff4beSrobert#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_DISABLE_DEPRECATION_WARNINGS) 2664*4bdff4beSrobert 266546035553Spatrick_LIBCPP_END_NAMESPACE_STD 266646035553Spatrick 2667*4bdff4beSrobert#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 2668*4bdff4beSrobert# include <cmath> 2669*4bdff4beSrobert# include <compare> 2670*4bdff4beSrobert# include <type_traits> 2671*4bdff4beSrobert#endif 2672*4bdff4beSrobert 267346035553Spatrick#endif // _LIBCPP_ATOMIC 2674