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