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