1*0b57cec5SDimitry Andric// -*- C++ -*- 2*0b57cec5SDimitry Andric//===--------------------------- atomic -----------------------------------===// 3*0b57cec5SDimitry Andric// 4*0b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5*0b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information. 6*0b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7*0b57cec5SDimitry Andric// 8*0b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 9*0b57cec5SDimitry Andric 10*0b57cec5SDimitry Andric#ifndef _LIBCPP_ATOMIC 11*0b57cec5SDimitry Andric#define _LIBCPP_ATOMIC 12*0b57cec5SDimitry Andric 13*0b57cec5SDimitry Andric/* 14*0b57cec5SDimitry Andric atomic synopsis 15*0b57cec5SDimitry Andric 16*0b57cec5SDimitry Andricnamespace std 17*0b57cec5SDimitry Andric{ 18*0b57cec5SDimitry Andric 19*0b57cec5SDimitry Andric// feature test macro 20*0b57cec5SDimitry Andric 21*0b57cec5SDimitry Andric#define __cpp_lib_atomic_is_always_lock_free // as specified by SG10 22*0b57cec5SDimitry Andric 23*0b57cec5SDimitry Andric // order and consistency 24*0b57cec5SDimitry Andric 25*0b57cec5SDimitry Andric enum memory_order: unspecified // enum class in C++20 26*0b57cec5SDimitry Andric { 27*0b57cec5SDimitry Andric relaxed, 28*0b57cec5SDimitry Andric consume, // load-consume 29*0b57cec5SDimitry Andric acquire, // load-acquire 30*0b57cec5SDimitry Andric release, // store-release 31*0b57cec5SDimitry Andric acq_rel, // store-release load-acquire 32*0b57cec5SDimitry Andric seq_cst // store-release load-acquire 33*0b57cec5SDimitry Andric }; 34*0b57cec5SDimitry Andric 35*0b57cec5SDimitry Andric inline constexpr auto memory_order_relaxed = memory_order::relaxed; 36*0b57cec5SDimitry Andric inline constexpr auto memory_order_consume = memory_order::consume; 37*0b57cec5SDimitry Andric inline constexpr auto memory_order_acquire = memory_order::acquire; 38*0b57cec5SDimitry Andric inline constexpr auto memory_order_release = memory_order::release; 39*0b57cec5SDimitry Andric inline constexpr auto memory_order_acq_rel = memory_order::acq_rel; 40*0b57cec5SDimitry Andric inline constexpr auto memory_order_seq_cst = memory_order::seq_cst; 41*0b57cec5SDimitry Andric 42*0b57cec5SDimitry Andrictemplate <class T> T kill_dependency(T y) noexcept; 43*0b57cec5SDimitry Andric 44*0b57cec5SDimitry Andric// lock-free property 45*0b57cec5SDimitry Andric 46*0b57cec5SDimitry Andric#define ATOMIC_BOOL_LOCK_FREE unspecified 47*0b57cec5SDimitry Andric#define ATOMIC_CHAR_LOCK_FREE unspecified 48*0b57cec5SDimitry Andric#define ATOMIC_CHAR16_T_LOCK_FREE unspecified 49*0b57cec5SDimitry Andric#define ATOMIC_CHAR32_T_LOCK_FREE unspecified 50*0b57cec5SDimitry Andric#define ATOMIC_WCHAR_T_LOCK_FREE unspecified 51*0b57cec5SDimitry Andric#define ATOMIC_SHORT_LOCK_FREE unspecified 52*0b57cec5SDimitry Andric#define ATOMIC_INT_LOCK_FREE unspecified 53*0b57cec5SDimitry Andric#define ATOMIC_LONG_LOCK_FREE unspecified 54*0b57cec5SDimitry Andric#define ATOMIC_LLONG_LOCK_FREE unspecified 55*0b57cec5SDimitry Andric#define ATOMIC_POINTER_LOCK_FREE unspecified 56*0b57cec5SDimitry Andric 57*0b57cec5SDimitry Andric// flag type and operations 58*0b57cec5SDimitry Andric 59*0b57cec5SDimitry Andrictypedef struct atomic_flag 60*0b57cec5SDimitry Andric{ 61*0b57cec5SDimitry Andric bool test_and_set(memory_order m = memory_order_seq_cst) volatile noexcept; 62*0b57cec5SDimitry Andric bool test_and_set(memory_order m = memory_order_seq_cst) noexcept; 63*0b57cec5SDimitry Andric void clear(memory_order m = memory_order_seq_cst) volatile noexcept; 64*0b57cec5SDimitry Andric void clear(memory_order m = memory_order_seq_cst) noexcept; 65*0b57cec5SDimitry Andric atomic_flag() noexcept = default; 66*0b57cec5SDimitry Andric atomic_flag(const atomic_flag&) = delete; 67*0b57cec5SDimitry Andric atomic_flag& operator=(const atomic_flag&) = delete; 68*0b57cec5SDimitry Andric atomic_flag& operator=(const atomic_flag&) volatile = delete; 69*0b57cec5SDimitry Andric} atomic_flag; 70*0b57cec5SDimitry Andric 71*0b57cec5SDimitry Andricbool 72*0b57cec5SDimitry Andric atomic_flag_test_and_set(volatile atomic_flag* obj) noexcept; 73*0b57cec5SDimitry Andric 74*0b57cec5SDimitry Andricbool 75*0b57cec5SDimitry Andric atomic_flag_test_and_set(atomic_flag* obj) noexcept; 76*0b57cec5SDimitry Andric 77*0b57cec5SDimitry Andricbool 78*0b57cec5SDimitry Andric atomic_flag_test_and_set_explicit(volatile atomic_flag* obj, 79*0b57cec5SDimitry Andric memory_order m) noexcept; 80*0b57cec5SDimitry Andric 81*0b57cec5SDimitry Andricbool 82*0b57cec5SDimitry Andric atomic_flag_test_and_set_explicit(atomic_flag* obj, memory_order m) noexcept; 83*0b57cec5SDimitry Andric 84*0b57cec5SDimitry Andricvoid 85*0b57cec5SDimitry Andric atomic_flag_clear(volatile atomic_flag* obj) noexcept; 86*0b57cec5SDimitry Andric 87*0b57cec5SDimitry Andricvoid 88*0b57cec5SDimitry Andric atomic_flag_clear(atomic_flag* obj) noexcept; 89*0b57cec5SDimitry Andric 90*0b57cec5SDimitry Andricvoid 91*0b57cec5SDimitry Andric atomic_flag_clear_explicit(volatile atomic_flag* obj, memory_order m) noexcept; 92*0b57cec5SDimitry Andric 93*0b57cec5SDimitry Andricvoid 94*0b57cec5SDimitry Andric atomic_flag_clear_explicit(atomic_flag* obj, memory_order m) noexcept; 95*0b57cec5SDimitry Andric 96*0b57cec5SDimitry Andric#define ATOMIC_FLAG_INIT see below 97*0b57cec5SDimitry Andric#define ATOMIC_VAR_INIT(value) see below 98*0b57cec5SDimitry Andric 99*0b57cec5SDimitry Andrictemplate <class T> 100*0b57cec5SDimitry Andricstruct atomic 101*0b57cec5SDimitry Andric{ 102*0b57cec5SDimitry Andric static constexpr bool is_always_lock_free; 103*0b57cec5SDimitry Andric bool is_lock_free() const volatile noexcept; 104*0b57cec5SDimitry Andric bool is_lock_free() const noexcept; 105*0b57cec5SDimitry Andric void store(T desr, memory_order m = memory_order_seq_cst) volatile noexcept; 106*0b57cec5SDimitry Andric void store(T desr, memory_order m = memory_order_seq_cst) noexcept; 107*0b57cec5SDimitry Andric T load(memory_order m = memory_order_seq_cst) const volatile noexcept; 108*0b57cec5SDimitry Andric T load(memory_order m = memory_order_seq_cst) const noexcept; 109*0b57cec5SDimitry Andric operator T() const volatile noexcept; 110*0b57cec5SDimitry Andric operator T() const noexcept; 111*0b57cec5SDimitry Andric T exchange(T desr, memory_order m = memory_order_seq_cst) volatile noexcept; 112*0b57cec5SDimitry Andric T exchange(T desr, memory_order m = memory_order_seq_cst) noexcept; 113*0b57cec5SDimitry Andric bool compare_exchange_weak(T& expc, T desr, 114*0b57cec5SDimitry Andric memory_order s, memory_order f) volatile noexcept; 115*0b57cec5SDimitry Andric bool compare_exchange_weak(T& expc, T desr, memory_order s, memory_order f) noexcept; 116*0b57cec5SDimitry Andric bool compare_exchange_strong(T& expc, T desr, 117*0b57cec5SDimitry Andric memory_order s, memory_order f) volatile noexcept; 118*0b57cec5SDimitry Andric bool compare_exchange_strong(T& expc, T desr, 119*0b57cec5SDimitry Andric memory_order s, memory_order f) noexcept; 120*0b57cec5SDimitry Andric bool compare_exchange_weak(T& expc, T desr, 121*0b57cec5SDimitry Andric memory_order m = memory_order_seq_cst) volatile noexcept; 122*0b57cec5SDimitry Andric bool compare_exchange_weak(T& expc, T desr, 123*0b57cec5SDimitry Andric memory_order m = memory_order_seq_cst) noexcept; 124*0b57cec5SDimitry Andric bool compare_exchange_strong(T& expc, T desr, 125*0b57cec5SDimitry Andric memory_order m = memory_order_seq_cst) volatile noexcept; 126*0b57cec5SDimitry Andric bool compare_exchange_strong(T& expc, T desr, 127*0b57cec5SDimitry Andric memory_order m = memory_order_seq_cst) noexcept; 128*0b57cec5SDimitry Andric 129*0b57cec5SDimitry Andric atomic() noexcept = default; 130*0b57cec5SDimitry Andric constexpr atomic(T desr) noexcept; 131*0b57cec5SDimitry Andric atomic(const atomic&) = delete; 132*0b57cec5SDimitry Andric atomic& operator=(const atomic&) = delete; 133*0b57cec5SDimitry Andric atomic& operator=(const atomic&) volatile = delete; 134*0b57cec5SDimitry Andric T operator=(T) volatile noexcept; 135*0b57cec5SDimitry Andric T operator=(T) noexcept; 136*0b57cec5SDimitry Andric}; 137*0b57cec5SDimitry Andric 138*0b57cec5SDimitry Andrictemplate <> 139*0b57cec5SDimitry Andricstruct atomic<integral> 140*0b57cec5SDimitry Andric{ 141*0b57cec5SDimitry Andric static constexpr bool is_always_lock_free; 142*0b57cec5SDimitry Andric bool is_lock_free() const volatile noexcept; 143*0b57cec5SDimitry Andric bool is_lock_free() const noexcept; 144*0b57cec5SDimitry Andric void store(integral desr, memory_order m = memory_order_seq_cst) volatile noexcept; 145*0b57cec5SDimitry Andric void store(integral desr, memory_order m = memory_order_seq_cst) noexcept; 146*0b57cec5SDimitry Andric integral load(memory_order m = memory_order_seq_cst) const volatile noexcept; 147*0b57cec5SDimitry Andric integral load(memory_order m = memory_order_seq_cst) const noexcept; 148*0b57cec5SDimitry Andric operator integral() const volatile noexcept; 149*0b57cec5SDimitry Andric operator integral() const noexcept; 150*0b57cec5SDimitry Andric integral exchange(integral desr, 151*0b57cec5SDimitry Andric memory_order m = memory_order_seq_cst) volatile noexcept; 152*0b57cec5SDimitry Andric integral exchange(integral desr, memory_order m = memory_order_seq_cst) noexcept; 153*0b57cec5SDimitry Andric bool compare_exchange_weak(integral& expc, integral desr, 154*0b57cec5SDimitry Andric memory_order s, memory_order f) volatile noexcept; 155*0b57cec5SDimitry Andric bool compare_exchange_weak(integral& expc, integral desr, 156*0b57cec5SDimitry Andric memory_order s, memory_order f) noexcept; 157*0b57cec5SDimitry Andric bool compare_exchange_strong(integral& expc, integral desr, 158*0b57cec5SDimitry Andric memory_order s, memory_order f) volatile noexcept; 159*0b57cec5SDimitry Andric bool compare_exchange_strong(integral& expc, integral desr, 160*0b57cec5SDimitry Andric memory_order s, memory_order f) noexcept; 161*0b57cec5SDimitry Andric bool compare_exchange_weak(integral& expc, integral desr, 162*0b57cec5SDimitry Andric memory_order m = memory_order_seq_cst) volatile noexcept; 163*0b57cec5SDimitry Andric bool compare_exchange_weak(integral& expc, integral desr, 164*0b57cec5SDimitry Andric memory_order m = memory_order_seq_cst) noexcept; 165*0b57cec5SDimitry Andric bool compare_exchange_strong(integral& expc, integral desr, 166*0b57cec5SDimitry Andric memory_order m = memory_order_seq_cst) volatile noexcept; 167*0b57cec5SDimitry Andric bool compare_exchange_strong(integral& expc, integral desr, 168*0b57cec5SDimitry Andric memory_order m = memory_order_seq_cst) noexcept; 169*0b57cec5SDimitry Andric 170*0b57cec5SDimitry Andric integral 171*0b57cec5SDimitry Andric fetch_add(integral op, memory_order m = memory_order_seq_cst) volatile noexcept; 172*0b57cec5SDimitry Andric integral fetch_add(integral op, memory_order m = memory_order_seq_cst) noexcept; 173*0b57cec5SDimitry Andric integral 174*0b57cec5SDimitry Andric fetch_sub(integral op, memory_order m = memory_order_seq_cst) volatile noexcept; 175*0b57cec5SDimitry Andric integral fetch_sub(integral op, memory_order m = memory_order_seq_cst) noexcept; 176*0b57cec5SDimitry Andric integral 177*0b57cec5SDimitry Andric fetch_and(integral op, memory_order m = memory_order_seq_cst) volatile noexcept; 178*0b57cec5SDimitry Andric integral fetch_and(integral op, memory_order m = memory_order_seq_cst) noexcept; 179*0b57cec5SDimitry Andric integral 180*0b57cec5SDimitry Andric fetch_or(integral op, memory_order m = memory_order_seq_cst) volatile noexcept; 181*0b57cec5SDimitry Andric integral fetch_or(integral op, memory_order m = memory_order_seq_cst) noexcept; 182*0b57cec5SDimitry Andric integral 183*0b57cec5SDimitry Andric fetch_xor(integral op, memory_order m = memory_order_seq_cst) volatile noexcept; 184*0b57cec5SDimitry Andric integral fetch_xor(integral op, memory_order m = memory_order_seq_cst) noexcept; 185*0b57cec5SDimitry Andric 186*0b57cec5SDimitry Andric atomic() noexcept = default; 187*0b57cec5SDimitry Andric constexpr atomic(integral desr) noexcept; 188*0b57cec5SDimitry Andric atomic(const atomic&) = delete; 189*0b57cec5SDimitry Andric atomic& operator=(const atomic&) = delete; 190*0b57cec5SDimitry Andric atomic& operator=(const atomic&) volatile = delete; 191*0b57cec5SDimitry Andric integral operator=(integral desr) volatile noexcept; 192*0b57cec5SDimitry Andric integral operator=(integral desr) noexcept; 193*0b57cec5SDimitry Andric 194*0b57cec5SDimitry Andric integral operator++(int) volatile noexcept; 195*0b57cec5SDimitry Andric integral operator++(int) noexcept; 196*0b57cec5SDimitry Andric integral operator--(int) volatile noexcept; 197*0b57cec5SDimitry Andric integral operator--(int) noexcept; 198*0b57cec5SDimitry Andric integral operator++() volatile noexcept; 199*0b57cec5SDimitry Andric integral operator++() noexcept; 200*0b57cec5SDimitry Andric integral operator--() volatile noexcept; 201*0b57cec5SDimitry Andric integral operator--() noexcept; 202*0b57cec5SDimitry Andric integral operator+=(integral op) volatile noexcept; 203*0b57cec5SDimitry Andric integral operator+=(integral op) noexcept; 204*0b57cec5SDimitry Andric integral operator-=(integral op) volatile noexcept; 205*0b57cec5SDimitry Andric integral operator-=(integral op) noexcept; 206*0b57cec5SDimitry Andric integral operator&=(integral op) volatile noexcept; 207*0b57cec5SDimitry Andric integral operator&=(integral op) noexcept; 208*0b57cec5SDimitry Andric integral operator|=(integral op) volatile noexcept; 209*0b57cec5SDimitry Andric integral operator|=(integral op) noexcept; 210*0b57cec5SDimitry Andric integral operator^=(integral op) volatile noexcept; 211*0b57cec5SDimitry Andric integral operator^=(integral op) noexcept; 212*0b57cec5SDimitry Andric}; 213*0b57cec5SDimitry Andric 214*0b57cec5SDimitry Andrictemplate <class T> 215*0b57cec5SDimitry Andricstruct atomic<T*> 216*0b57cec5SDimitry Andric{ 217*0b57cec5SDimitry Andric static constexpr bool is_always_lock_free; 218*0b57cec5SDimitry Andric bool is_lock_free() const volatile noexcept; 219*0b57cec5SDimitry Andric bool is_lock_free() const noexcept; 220*0b57cec5SDimitry Andric void store(T* desr, memory_order m = memory_order_seq_cst) volatile noexcept; 221*0b57cec5SDimitry Andric void store(T* desr, memory_order m = memory_order_seq_cst) noexcept; 222*0b57cec5SDimitry Andric T* load(memory_order m = memory_order_seq_cst) const volatile noexcept; 223*0b57cec5SDimitry Andric T* load(memory_order m = memory_order_seq_cst) const noexcept; 224*0b57cec5SDimitry Andric operator T*() const volatile noexcept; 225*0b57cec5SDimitry Andric operator T*() const noexcept; 226*0b57cec5SDimitry Andric T* exchange(T* desr, memory_order m = memory_order_seq_cst) volatile noexcept; 227*0b57cec5SDimitry Andric T* exchange(T* desr, memory_order m = memory_order_seq_cst) noexcept; 228*0b57cec5SDimitry Andric bool compare_exchange_weak(T*& expc, T* desr, 229*0b57cec5SDimitry Andric memory_order s, memory_order f) volatile noexcept; 230*0b57cec5SDimitry Andric bool compare_exchange_weak(T*& expc, T* desr, 231*0b57cec5SDimitry Andric memory_order s, memory_order f) noexcept; 232*0b57cec5SDimitry Andric bool compare_exchange_strong(T*& expc, T* desr, 233*0b57cec5SDimitry Andric memory_order s, memory_order f) volatile noexcept; 234*0b57cec5SDimitry Andric bool compare_exchange_strong(T*& expc, T* desr, 235*0b57cec5SDimitry Andric memory_order s, memory_order f) noexcept; 236*0b57cec5SDimitry Andric bool compare_exchange_weak(T*& expc, T* desr, 237*0b57cec5SDimitry Andric memory_order m = memory_order_seq_cst) volatile noexcept; 238*0b57cec5SDimitry Andric bool compare_exchange_weak(T*& expc, T* desr, 239*0b57cec5SDimitry Andric memory_order m = memory_order_seq_cst) noexcept; 240*0b57cec5SDimitry Andric bool compare_exchange_strong(T*& expc, T* desr, 241*0b57cec5SDimitry Andric memory_order m = memory_order_seq_cst) volatile noexcept; 242*0b57cec5SDimitry Andric bool compare_exchange_strong(T*& expc, T* desr, 243*0b57cec5SDimitry Andric memory_order m = memory_order_seq_cst) noexcept; 244*0b57cec5SDimitry Andric T* fetch_add(ptrdiff_t op, memory_order m = memory_order_seq_cst) volatile noexcept; 245*0b57cec5SDimitry Andric T* fetch_add(ptrdiff_t op, memory_order m = memory_order_seq_cst) noexcept; 246*0b57cec5SDimitry Andric T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst) volatile noexcept; 247*0b57cec5SDimitry Andric T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst) noexcept; 248*0b57cec5SDimitry Andric 249*0b57cec5SDimitry Andric atomic() noexcept = default; 250*0b57cec5SDimitry Andric constexpr atomic(T* desr) noexcept; 251*0b57cec5SDimitry Andric atomic(const atomic&) = delete; 252*0b57cec5SDimitry Andric atomic& operator=(const atomic&) = delete; 253*0b57cec5SDimitry Andric atomic& operator=(const atomic&) volatile = delete; 254*0b57cec5SDimitry Andric 255*0b57cec5SDimitry Andric T* operator=(T*) volatile noexcept; 256*0b57cec5SDimitry Andric T* operator=(T*) noexcept; 257*0b57cec5SDimitry Andric T* operator++(int) volatile noexcept; 258*0b57cec5SDimitry Andric T* operator++(int) noexcept; 259*0b57cec5SDimitry Andric T* operator--(int) volatile noexcept; 260*0b57cec5SDimitry Andric T* operator--(int) noexcept; 261*0b57cec5SDimitry Andric T* operator++() volatile noexcept; 262*0b57cec5SDimitry Andric T* operator++() noexcept; 263*0b57cec5SDimitry Andric T* operator--() volatile noexcept; 264*0b57cec5SDimitry Andric T* operator--() noexcept; 265*0b57cec5SDimitry Andric T* operator+=(ptrdiff_t op) volatile noexcept; 266*0b57cec5SDimitry Andric T* operator+=(ptrdiff_t op) noexcept; 267*0b57cec5SDimitry Andric T* operator-=(ptrdiff_t op) volatile noexcept; 268*0b57cec5SDimitry Andric T* operator-=(ptrdiff_t op) noexcept; 269*0b57cec5SDimitry Andric}; 270*0b57cec5SDimitry Andric 271*0b57cec5SDimitry Andric 272*0b57cec5SDimitry Andrictemplate <class T> 273*0b57cec5SDimitry Andric bool 274*0b57cec5SDimitry Andric atomic_is_lock_free(const volatile atomic<T>* obj) noexcept; 275*0b57cec5SDimitry Andric 276*0b57cec5SDimitry Andrictemplate <class T> 277*0b57cec5SDimitry Andric bool 278*0b57cec5SDimitry Andric atomic_is_lock_free(const atomic<T>* obj) noexcept; 279*0b57cec5SDimitry Andric 280*0b57cec5SDimitry Andrictemplate <class T> 281*0b57cec5SDimitry Andric void 282*0b57cec5SDimitry Andric atomic_init(volatile atomic<T>* obj, T desr) noexcept; 283*0b57cec5SDimitry Andric 284*0b57cec5SDimitry Andrictemplate <class T> 285*0b57cec5SDimitry Andric void 286*0b57cec5SDimitry Andric atomic_init(atomic<T>* obj, T desr) noexcept; 287*0b57cec5SDimitry Andric 288*0b57cec5SDimitry Andrictemplate <class T> 289*0b57cec5SDimitry Andric void 290*0b57cec5SDimitry Andric atomic_store(volatile atomic<T>* obj, T desr) noexcept; 291*0b57cec5SDimitry Andric 292*0b57cec5SDimitry Andrictemplate <class T> 293*0b57cec5SDimitry Andric void 294*0b57cec5SDimitry Andric atomic_store(atomic<T>* obj, T desr) noexcept; 295*0b57cec5SDimitry Andric 296*0b57cec5SDimitry Andrictemplate <class T> 297*0b57cec5SDimitry Andric void 298*0b57cec5SDimitry Andric atomic_store_explicit(volatile atomic<T>* obj, T desr, memory_order m) noexcept; 299*0b57cec5SDimitry Andric 300*0b57cec5SDimitry Andrictemplate <class T> 301*0b57cec5SDimitry Andric void 302*0b57cec5SDimitry Andric atomic_store_explicit(atomic<T>* obj, T desr, memory_order m) noexcept; 303*0b57cec5SDimitry Andric 304*0b57cec5SDimitry Andrictemplate <class T> 305*0b57cec5SDimitry Andric T 306*0b57cec5SDimitry Andric atomic_load(const volatile atomic<T>* obj) noexcept; 307*0b57cec5SDimitry Andric 308*0b57cec5SDimitry Andrictemplate <class T> 309*0b57cec5SDimitry Andric T 310*0b57cec5SDimitry Andric atomic_load(const atomic<T>* obj) noexcept; 311*0b57cec5SDimitry Andric 312*0b57cec5SDimitry Andrictemplate <class T> 313*0b57cec5SDimitry Andric T 314*0b57cec5SDimitry Andric atomic_load_explicit(const volatile atomic<T>* obj, memory_order m) noexcept; 315*0b57cec5SDimitry Andric 316*0b57cec5SDimitry Andrictemplate <class T> 317*0b57cec5SDimitry Andric T 318*0b57cec5SDimitry Andric atomic_load_explicit(const atomic<T>* obj, memory_order m) noexcept; 319*0b57cec5SDimitry Andric 320*0b57cec5SDimitry Andrictemplate <class T> 321*0b57cec5SDimitry Andric T 322*0b57cec5SDimitry Andric atomic_exchange(volatile atomic<T>* obj, T desr) noexcept; 323*0b57cec5SDimitry Andric 324*0b57cec5SDimitry Andrictemplate <class T> 325*0b57cec5SDimitry Andric T 326*0b57cec5SDimitry Andric atomic_exchange(atomic<T>* obj, T desr) noexcept; 327*0b57cec5SDimitry Andric 328*0b57cec5SDimitry Andrictemplate <class T> 329*0b57cec5SDimitry Andric T 330*0b57cec5SDimitry Andric atomic_exchange_explicit(volatile atomic<T>* obj, T desr, memory_order m) noexcept; 331*0b57cec5SDimitry Andric 332*0b57cec5SDimitry Andrictemplate <class T> 333*0b57cec5SDimitry Andric T 334*0b57cec5SDimitry Andric atomic_exchange_explicit(atomic<T>* obj, T desr, memory_order m) noexcept; 335*0b57cec5SDimitry Andric 336*0b57cec5SDimitry Andrictemplate <class T> 337*0b57cec5SDimitry Andric bool 338*0b57cec5SDimitry Andric atomic_compare_exchange_weak(volatile atomic<T>* obj, T* expc, T desr) noexcept; 339*0b57cec5SDimitry Andric 340*0b57cec5SDimitry Andrictemplate <class T> 341*0b57cec5SDimitry Andric bool 342*0b57cec5SDimitry Andric atomic_compare_exchange_weak(atomic<T>* obj, T* expc, T desr) noexcept; 343*0b57cec5SDimitry Andric 344*0b57cec5SDimitry Andrictemplate <class T> 345*0b57cec5SDimitry Andric bool 346*0b57cec5SDimitry Andric atomic_compare_exchange_strong(volatile atomic<T>* obj, T* expc, T desr) noexcept; 347*0b57cec5SDimitry Andric 348*0b57cec5SDimitry Andrictemplate <class T> 349*0b57cec5SDimitry Andric bool 350*0b57cec5SDimitry Andric atomic_compare_exchange_strong(atomic<T>* obj, T* expc, T desr) noexcept; 351*0b57cec5SDimitry Andric 352*0b57cec5SDimitry Andrictemplate <class T> 353*0b57cec5SDimitry Andric bool 354*0b57cec5SDimitry Andric atomic_compare_exchange_weak_explicit(volatile atomic<T>* obj, T* expc, 355*0b57cec5SDimitry Andric T desr, 356*0b57cec5SDimitry Andric memory_order s, memory_order f) noexcept; 357*0b57cec5SDimitry Andric 358*0b57cec5SDimitry Andrictemplate <class T> 359*0b57cec5SDimitry Andric bool 360*0b57cec5SDimitry Andric atomic_compare_exchange_weak_explicit(atomic<T>* obj, T* expc, T desr, 361*0b57cec5SDimitry Andric memory_order s, memory_order f) noexcept; 362*0b57cec5SDimitry Andric 363*0b57cec5SDimitry Andrictemplate <class T> 364*0b57cec5SDimitry Andric bool 365*0b57cec5SDimitry Andric atomic_compare_exchange_strong_explicit(volatile atomic<T>* obj, 366*0b57cec5SDimitry Andric T* expc, T desr, 367*0b57cec5SDimitry Andric memory_order s, memory_order f) noexcept; 368*0b57cec5SDimitry Andric 369*0b57cec5SDimitry Andrictemplate <class T> 370*0b57cec5SDimitry Andric bool 371*0b57cec5SDimitry Andric atomic_compare_exchange_strong_explicit(atomic<T>* obj, T* expc, 372*0b57cec5SDimitry Andric T desr, 373*0b57cec5SDimitry Andric memory_order s, memory_order f) noexcept; 374*0b57cec5SDimitry Andric 375*0b57cec5SDimitry Andrictemplate <class Integral> 376*0b57cec5SDimitry Andric Integral 377*0b57cec5SDimitry Andric atomic_fetch_add(volatile atomic<Integral>* obj, Integral op) noexcept; 378*0b57cec5SDimitry Andric 379*0b57cec5SDimitry Andrictemplate <class Integral> 380*0b57cec5SDimitry Andric Integral 381*0b57cec5SDimitry Andric atomic_fetch_add(atomic<Integral>* obj, Integral op) noexcept; 382*0b57cec5SDimitry Andric 383*0b57cec5SDimitry Andrictemplate <class Integral> 384*0b57cec5SDimitry Andric Integral 385*0b57cec5SDimitry Andric atomic_fetch_add_explicit(volatile atomic<Integral>* obj, Integral op, 386*0b57cec5SDimitry Andric memory_order m) noexcept; 387*0b57cec5SDimitry Andrictemplate <class Integral> 388*0b57cec5SDimitry Andric Integral 389*0b57cec5SDimitry Andric atomic_fetch_add_explicit(atomic<Integral>* obj, Integral op, 390*0b57cec5SDimitry Andric memory_order m) noexcept; 391*0b57cec5SDimitry Andrictemplate <class Integral> 392*0b57cec5SDimitry Andric Integral 393*0b57cec5SDimitry Andric atomic_fetch_sub(volatile atomic<Integral>* obj, Integral op) noexcept; 394*0b57cec5SDimitry Andric 395*0b57cec5SDimitry Andrictemplate <class Integral> 396*0b57cec5SDimitry Andric Integral 397*0b57cec5SDimitry Andric atomic_fetch_sub(atomic<Integral>* obj, Integral op) noexcept; 398*0b57cec5SDimitry Andric 399*0b57cec5SDimitry Andrictemplate <class Integral> 400*0b57cec5SDimitry Andric Integral 401*0b57cec5SDimitry Andric atomic_fetch_sub_explicit(volatile atomic<Integral>* obj, Integral op, 402*0b57cec5SDimitry Andric memory_order m) noexcept; 403*0b57cec5SDimitry Andrictemplate <class Integral> 404*0b57cec5SDimitry Andric Integral 405*0b57cec5SDimitry Andric atomic_fetch_sub_explicit(atomic<Integral>* obj, Integral op, 406*0b57cec5SDimitry Andric memory_order m) noexcept; 407*0b57cec5SDimitry Andrictemplate <class Integral> 408*0b57cec5SDimitry Andric Integral 409*0b57cec5SDimitry Andric atomic_fetch_and(volatile atomic<Integral>* obj, Integral op) noexcept; 410*0b57cec5SDimitry Andric 411*0b57cec5SDimitry Andrictemplate <class Integral> 412*0b57cec5SDimitry Andric Integral 413*0b57cec5SDimitry Andric atomic_fetch_and(atomic<Integral>* obj, Integral op) noexcept; 414*0b57cec5SDimitry Andric 415*0b57cec5SDimitry Andrictemplate <class Integral> 416*0b57cec5SDimitry Andric Integral 417*0b57cec5SDimitry Andric atomic_fetch_and_explicit(volatile atomic<Integral>* obj, Integral op, 418*0b57cec5SDimitry Andric memory_order m) noexcept; 419*0b57cec5SDimitry Andrictemplate <class Integral> 420*0b57cec5SDimitry Andric Integral 421*0b57cec5SDimitry Andric atomic_fetch_and_explicit(atomic<Integral>* obj, Integral op, 422*0b57cec5SDimitry Andric memory_order m) noexcept; 423*0b57cec5SDimitry Andrictemplate <class Integral> 424*0b57cec5SDimitry Andric Integral 425*0b57cec5SDimitry Andric atomic_fetch_or(volatile atomic<Integral>* obj, Integral op) noexcept; 426*0b57cec5SDimitry Andric 427*0b57cec5SDimitry Andrictemplate <class Integral> 428*0b57cec5SDimitry Andric Integral 429*0b57cec5SDimitry Andric atomic_fetch_or(atomic<Integral>* obj, Integral op) noexcept; 430*0b57cec5SDimitry Andric 431*0b57cec5SDimitry Andrictemplate <class Integral> 432*0b57cec5SDimitry Andric Integral 433*0b57cec5SDimitry Andric atomic_fetch_or_explicit(volatile atomic<Integral>* obj, Integral op, 434*0b57cec5SDimitry Andric memory_order m) noexcept; 435*0b57cec5SDimitry Andrictemplate <class Integral> 436*0b57cec5SDimitry Andric Integral 437*0b57cec5SDimitry Andric atomic_fetch_or_explicit(atomic<Integral>* obj, Integral op, 438*0b57cec5SDimitry Andric memory_order m) noexcept; 439*0b57cec5SDimitry Andrictemplate <class Integral> 440*0b57cec5SDimitry Andric Integral 441*0b57cec5SDimitry Andric atomic_fetch_xor(volatile atomic<Integral>* obj, Integral op) noexcept; 442*0b57cec5SDimitry Andric 443*0b57cec5SDimitry Andrictemplate <class Integral> 444*0b57cec5SDimitry Andric Integral 445*0b57cec5SDimitry Andric atomic_fetch_xor(atomic<Integral>* obj, Integral op) noexcept; 446*0b57cec5SDimitry Andric 447*0b57cec5SDimitry Andrictemplate <class Integral> 448*0b57cec5SDimitry Andric Integral 449*0b57cec5SDimitry Andric atomic_fetch_xor_explicit(volatile atomic<Integral>* obj, Integral op, 450*0b57cec5SDimitry Andric memory_order m) noexcept; 451*0b57cec5SDimitry Andrictemplate <class Integral> 452*0b57cec5SDimitry Andric Integral 453*0b57cec5SDimitry Andric atomic_fetch_xor_explicit(atomic<Integral>* obj, Integral op, 454*0b57cec5SDimitry Andric memory_order m) noexcept; 455*0b57cec5SDimitry Andric 456*0b57cec5SDimitry Andrictemplate <class T> 457*0b57cec5SDimitry Andric T* 458*0b57cec5SDimitry Andric atomic_fetch_add(volatile atomic<T*>* obj, ptrdiff_t op) noexcept; 459*0b57cec5SDimitry Andric 460*0b57cec5SDimitry Andrictemplate <class T> 461*0b57cec5SDimitry Andric T* 462*0b57cec5SDimitry Andric atomic_fetch_add(atomic<T*>* obj, ptrdiff_t op) noexcept; 463*0b57cec5SDimitry Andric 464*0b57cec5SDimitry Andrictemplate <class T> 465*0b57cec5SDimitry Andric T* 466*0b57cec5SDimitry Andric atomic_fetch_add_explicit(volatile atomic<T*>* obj, ptrdiff_t op, 467*0b57cec5SDimitry Andric memory_order m) noexcept; 468*0b57cec5SDimitry Andrictemplate <class T> 469*0b57cec5SDimitry Andric T* 470*0b57cec5SDimitry Andric atomic_fetch_add_explicit(atomic<T*>* obj, ptrdiff_t op, memory_order m) noexcept; 471*0b57cec5SDimitry Andric 472*0b57cec5SDimitry Andrictemplate <class T> 473*0b57cec5SDimitry Andric T* 474*0b57cec5SDimitry Andric atomic_fetch_sub(volatile atomic<T*>* obj, ptrdiff_t op) noexcept; 475*0b57cec5SDimitry Andric 476*0b57cec5SDimitry Andrictemplate <class T> 477*0b57cec5SDimitry Andric T* 478*0b57cec5SDimitry Andric atomic_fetch_sub(atomic<T*>* obj, ptrdiff_t op) noexcept; 479*0b57cec5SDimitry Andric 480*0b57cec5SDimitry Andrictemplate <class T> 481*0b57cec5SDimitry Andric T* 482*0b57cec5SDimitry Andric atomic_fetch_sub_explicit(volatile atomic<T*>* obj, ptrdiff_t op, 483*0b57cec5SDimitry Andric memory_order m) noexcept; 484*0b57cec5SDimitry Andrictemplate <class T> 485*0b57cec5SDimitry Andric T* 486*0b57cec5SDimitry Andric atomic_fetch_sub_explicit(atomic<T*>* obj, ptrdiff_t op, memory_order m) noexcept; 487*0b57cec5SDimitry Andric 488*0b57cec5SDimitry Andric// Atomics for standard typedef types 489*0b57cec5SDimitry Andric 490*0b57cec5SDimitry Andrictypedef atomic<bool> atomic_bool; 491*0b57cec5SDimitry Andrictypedef atomic<char> atomic_char; 492*0b57cec5SDimitry Andrictypedef atomic<signed char> atomic_schar; 493*0b57cec5SDimitry Andrictypedef atomic<unsigned char> atomic_uchar; 494*0b57cec5SDimitry Andrictypedef atomic<short> atomic_short; 495*0b57cec5SDimitry Andrictypedef atomic<unsigned short> atomic_ushort; 496*0b57cec5SDimitry Andrictypedef atomic<int> atomic_int; 497*0b57cec5SDimitry Andrictypedef atomic<unsigned int> atomic_uint; 498*0b57cec5SDimitry Andrictypedef atomic<long> atomic_long; 499*0b57cec5SDimitry Andrictypedef atomic<unsigned long> atomic_ulong; 500*0b57cec5SDimitry Andrictypedef atomic<long long> atomic_llong; 501*0b57cec5SDimitry Andrictypedef atomic<unsigned long long> atomic_ullong; 502*0b57cec5SDimitry Andrictypedef atomic<char16_t> atomic_char16_t; 503*0b57cec5SDimitry Andrictypedef atomic<char32_t> atomic_char32_t; 504*0b57cec5SDimitry Andrictypedef atomic<wchar_t> atomic_wchar_t; 505*0b57cec5SDimitry Andric 506*0b57cec5SDimitry Andrictypedef atomic<int_least8_t> atomic_int_least8_t; 507*0b57cec5SDimitry Andrictypedef atomic<uint_least8_t> atomic_uint_least8_t; 508*0b57cec5SDimitry Andrictypedef atomic<int_least16_t> atomic_int_least16_t; 509*0b57cec5SDimitry Andrictypedef atomic<uint_least16_t> atomic_uint_least16_t; 510*0b57cec5SDimitry Andrictypedef atomic<int_least32_t> atomic_int_least32_t; 511*0b57cec5SDimitry Andrictypedef atomic<uint_least32_t> atomic_uint_least32_t; 512*0b57cec5SDimitry Andrictypedef atomic<int_least64_t> atomic_int_least64_t; 513*0b57cec5SDimitry Andrictypedef atomic<uint_least64_t> atomic_uint_least64_t; 514*0b57cec5SDimitry Andric 515*0b57cec5SDimitry Andrictypedef atomic<int_fast8_t> atomic_int_fast8_t; 516*0b57cec5SDimitry Andrictypedef atomic<uint_fast8_t> atomic_uint_fast8_t; 517*0b57cec5SDimitry Andrictypedef atomic<int_fast16_t> atomic_int_fast16_t; 518*0b57cec5SDimitry Andrictypedef atomic<uint_fast16_t> atomic_uint_fast16_t; 519*0b57cec5SDimitry Andrictypedef atomic<int_fast32_t> atomic_int_fast32_t; 520*0b57cec5SDimitry Andrictypedef atomic<uint_fast32_t> atomic_uint_fast32_t; 521*0b57cec5SDimitry Andrictypedef atomic<int_fast64_t> atomic_int_fast64_t; 522*0b57cec5SDimitry Andrictypedef atomic<uint_fast64_t> atomic_uint_fast64_t; 523*0b57cec5SDimitry Andric 524*0b57cec5SDimitry Andrictypedef atomic<int8_t> atomic_int8_t; 525*0b57cec5SDimitry Andrictypedef atomic<uint8_t> atomic_uint8_t; 526*0b57cec5SDimitry Andrictypedef atomic<int16_t> atomic_int16_t; 527*0b57cec5SDimitry Andrictypedef atomic<uint16_t> atomic_uint16_t; 528*0b57cec5SDimitry Andrictypedef atomic<int32_t> atomic_int32_t; 529*0b57cec5SDimitry Andrictypedef atomic<uint32_t> atomic_uint32_t; 530*0b57cec5SDimitry Andrictypedef atomic<int64_t> atomic_int64_t; 531*0b57cec5SDimitry Andrictypedef atomic<uint64_t> atomic_uint64_t; 532*0b57cec5SDimitry Andric 533*0b57cec5SDimitry Andrictypedef atomic<intptr_t> atomic_intptr_t; 534*0b57cec5SDimitry Andrictypedef atomic<uintptr_t> atomic_uintptr_t; 535*0b57cec5SDimitry Andrictypedef atomic<size_t> atomic_size_t; 536*0b57cec5SDimitry Andrictypedef atomic<ptrdiff_t> atomic_ptrdiff_t; 537*0b57cec5SDimitry Andrictypedef atomic<intmax_t> atomic_intmax_t; 538*0b57cec5SDimitry Andrictypedef atomic<uintmax_t> atomic_uintmax_t; 539*0b57cec5SDimitry Andric 540*0b57cec5SDimitry Andric// fences 541*0b57cec5SDimitry Andric 542*0b57cec5SDimitry Andricvoid atomic_thread_fence(memory_order m) noexcept; 543*0b57cec5SDimitry Andricvoid atomic_signal_fence(memory_order m) noexcept; 544*0b57cec5SDimitry Andric 545*0b57cec5SDimitry Andric} // std 546*0b57cec5SDimitry Andric 547*0b57cec5SDimitry Andric*/ 548*0b57cec5SDimitry Andric 549*0b57cec5SDimitry Andric#include <__config> 550*0b57cec5SDimitry Andric#include <cstddef> 551*0b57cec5SDimitry Andric#include <cstdint> 552*0b57cec5SDimitry Andric#include <type_traits> 553*0b57cec5SDimitry Andric#include <version> 554*0b57cec5SDimitry Andric 555*0b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 556*0b57cec5SDimitry Andric#pragma GCC system_header 557*0b57cec5SDimitry Andric#endif 558*0b57cec5SDimitry Andric 559*0b57cec5SDimitry Andric#ifdef _LIBCPP_HAS_NO_THREADS 560*0b57cec5SDimitry Andric# error <atomic> is not supported on this single threaded system 561*0b57cec5SDimitry Andric#endif 562*0b57cec5SDimitry Andric#ifdef _LIBCPP_HAS_NO_ATOMIC_HEADER 563*0b57cec5SDimitry Andric# error <atomic> is not implemented 564*0b57cec5SDimitry Andric#endif 565*0b57cec5SDimitry Andric#ifdef kill_dependency 566*0b57cec5SDimitry Andric# error C++ standard library is incompatible with <stdatomic.h> 567*0b57cec5SDimitry Andric#endif 568*0b57cec5SDimitry Andric 569*0b57cec5SDimitry Andric#define _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) \ 570*0b57cec5SDimitry Andric _LIBCPP_DIAGNOSE_WARNING(__m == memory_order_consume || \ 571*0b57cec5SDimitry Andric __m == memory_order_acquire || \ 572*0b57cec5SDimitry Andric __m == memory_order_acq_rel, \ 573*0b57cec5SDimitry Andric "memory order argument to atomic operation is invalid") 574*0b57cec5SDimitry Andric 575*0b57cec5SDimitry Andric#define _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) \ 576*0b57cec5SDimitry Andric _LIBCPP_DIAGNOSE_WARNING(__m == memory_order_release || \ 577*0b57cec5SDimitry Andric __m == memory_order_acq_rel, \ 578*0b57cec5SDimitry Andric "memory order argument to atomic operation is invalid") 579*0b57cec5SDimitry Andric 580*0b57cec5SDimitry Andric#define _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__m, __f) \ 581*0b57cec5SDimitry Andric _LIBCPP_DIAGNOSE_WARNING(__f == memory_order_release || \ 582*0b57cec5SDimitry Andric __f == memory_order_acq_rel, \ 583*0b57cec5SDimitry Andric "memory order argument to atomic operation is invalid") 584*0b57cec5SDimitry Andric 585*0b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD 586*0b57cec5SDimitry Andric 587*0b57cec5SDimitry Andric// Figure out what the underlying type for `memory_order` would be if it were 588*0b57cec5SDimitry Andric// declared as an unscoped enum (accounting for -fshort-enums). Use this result 589*0b57cec5SDimitry Andric// to pin the underlying type in C++20. 590*0b57cec5SDimitry Andricenum __legacy_memory_order { 591*0b57cec5SDimitry Andric __mo_relaxed, 592*0b57cec5SDimitry Andric __mo_consume, 593*0b57cec5SDimitry Andric __mo_acquire, 594*0b57cec5SDimitry Andric __mo_release, 595*0b57cec5SDimitry Andric __mo_acq_rel, 596*0b57cec5SDimitry Andric __mo_seq_cst 597*0b57cec5SDimitry Andric}; 598*0b57cec5SDimitry Andric 599*0b57cec5SDimitry Andrictypedef underlying_type<__legacy_memory_order>::type __memory_order_underlying_t; 600*0b57cec5SDimitry Andric 601*0b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 17 602*0b57cec5SDimitry Andric 603*0b57cec5SDimitry Andricenum class memory_order : __memory_order_underlying_t { 604*0b57cec5SDimitry Andric relaxed = __mo_relaxed, 605*0b57cec5SDimitry Andric consume = __mo_consume, 606*0b57cec5SDimitry Andric acquire = __mo_acquire, 607*0b57cec5SDimitry Andric release = __mo_release, 608*0b57cec5SDimitry Andric acq_rel = __mo_acq_rel, 609*0b57cec5SDimitry Andric seq_cst = __mo_seq_cst 610*0b57cec5SDimitry Andric}; 611*0b57cec5SDimitry Andric 612*0b57cec5SDimitry Andricinline constexpr auto memory_order_relaxed = memory_order::relaxed; 613*0b57cec5SDimitry Andricinline constexpr auto memory_order_consume = memory_order::consume; 614*0b57cec5SDimitry Andricinline constexpr auto memory_order_acquire = memory_order::acquire; 615*0b57cec5SDimitry Andricinline constexpr auto memory_order_release = memory_order::release; 616*0b57cec5SDimitry Andricinline constexpr auto memory_order_acq_rel = memory_order::acq_rel; 617*0b57cec5SDimitry Andricinline constexpr auto memory_order_seq_cst = memory_order::seq_cst; 618*0b57cec5SDimitry Andric 619*0b57cec5SDimitry Andric#else 620*0b57cec5SDimitry Andric 621*0b57cec5SDimitry Andrictypedef enum memory_order { 622*0b57cec5SDimitry Andric memory_order_relaxed = __mo_relaxed, 623*0b57cec5SDimitry Andric memory_order_consume = __mo_consume, 624*0b57cec5SDimitry Andric memory_order_acquire = __mo_acquire, 625*0b57cec5SDimitry Andric memory_order_release = __mo_release, 626*0b57cec5SDimitry Andric memory_order_acq_rel = __mo_acq_rel, 627*0b57cec5SDimitry Andric memory_order_seq_cst = __mo_seq_cst, 628*0b57cec5SDimitry Andric} memory_order; 629*0b57cec5SDimitry Andric 630*0b57cec5SDimitry Andric#endif // _LIBCPP_STD_VER > 17 631*0b57cec5SDimitry Andric 632*0b57cec5SDimitry Andricstatic_assert((is_same<underlying_type<memory_order>::type, __memory_order_underlying_t>::value), 633*0b57cec5SDimitry Andric "unexpected underlying type for std::memory_order"); 634*0b57cec5SDimitry Andric 635*0b57cec5SDimitry Andric#if defined(_LIBCPP_HAS_GCC_ATOMIC_IMP) || \ 636*0b57cec5SDimitry Andric defined(_LIBCPP_ATOMIC_ONLY_USE_BUILTINS) 637*0b57cec5SDimitry Andric 638*0b57cec5SDimitry Andric// [atomics.types.generic]p1 guarantees _Tp is trivially copyable. Because 639*0b57cec5SDimitry Andric// the default operator= in an object is not volatile, a byte-by-byte copy 640*0b57cec5SDimitry Andric// is required. 641*0b57cec5SDimitry Andrictemplate <typename _Tp, typename _Tv> _LIBCPP_INLINE_VISIBILITY 642*0b57cec5SDimitry Andrictypename enable_if<is_assignable<_Tp&, _Tv>::value>::type 643*0b57cec5SDimitry Andric__cxx_atomic_assign_volatile(_Tp& __a_value, _Tv const& __val) { 644*0b57cec5SDimitry Andric __a_value = __val; 645*0b57cec5SDimitry Andric} 646*0b57cec5SDimitry Andrictemplate <typename _Tp, typename _Tv> _LIBCPP_INLINE_VISIBILITY 647*0b57cec5SDimitry Andrictypename enable_if<is_assignable<_Tp&, _Tv>::value>::type 648*0b57cec5SDimitry Andric__cxx_atomic_assign_volatile(_Tp volatile& __a_value, _Tv volatile const& __val) { 649*0b57cec5SDimitry Andric volatile char* __to = reinterpret_cast<volatile char*>(&__a_value); 650*0b57cec5SDimitry Andric volatile char* __end = __to + sizeof(_Tp); 651*0b57cec5SDimitry Andric volatile const char* __from = reinterpret_cast<volatile const char*>(&__val); 652*0b57cec5SDimitry Andric while (__to != __end) 653*0b57cec5SDimitry Andric *__to++ = *__from++; 654*0b57cec5SDimitry Andric} 655*0b57cec5SDimitry Andric 656*0b57cec5SDimitry Andric#endif 657*0b57cec5SDimitry Andric 658*0b57cec5SDimitry Andric#if defined(_LIBCPP_HAS_GCC_ATOMIC_IMP) 659*0b57cec5SDimitry Andric 660*0b57cec5SDimitry Andrictemplate <typename _Tp> 661*0b57cec5SDimitry Andricstruct __cxx_atomic_base_impl { 662*0b57cec5SDimitry Andric 663*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 664*0b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 665*0b57cec5SDimitry Andric __cxx_atomic_base_impl() _NOEXCEPT = default; 666*0b57cec5SDimitry Andric#else 667*0b57cec5SDimitry Andric __cxx_atomic_base_impl() _NOEXCEPT : __a_value() {} 668*0b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG 669*0b57cec5SDimitry Andric _LIBCPP_CONSTEXPR explicit __cxx_atomic_base_impl(_Tp value) _NOEXCEPT 670*0b57cec5SDimitry Andric : __a_value(value) {} 671*0b57cec5SDimitry Andric _Tp __a_value; 672*0b57cec5SDimitry Andric}; 673*0b57cec5SDimitry Andric 674*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY inline _LIBCPP_CONSTEXPR int __to_gcc_order(memory_order __order) { 675*0b57cec5SDimitry Andric // Avoid switch statement to make this a constexpr. 676*0b57cec5SDimitry Andric return __order == memory_order_relaxed ? __ATOMIC_RELAXED: 677*0b57cec5SDimitry Andric (__order == memory_order_acquire ? __ATOMIC_ACQUIRE: 678*0b57cec5SDimitry Andric (__order == memory_order_release ? __ATOMIC_RELEASE: 679*0b57cec5SDimitry Andric (__order == memory_order_seq_cst ? __ATOMIC_SEQ_CST: 680*0b57cec5SDimitry Andric (__order == memory_order_acq_rel ? __ATOMIC_ACQ_REL: 681*0b57cec5SDimitry Andric __ATOMIC_CONSUME)))); 682*0b57cec5SDimitry Andric} 683*0b57cec5SDimitry Andric 684*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY inline _LIBCPP_CONSTEXPR int __to_gcc_failure_order(memory_order __order) { 685*0b57cec5SDimitry Andric // Avoid switch statement to make this a constexpr. 686*0b57cec5SDimitry Andric return __order == memory_order_relaxed ? __ATOMIC_RELAXED: 687*0b57cec5SDimitry Andric (__order == memory_order_acquire ? __ATOMIC_ACQUIRE: 688*0b57cec5SDimitry Andric (__order == memory_order_release ? __ATOMIC_RELAXED: 689*0b57cec5SDimitry Andric (__order == memory_order_seq_cst ? __ATOMIC_SEQ_CST: 690*0b57cec5SDimitry Andric (__order == memory_order_acq_rel ? __ATOMIC_ACQUIRE: 691*0b57cec5SDimitry Andric __ATOMIC_CONSUME)))); 692*0b57cec5SDimitry Andric} 693*0b57cec5SDimitry Andric 694*0b57cec5SDimitry Andrictemplate <typename _Tp> 695*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 696*0b57cec5SDimitry Andricvoid __cxx_atomic_init(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __val) { 697*0b57cec5SDimitry Andric __cxx_atomic_assign_volatile(__a->__a_value, __val); 698*0b57cec5SDimitry Andric} 699*0b57cec5SDimitry Andric 700*0b57cec5SDimitry Andrictemplate <typename _Tp> 701*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 702*0b57cec5SDimitry Andricvoid __cxx_atomic_init(__cxx_atomic_base_impl<_Tp>* __a, _Tp __val) { 703*0b57cec5SDimitry Andric __a->__a_value = __val; 704*0b57cec5SDimitry Andric} 705*0b57cec5SDimitry Andric 706*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY inline 707*0b57cec5SDimitry Andricvoid __cxx_atomic_thread_fence(memory_order __order) { 708*0b57cec5SDimitry Andric __atomic_thread_fence(__to_gcc_order(__order)); 709*0b57cec5SDimitry Andric} 710*0b57cec5SDimitry Andric 711*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY inline 712*0b57cec5SDimitry Andricvoid __cxx_atomic_signal_fence(memory_order __order) { 713*0b57cec5SDimitry Andric __atomic_signal_fence(__to_gcc_order(__order)); 714*0b57cec5SDimitry Andric} 715*0b57cec5SDimitry Andric 716*0b57cec5SDimitry Andrictemplate <typename _Tp> 717*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 718*0b57cec5SDimitry Andricvoid __cxx_atomic_store(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __val, 719*0b57cec5SDimitry Andric memory_order __order) { 720*0b57cec5SDimitry Andric __atomic_store(&__a->__a_value, &__val, 721*0b57cec5SDimitry Andric __to_gcc_order(__order)); 722*0b57cec5SDimitry Andric} 723*0b57cec5SDimitry Andric 724*0b57cec5SDimitry Andrictemplate <typename _Tp> 725*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 726*0b57cec5SDimitry Andricvoid __cxx_atomic_store(__cxx_atomic_base_impl<_Tp>* __a, _Tp __val, 727*0b57cec5SDimitry Andric memory_order __order) { 728*0b57cec5SDimitry Andric __atomic_store(&__a->__a_value, &__val, 729*0b57cec5SDimitry Andric __to_gcc_order(__order)); 730*0b57cec5SDimitry Andric} 731*0b57cec5SDimitry Andric 732*0b57cec5SDimitry Andrictemplate <typename _Tp> 733*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 734*0b57cec5SDimitry Andric_Tp __cxx_atomic_load(const volatile __cxx_atomic_base_impl<_Tp>* __a, 735*0b57cec5SDimitry Andric memory_order __order) { 736*0b57cec5SDimitry Andric _Tp __ret; 737*0b57cec5SDimitry Andric __atomic_load(&__a->__a_value, &__ret, 738*0b57cec5SDimitry Andric __to_gcc_order(__order)); 739*0b57cec5SDimitry Andric return __ret; 740*0b57cec5SDimitry Andric} 741*0b57cec5SDimitry Andric 742*0b57cec5SDimitry Andrictemplate <typename _Tp> 743*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 744*0b57cec5SDimitry Andric_Tp __cxx_atomic_load(const __cxx_atomic_base_impl<_Tp>* __a, memory_order __order) { 745*0b57cec5SDimitry Andric _Tp __ret; 746*0b57cec5SDimitry Andric __atomic_load(&__a->__a_value, &__ret, 747*0b57cec5SDimitry Andric __to_gcc_order(__order)); 748*0b57cec5SDimitry Andric return __ret; 749*0b57cec5SDimitry Andric} 750*0b57cec5SDimitry Andric 751*0b57cec5SDimitry Andrictemplate <typename _Tp> 752*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 753*0b57cec5SDimitry Andric_Tp __cxx_atomic_exchange(volatile __cxx_atomic_base_impl<_Tp>* __a, 754*0b57cec5SDimitry Andric _Tp __value, memory_order __order) { 755*0b57cec5SDimitry Andric _Tp __ret; 756*0b57cec5SDimitry Andric __atomic_exchange(&__a->__a_value, &__value, &__ret, 757*0b57cec5SDimitry Andric __to_gcc_order(__order)); 758*0b57cec5SDimitry Andric return __ret; 759*0b57cec5SDimitry Andric} 760*0b57cec5SDimitry Andric 761*0b57cec5SDimitry Andrictemplate <typename _Tp> 762*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 763*0b57cec5SDimitry Andric_Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp>* __a, _Tp __value, 764*0b57cec5SDimitry Andric memory_order __order) { 765*0b57cec5SDimitry Andric _Tp __ret; 766*0b57cec5SDimitry Andric __atomic_exchange(&__a->__a_value, &__value, &__ret, 767*0b57cec5SDimitry Andric __to_gcc_order(__order)); 768*0b57cec5SDimitry Andric return __ret; 769*0b57cec5SDimitry Andric} 770*0b57cec5SDimitry Andric 771*0b57cec5SDimitry Andrictemplate <typename _Tp> 772*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 773*0b57cec5SDimitry Andricbool __cxx_atomic_compare_exchange_strong( 774*0b57cec5SDimitry Andric volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, 775*0b57cec5SDimitry Andric memory_order __success, memory_order __failure) { 776*0b57cec5SDimitry Andric return __atomic_compare_exchange(&__a->__a_value, __expected, &__value, 777*0b57cec5SDimitry Andric false, 778*0b57cec5SDimitry Andric __to_gcc_order(__success), 779*0b57cec5SDimitry Andric __to_gcc_failure_order(__failure)); 780*0b57cec5SDimitry Andric} 781*0b57cec5SDimitry Andric 782*0b57cec5SDimitry Andrictemplate <typename _Tp> 783*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 784*0b57cec5SDimitry Andricbool __cxx_atomic_compare_exchange_strong( 785*0b57cec5SDimitry Andric __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success, 786*0b57cec5SDimitry Andric memory_order __failure) { 787*0b57cec5SDimitry Andric return __atomic_compare_exchange(&__a->__a_value, __expected, &__value, 788*0b57cec5SDimitry Andric false, 789*0b57cec5SDimitry Andric __to_gcc_order(__success), 790*0b57cec5SDimitry Andric __to_gcc_failure_order(__failure)); 791*0b57cec5SDimitry Andric} 792*0b57cec5SDimitry Andric 793*0b57cec5SDimitry Andrictemplate <typename _Tp> 794*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 795*0b57cec5SDimitry Andricbool __cxx_atomic_compare_exchange_weak( 796*0b57cec5SDimitry Andric volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, 797*0b57cec5SDimitry Andric memory_order __success, memory_order __failure) { 798*0b57cec5SDimitry Andric return __atomic_compare_exchange(&__a->__a_value, __expected, &__value, 799*0b57cec5SDimitry Andric true, 800*0b57cec5SDimitry Andric __to_gcc_order(__success), 801*0b57cec5SDimitry Andric __to_gcc_failure_order(__failure)); 802*0b57cec5SDimitry Andric} 803*0b57cec5SDimitry Andric 804*0b57cec5SDimitry Andrictemplate <typename _Tp> 805*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 806*0b57cec5SDimitry Andricbool __cxx_atomic_compare_exchange_weak( 807*0b57cec5SDimitry Andric __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success, 808*0b57cec5SDimitry Andric memory_order __failure) { 809*0b57cec5SDimitry Andric return __atomic_compare_exchange(&__a->__a_value, __expected, &__value, 810*0b57cec5SDimitry Andric true, 811*0b57cec5SDimitry Andric __to_gcc_order(__success), 812*0b57cec5SDimitry Andric __to_gcc_failure_order(__failure)); 813*0b57cec5SDimitry Andric} 814*0b57cec5SDimitry Andric 815*0b57cec5SDimitry Andrictemplate <typename _Tp> 816*0b57cec5SDimitry Andricstruct __skip_amt { enum {value = 1}; }; 817*0b57cec5SDimitry Andric 818*0b57cec5SDimitry Andrictemplate <typename _Tp> 819*0b57cec5SDimitry Andricstruct __skip_amt<_Tp*> { enum {value = sizeof(_Tp)}; }; 820*0b57cec5SDimitry Andric 821*0b57cec5SDimitry Andric// FIXME: Haven't figured out what the spec says about using arrays with 822*0b57cec5SDimitry Andric// atomic_fetch_add. Force a failure rather than creating bad behavior. 823*0b57cec5SDimitry Andrictemplate <typename _Tp> 824*0b57cec5SDimitry Andricstruct __skip_amt<_Tp[]> { }; 825*0b57cec5SDimitry Andrictemplate <typename _Tp, int n> 826*0b57cec5SDimitry Andricstruct __skip_amt<_Tp[n]> { }; 827*0b57cec5SDimitry Andric 828*0b57cec5SDimitry Andrictemplate <typename _Tp, typename _Td> 829*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 830*0b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_add(volatile __cxx_atomic_base_impl<_Tp>* __a, 831*0b57cec5SDimitry Andric _Td __delta, memory_order __order) { 832*0b57cec5SDimitry Andric return __atomic_fetch_add(&__a->__a_value, __delta * __skip_amt<_Tp>::value, 833*0b57cec5SDimitry Andric __to_gcc_order(__order)); 834*0b57cec5SDimitry Andric} 835*0b57cec5SDimitry Andric 836*0b57cec5SDimitry Andrictemplate <typename _Tp, typename _Td> 837*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 838*0b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp>* __a, _Td __delta, 839*0b57cec5SDimitry Andric memory_order __order) { 840*0b57cec5SDimitry Andric return __atomic_fetch_add(&__a->__a_value, __delta * __skip_amt<_Tp>::value, 841*0b57cec5SDimitry Andric __to_gcc_order(__order)); 842*0b57cec5SDimitry Andric} 843*0b57cec5SDimitry Andric 844*0b57cec5SDimitry Andrictemplate <typename _Tp, typename _Td> 845*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 846*0b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_sub(volatile __cxx_atomic_base_impl<_Tp>* __a, 847*0b57cec5SDimitry Andric _Td __delta, memory_order __order) { 848*0b57cec5SDimitry Andric return __atomic_fetch_sub(&__a->__a_value, __delta * __skip_amt<_Tp>::value, 849*0b57cec5SDimitry Andric __to_gcc_order(__order)); 850*0b57cec5SDimitry Andric} 851*0b57cec5SDimitry Andric 852*0b57cec5SDimitry Andrictemplate <typename _Tp, typename _Td> 853*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 854*0b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp>* __a, _Td __delta, 855*0b57cec5SDimitry Andric memory_order __order) { 856*0b57cec5SDimitry Andric return __atomic_fetch_sub(&__a->__a_value, __delta * __skip_amt<_Tp>::value, 857*0b57cec5SDimitry Andric __to_gcc_order(__order)); 858*0b57cec5SDimitry Andric} 859*0b57cec5SDimitry Andric 860*0b57cec5SDimitry Andrictemplate <typename _Tp> 861*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 862*0b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_and(volatile __cxx_atomic_base_impl<_Tp>* __a, 863*0b57cec5SDimitry Andric _Tp __pattern, memory_order __order) { 864*0b57cec5SDimitry Andric return __atomic_fetch_and(&__a->__a_value, __pattern, 865*0b57cec5SDimitry Andric __to_gcc_order(__order)); 866*0b57cec5SDimitry Andric} 867*0b57cec5SDimitry Andric 868*0b57cec5SDimitry Andrictemplate <typename _Tp> 869*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 870*0b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp>* __a, 871*0b57cec5SDimitry Andric _Tp __pattern, memory_order __order) { 872*0b57cec5SDimitry Andric return __atomic_fetch_and(&__a->__a_value, __pattern, 873*0b57cec5SDimitry Andric __to_gcc_order(__order)); 874*0b57cec5SDimitry Andric} 875*0b57cec5SDimitry Andric 876*0b57cec5SDimitry Andrictemplate <typename _Tp> 877*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 878*0b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_or(volatile __cxx_atomic_base_impl<_Tp>* __a, 879*0b57cec5SDimitry Andric _Tp __pattern, memory_order __order) { 880*0b57cec5SDimitry Andric return __atomic_fetch_or(&__a->__a_value, __pattern, 881*0b57cec5SDimitry Andric __to_gcc_order(__order)); 882*0b57cec5SDimitry Andric} 883*0b57cec5SDimitry Andric 884*0b57cec5SDimitry Andrictemplate <typename _Tp> 885*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 886*0b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern, 887*0b57cec5SDimitry Andric memory_order __order) { 888*0b57cec5SDimitry Andric return __atomic_fetch_or(&__a->__a_value, __pattern, 889*0b57cec5SDimitry Andric __to_gcc_order(__order)); 890*0b57cec5SDimitry Andric} 891*0b57cec5SDimitry Andric 892*0b57cec5SDimitry Andrictemplate <typename _Tp> 893*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 894*0b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_xor(volatile __cxx_atomic_base_impl<_Tp>* __a, 895*0b57cec5SDimitry Andric _Tp __pattern, memory_order __order) { 896*0b57cec5SDimitry Andric return __atomic_fetch_xor(&__a->__a_value, __pattern, 897*0b57cec5SDimitry Andric __to_gcc_order(__order)); 898*0b57cec5SDimitry Andric} 899*0b57cec5SDimitry Andric 900*0b57cec5SDimitry Andrictemplate <typename _Tp> 901*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 902*0b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern, 903*0b57cec5SDimitry Andric memory_order __order) { 904*0b57cec5SDimitry Andric return __atomic_fetch_xor(&__a->__a_value, __pattern, 905*0b57cec5SDimitry Andric __to_gcc_order(__order)); 906*0b57cec5SDimitry Andric} 907*0b57cec5SDimitry Andric 908*0b57cec5SDimitry Andric#define __cxx_atomic_is_lock_free(__s) __atomic_is_lock_free(__s, 0) 909*0b57cec5SDimitry Andric 910*0b57cec5SDimitry Andric#elif defined(_LIBCPP_HAS_C_ATOMIC_IMP) 911*0b57cec5SDimitry Andric 912*0b57cec5SDimitry Andrictemplate <typename _Tp> 913*0b57cec5SDimitry Andricstruct __cxx_atomic_base_impl { 914*0b57cec5SDimitry Andric 915*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 916*0b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 917*0b57cec5SDimitry Andric __cxx_atomic_base_impl() _NOEXCEPT = default; 918*0b57cec5SDimitry Andric#else 919*0b57cec5SDimitry Andric __cxx_atomic_base_impl() _NOEXCEPT : __a_value() {} 920*0b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG 921*0b57cec5SDimitry Andric _LIBCPP_CONSTEXPR explicit __cxx_atomic_base_impl(_Tp value) _NOEXCEPT 922*0b57cec5SDimitry Andric : __a_value(value) {} 923*0b57cec5SDimitry Andric _Atomic(_Tp) __a_value; 924*0b57cec5SDimitry Andric}; 925*0b57cec5SDimitry Andric 926*0b57cec5SDimitry Andric#define __cxx_atomic_is_lock_free(__s) __c11_atomic_is_lock_free(__s) 927*0b57cec5SDimitry Andric 928*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY inline 929*0b57cec5SDimitry Andricvoid __cxx_atomic_thread_fence(memory_order __order) _NOEXCEPT { 930*0b57cec5SDimitry Andric __c11_atomic_thread_fence(static_cast<__memory_order_underlying_t>(__order)); 931*0b57cec5SDimitry Andric} 932*0b57cec5SDimitry Andric 933*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY inline 934*0b57cec5SDimitry Andricvoid __cxx_atomic_signal_fence(memory_order __order) _NOEXCEPT { 935*0b57cec5SDimitry Andric __c11_atomic_signal_fence(static_cast<__memory_order_underlying_t>(__order)); 936*0b57cec5SDimitry Andric} 937*0b57cec5SDimitry Andric 938*0b57cec5SDimitry Andrictemplate<class _Tp> 939*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 940*0b57cec5SDimitry Andricvoid __cxx_atomic_init(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __val) _NOEXCEPT { 941*0b57cec5SDimitry Andric __c11_atomic_init(&__a->__a_value, __val); 942*0b57cec5SDimitry Andric} 943*0b57cec5SDimitry Andrictemplate<class _Tp> 944*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 945*0b57cec5SDimitry Andricvoid __cxx_atomic_init(__cxx_atomic_base_impl<_Tp> * __a, _Tp __val) _NOEXCEPT { 946*0b57cec5SDimitry Andric __c11_atomic_init(&__a->__a_value, __val); 947*0b57cec5SDimitry Andric} 948*0b57cec5SDimitry Andric 949*0b57cec5SDimitry Andrictemplate<class _Tp> 950*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 951*0b57cec5SDimitry Andricvoid __cxx_atomic_store(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __val, memory_order __order) _NOEXCEPT { 952*0b57cec5SDimitry Andric __c11_atomic_store(&__a->__a_value, __val, static_cast<__memory_order_underlying_t>(__order)); 953*0b57cec5SDimitry Andric} 954*0b57cec5SDimitry Andrictemplate<class _Tp> 955*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 956*0b57cec5SDimitry Andricvoid __cxx_atomic_store(__cxx_atomic_base_impl<_Tp> * __a, _Tp __val, memory_order __order) _NOEXCEPT { 957*0b57cec5SDimitry Andric __c11_atomic_store(&__a->__a_value, __val, static_cast<__memory_order_underlying_t>(__order)); 958*0b57cec5SDimitry Andric} 959*0b57cec5SDimitry Andric 960*0b57cec5SDimitry Andrictemplate<class _Tp> 961*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 962*0b57cec5SDimitry Andric_Tp __cxx_atomic_load(__cxx_atomic_base_impl<_Tp> const volatile* __a, memory_order __order) _NOEXCEPT { 963*0b57cec5SDimitry Andric using __ptr_type = typename remove_const<decltype(__a->__a_value)>::type*; 964*0b57cec5SDimitry Andric return __c11_atomic_load(const_cast<__ptr_type>(&__a->__a_value), static_cast<__memory_order_underlying_t>(__order)); 965*0b57cec5SDimitry Andric} 966*0b57cec5SDimitry Andrictemplate<class _Tp> 967*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 968*0b57cec5SDimitry Andric_Tp __cxx_atomic_load(__cxx_atomic_base_impl<_Tp> const* __a, memory_order __order) _NOEXCEPT { 969*0b57cec5SDimitry Andric using __ptr_type = typename remove_const<decltype(__a->__a_value)>::type*; 970*0b57cec5SDimitry Andric return __c11_atomic_load(const_cast<__ptr_type>(&__a->__a_value), static_cast<__memory_order_underlying_t>(__order)); 971*0b57cec5SDimitry Andric} 972*0b57cec5SDimitry Andric 973*0b57cec5SDimitry Andrictemplate<class _Tp> 974*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 975*0b57cec5SDimitry Andric_Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __value, memory_order __order) _NOEXCEPT { 976*0b57cec5SDimitry Andric return __c11_atomic_exchange(&__a->__a_value, __value, static_cast<__memory_order_underlying_t>(__order)); 977*0b57cec5SDimitry Andric} 978*0b57cec5SDimitry Andrictemplate<class _Tp> 979*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 980*0b57cec5SDimitry Andric_Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp> * __a, _Tp __value, memory_order __order) _NOEXCEPT { 981*0b57cec5SDimitry Andric return __c11_atomic_exchange(&__a->__a_value, __value, static_cast<__memory_order_underlying_t>(__order)); 982*0b57cec5SDimitry Andric} 983*0b57cec5SDimitry Andric 984*0b57cec5SDimitry Andrictemplate<class _Tp> 985*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 986*0b57cec5SDimitry Andricbool __cxx_atomic_compare_exchange_strong(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT { 987*0b57cec5SDimitry Andric return __c11_atomic_compare_exchange_strong(&__a->__a_value, __expected, __value, static_cast<__memory_order_underlying_t>(__success), static_cast<__memory_order_underlying_t>(__failure)); 988*0b57cec5SDimitry Andric} 989*0b57cec5SDimitry Andrictemplate<class _Tp> 990*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 991*0b57cec5SDimitry Andricbool __cxx_atomic_compare_exchange_strong(__cxx_atomic_base_impl<_Tp> * __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT { 992*0b57cec5SDimitry Andric return __c11_atomic_compare_exchange_strong(&__a->__a_value, __expected, __value, static_cast<__memory_order_underlying_t>(__success), static_cast<__memory_order_underlying_t>(__failure)); 993*0b57cec5SDimitry Andric} 994*0b57cec5SDimitry Andric 995*0b57cec5SDimitry Andrictemplate<class _Tp> 996*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 997*0b57cec5SDimitry Andricbool __cxx_atomic_compare_exchange_weak(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT { 998*0b57cec5SDimitry Andric return __c11_atomic_compare_exchange_weak(&__a->__a_value, __expected, __value, static_cast<__memory_order_underlying_t>(__success), static_cast<__memory_order_underlying_t>(__failure)); 999*0b57cec5SDimitry Andric} 1000*0b57cec5SDimitry Andrictemplate<class _Tp> 1001*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 1002*0b57cec5SDimitry Andricbool __cxx_atomic_compare_exchange_weak(__cxx_atomic_base_impl<_Tp> * __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT { 1003*0b57cec5SDimitry Andric return __c11_atomic_compare_exchange_weak(&__a->__a_value, __expected, __value, static_cast<__memory_order_underlying_t>(__success), static_cast<__memory_order_underlying_t>(__failure)); 1004*0b57cec5SDimitry Andric} 1005*0b57cec5SDimitry Andric 1006*0b57cec5SDimitry Andrictemplate<class _Tp> 1007*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 1008*0b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __delta, memory_order __order) _NOEXCEPT { 1009*0b57cec5SDimitry Andric return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order)); 1010*0b57cec5SDimitry Andric} 1011*0b57cec5SDimitry Andrictemplate<class _Tp> 1012*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 1013*0b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp> * __a, _Tp __delta, memory_order __order) _NOEXCEPT { 1014*0b57cec5SDimitry Andric return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order)); 1015*0b57cec5SDimitry Andric} 1016*0b57cec5SDimitry Andric 1017*0b57cec5SDimitry Andrictemplate<class _Tp> 1018*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 1019*0b57cec5SDimitry Andric_Tp* __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp*> volatile* __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT { 1020*0b57cec5SDimitry Andric return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order)); 1021*0b57cec5SDimitry Andric} 1022*0b57cec5SDimitry Andrictemplate<class _Tp> 1023*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 1024*0b57cec5SDimitry Andric_Tp* __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp*> * __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT { 1025*0b57cec5SDimitry Andric return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order)); 1026*0b57cec5SDimitry Andric} 1027*0b57cec5SDimitry Andric 1028*0b57cec5SDimitry Andrictemplate<class _Tp> 1029*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 1030*0b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __delta, memory_order __order) _NOEXCEPT { 1031*0b57cec5SDimitry Andric return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order)); 1032*0b57cec5SDimitry Andric} 1033*0b57cec5SDimitry Andrictemplate<class _Tp> 1034*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 1035*0b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp> * __a, _Tp __delta, memory_order __order) _NOEXCEPT { 1036*0b57cec5SDimitry Andric return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order)); 1037*0b57cec5SDimitry Andric} 1038*0b57cec5SDimitry Andrictemplate<class _Tp> 1039*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 1040*0b57cec5SDimitry Andric_Tp* __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp*> volatile* __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT { 1041*0b57cec5SDimitry Andric return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order)); 1042*0b57cec5SDimitry Andric} 1043*0b57cec5SDimitry Andrictemplate<class _Tp> 1044*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 1045*0b57cec5SDimitry Andric_Tp* __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp*> * __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT { 1046*0b57cec5SDimitry Andric return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order)); 1047*0b57cec5SDimitry Andric} 1048*0b57cec5SDimitry Andric 1049*0b57cec5SDimitry Andrictemplate<class _Tp> 1050*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 1051*0b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT { 1052*0b57cec5SDimitry Andric return __c11_atomic_fetch_and(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order)); 1053*0b57cec5SDimitry Andric} 1054*0b57cec5SDimitry Andrictemplate<class _Tp> 1055*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 1056*0b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, memory_order __order) _NOEXCEPT { 1057*0b57cec5SDimitry Andric return __c11_atomic_fetch_and(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order)); 1058*0b57cec5SDimitry Andric} 1059*0b57cec5SDimitry Andric 1060*0b57cec5SDimitry Andrictemplate<class _Tp> 1061*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 1062*0b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT { 1063*0b57cec5SDimitry Andric return __c11_atomic_fetch_or(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order)); 1064*0b57cec5SDimitry Andric} 1065*0b57cec5SDimitry Andrictemplate<class _Tp> 1066*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 1067*0b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, memory_order __order) _NOEXCEPT { 1068*0b57cec5SDimitry Andric return __c11_atomic_fetch_or(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order)); 1069*0b57cec5SDimitry Andric} 1070*0b57cec5SDimitry Andric 1071*0b57cec5SDimitry Andrictemplate<class _Tp> 1072*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 1073*0b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT { 1074*0b57cec5SDimitry Andric return __c11_atomic_fetch_xor(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order)); 1075*0b57cec5SDimitry Andric} 1076*0b57cec5SDimitry Andrictemplate<class _Tp> 1077*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 1078*0b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, memory_order __order) _NOEXCEPT { 1079*0b57cec5SDimitry Andric return __c11_atomic_fetch_xor(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order)); 1080*0b57cec5SDimitry Andric} 1081*0b57cec5SDimitry Andric 1082*0b57cec5SDimitry Andric#endif // _LIBCPP_HAS_GCC_ATOMIC_IMP, _LIBCPP_HAS_C_ATOMIC_IMP 1083*0b57cec5SDimitry Andric 1084*0b57cec5SDimitry Andrictemplate <class _Tp> 1085*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 1086*0b57cec5SDimitry Andric_Tp kill_dependency(_Tp __y) _NOEXCEPT 1087*0b57cec5SDimitry Andric{ 1088*0b57cec5SDimitry Andric return __y; 1089*0b57cec5SDimitry Andric} 1090*0b57cec5SDimitry Andric 1091*0b57cec5SDimitry Andric#if defined(__CLANG_ATOMIC_BOOL_LOCK_FREE) 1092*0b57cec5SDimitry Andric# define ATOMIC_BOOL_LOCK_FREE __CLANG_ATOMIC_BOOL_LOCK_FREE 1093*0b57cec5SDimitry Andric# define ATOMIC_CHAR_LOCK_FREE __CLANG_ATOMIC_CHAR_LOCK_FREE 1094*0b57cec5SDimitry Andric# define ATOMIC_CHAR16_T_LOCK_FREE __CLANG_ATOMIC_CHAR16_T_LOCK_FREE 1095*0b57cec5SDimitry Andric# define ATOMIC_CHAR32_T_LOCK_FREE __CLANG_ATOMIC_CHAR32_T_LOCK_FREE 1096*0b57cec5SDimitry Andric# define ATOMIC_WCHAR_T_LOCK_FREE __CLANG_ATOMIC_WCHAR_T_LOCK_FREE 1097*0b57cec5SDimitry Andric# define ATOMIC_SHORT_LOCK_FREE __CLANG_ATOMIC_SHORT_LOCK_FREE 1098*0b57cec5SDimitry Andric# define ATOMIC_INT_LOCK_FREE __CLANG_ATOMIC_INT_LOCK_FREE 1099*0b57cec5SDimitry Andric# define ATOMIC_LONG_LOCK_FREE __CLANG_ATOMIC_LONG_LOCK_FREE 1100*0b57cec5SDimitry Andric# define ATOMIC_LLONG_LOCK_FREE __CLANG_ATOMIC_LLONG_LOCK_FREE 1101*0b57cec5SDimitry Andric# define ATOMIC_POINTER_LOCK_FREE __CLANG_ATOMIC_POINTER_LOCK_FREE 1102*0b57cec5SDimitry Andric#elif defined(__GCC_ATOMIC_BOOL_LOCK_FREE) 1103*0b57cec5SDimitry Andric# define ATOMIC_BOOL_LOCK_FREE __GCC_ATOMIC_BOOL_LOCK_FREE 1104*0b57cec5SDimitry Andric# define ATOMIC_CHAR_LOCK_FREE __GCC_ATOMIC_CHAR_LOCK_FREE 1105*0b57cec5SDimitry Andric# define ATOMIC_CHAR16_T_LOCK_FREE __GCC_ATOMIC_CHAR16_T_LOCK_FREE 1106*0b57cec5SDimitry Andric# define ATOMIC_CHAR32_T_LOCK_FREE __GCC_ATOMIC_CHAR32_T_LOCK_FREE 1107*0b57cec5SDimitry Andric# define ATOMIC_WCHAR_T_LOCK_FREE __GCC_ATOMIC_WCHAR_T_LOCK_FREE 1108*0b57cec5SDimitry Andric# define ATOMIC_SHORT_LOCK_FREE __GCC_ATOMIC_SHORT_LOCK_FREE 1109*0b57cec5SDimitry Andric# define ATOMIC_INT_LOCK_FREE __GCC_ATOMIC_INT_LOCK_FREE 1110*0b57cec5SDimitry Andric# define ATOMIC_LONG_LOCK_FREE __GCC_ATOMIC_LONG_LOCK_FREE 1111*0b57cec5SDimitry Andric# define ATOMIC_LLONG_LOCK_FREE __GCC_ATOMIC_LLONG_LOCK_FREE 1112*0b57cec5SDimitry Andric# define ATOMIC_POINTER_LOCK_FREE __GCC_ATOMIC_POINTER_LOCK_FREE 1113*0b57cec5SDimitry Andric#endif 1114*0b57cec5SDimitry Andric 1115*0b57cec5SDimitry Andric#ifdef _LIBCPP_ATOMIC_ONLY_USE_BUILTINS 1116*0b57cec5SDimitry Andric 1117*0b57cec5SDimitry Andrictemplate<typename _Tp> 1118*0b57cec5SDimitry Andricstruct __cxx_atomic_lock_impl { 1119*0b57cec5SDimitry Andric 1120*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1121*0b57cec5SDimitry Andric __cxx_atomic_lock_impl() _NOEXCEPT 1122*0b57cec5SDimitry Andric : __a_value(), __a_lock(0) {} 1123*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR explicit 1124*0b57cec5SDimitry Andric __cxx_atomic_lock_impl(_Tp value) _NOEXCEPT 1125*0b57cec5SDimitry Andric : __a_value(value), __a_lock(0) {} 1126*0b57cec5SDimitry Andric 1127*0b57cec5SDimitry Andric _Tp __a_value; 1128*0b57cec5SDimitry Andric mutable __cxx_atomic_base_impl<_LIBCPP_ATOMIC_FLAG_TYPE> __a_lock; 1129*0b57cec5SDimitry Andric 1130*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY void __lock() const volatile { 1131*0b57cec5SDimitry Andric while(1 == __cxx_atomic_exchange(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(true), memory_order_acquire)) 1132*0b57cec5SDimitry Andric /*spin*/; 1133*0b57cec5SDimitry Andric } 1134*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY void __lock() const { 1135*0b57cec5SDimitry Andric while(1 == __cxx_atomic_exchange(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(true), memory_order_acquire)) 1136*0b57cec5SDimitry Andric /*spin*/; 1137*0b57cec5SDimitry Andric } 1138*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY void __unlock() const volatile { 1139*0b57cec5SDimitry Andric __cxx_atomic_store(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(false), memory_order_release); 1140*0b57cec5SDimitry Andric } 1141*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY void __unlock() const { 1142*0b57cec5SDimitry Andric __cxx_atomic_store(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(false), memory_order_release); 1143*0b57cec5SDimitry Andric } 1144*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY _Tp __read() const volatile { 1145*0b57cec5SDimitry Andric __lock(); 1146*0b57cec5SDimitry Andric _Tp __old; 1147*0b57cec5SDimitry Andric __cxx_atomic_assign_volatile(__old, __a_value); 1148*0b57cec5SDimitry Andric __unlock(); 1149*0b57cec5SDimitry Andric return __old; 1150*0b57cec5SDimitry Andric } 1151*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY _Tp __read() const { 1152*0b57cec5SDimitry Andric __lock(); 1153*0b57cec5SDimitry Andric _Tp __old = __a_value; 1154*0b57cec5SDimitry Andric __unlock(); 1155*0b57cec5SDimitry Andric return __old; 1156*0b57cec5SDimitry Andric } 1157*0b57cec5SDimitry Andric}; 1158*0b57cec5SDimitry Andric 1159*0b57cec5SDimitry Andrictemplate <typename _Tp> 1160*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 1161*0b57cec5SDimitry Andricvoid __cxx_atomic_init(volatile __cxx_atomic_lock_impl<_Tp>* __a, _Tp __val) { 1162*0b57cec5SDimitry Andric __cxx_atomic_assign_volatile(__a->__a_value, __val); 1163*0b57cec5SDimitry Andric} 1164*0b57cec5SDimitry Andrictemplate <typename _Tp> 1165*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 1166*0b57cec5SDimitry Andricvoid __cxx_atomic_init(__cxx_atomic_lock_impl<_Tp>* __a, _Tp __val) { 1167*0b57cec5SDimitry Andric __a->__a_value = __val; 1168*0b57cec5SDimitry Andric} 1169*0b57cec5SDimitry Andric 1170*0b57cec5SDimitry Andrictemplate <typename _Tp> 1171*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 1172*0b57cec5SDimitry Andricvoid __cxx_atomic_store(volatile __cxx_atomic_lock_impl<_Tp>* __a, _Tp __val, memory_order) { 1173*0b57cec5SDimitry Andric __a->__lock(); 1174*0b57cec5SDimitry Andric __cxx_atomic_assign_volatile(__a->__a_value, __val); 1175*0b57cec5SDimitry Andric __a->__unlock(); 1176*0b57cec5SDimitry Andric} 1177*0b57cec5SDimitry Andrictemplate <typename _Tp> 1178*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 1179*0b57cec5SDimitry Andricvoid __cxx_atomic_store(__cxx_atomic_lock_impl<_Tp>* __a, _Tp __val, memory_order) { 1180*0b57cec5SDimitry Andric __a->__lock(); 1181*0b57cec5SDimitry Andric __a->__a_value = __val; 1182*0b57cec5SDimitry Andric __a->__unlock(); 1183*0b57cec5SDimitry Andric} 1184*0b57cec5SDimitry Andric 1185*0b57cec5SDimitry Andrictemplate <typename _Tp> 1186*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 1187*0b57cec5SDimitry Andric_Tp __cxx_atomic_load(const volatile __cxx_atomic_lock_impl<_Tp>* __a, memory_order) { 1188*0b57cec5SDimitry Andric return __a->__read(); 1189*0b57cec5SDimitry Andric} 1190*0b57cec5SDimitry Andrictemplate <typename _Tp> 1191*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 1192*0b57cec5SDimitry Andric_Tp __cxx_atomic_load(const __cxx_atomic_lock_impl<_Tp>* __a, memory_order) { 1193*0b57cec5SDimitry Andric return __a->__read(); 1194*0b57cec5SDimitry Andric} 1195*0b57cec5SDimitry Andric 1196*0b57cec5SDimitry Andrictemplate <typename _Tp> 1197*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 1198*0b57cec5SDimitry Andric_Tp __cxx_atomic_exchange(volatile __cxx_atomic_lock_impl<_Tp>* __a, _Tp __value, memory_order) { 1199*0b57cec5SDimitry Andric __a->__lock(); 1200*0b57cec5SDimitry Andric _Tp __old; 1201*0b57cec5SDimitry Andric __cxx_atomic_assign_volatile(__old, __a->__a_value); 1202*0b57cec5SDimitry Andric __cxx_atomic_assign_volatile(__a->__a_value, __value); 1203*0b57cec5SDimitry Andric __a->__unlock(); 1204*0b57cec5SDimitry Andric return __old; 1205*0b57cec5SDimitry Andric} 1206*0b57cec5SDimitry Andrictemplate <typename _Tp> 1207*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 1208*0b57cec5SDimitry Andric_Tp __cxx_atomic_exchange(__cxx_atomic_lock_impl<_Tp>* __a, _Tp __value, memory_order) { 1209*0b57cec5SDimitry Andric __a->__lock(); 1210*0b57cec5SDimitry Andric _Tp __old = __a->__a_value; 1211*0b57cec5SDimitry Andric __a->__a_value = __value; 1212*0b57cec5SDimitry Andric __a->__unlock(); 1213*0b57cec5SDimitry Andric return __old; 1214*0b57cec5SDimitry Andric} 1215*0b57cec5SDimitry Andric 1216*0b57cec5SDimitry Andrictemplate <typename _Tp> 1217*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 1218*0b57cec5SDimitry Andricbool __cxx_atomic_compare_exchange_strong(volatile __cxx_atomic_lock_impl<_Tp>* __a, 1219*0b57cec5SDimitry Andric _Tp* __expected, _Tp __value, memory_order, memory_order) { 1220*0b57cec5SDimitry Andric __a->__lock(); 1221*0b57cec5SDimitry Andric _Tp temp; 1222*0b57cec5SDimitry Andric __cxx_atomic_assign_volatile(temp, __a->__a_value); 1223*0b57cec5SDimitry Andric bool __ret = temp == *__expected; 1224*0b57cec5SDimitry Andric if(__ret) 1225*0b57cec5SDimitry Andric __cxx_atomic_assign_volatile(__a->__a_value, __value); 1226*0b57cec5SDimitry Andric else 1227*0b57cec5SDimitry Andric __cxx_atomic_assign_volatile(*__expected, __a->__a_value); 1228*0b57cec5SDimitry Andric __a->__unlock(); 1229*0b57cec5SDimitry Andric return __ret; 1230*0b57cec5SDimitry Andric} 1231*0b57cec5SDimitry Andrictemplate <typename _Tp> 1232*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 1233*0b57cec5SDimitry Andricbool __cxx_atomic_compare_exchange_strong(__cxx_atomic_lock_impl<_Tp>* __a, 1234*0b57cec5SDimitry Andric _Tp* __expected, _Tp __value, memory_order, memory_order) { 1235*0b57cec5SDimitry Andric __a->__lock(); 1236*0b57cec5SDimitry Andric bool __ret = __a->__a_value == *__expected; 1237*0b57cec5SDimitry Andric if(__ret) 1238*0b57cec5SDimitry Andric __a->__a_value = __value; 1239*0b57cec5SDimitry Andric else 1240*0b57cec5SDimitry Andric *__expected = __a->__a_value; 1241*0b57cec5SDimitry Andric __a->__unlock(); 1242*0b57cec5SDimitry Andric return __ret; 1243*0b57cec5SDimitry Andric} 1244*0b57cec5SDimitry Andric 1245*0b57cec5SDimitry Andrictemplate <typename _Tp> 1246*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 1247*0b57cec5SDimitry Andricbool __cxx_atomic_compare_exchange_weak(volatile __cxx_atomic_lock_impl<_Tp>* __a, 1248*0b57cec5SDimitry Andric _Tp* __expected, _Tp __value, memory_order, memory_order) { 1249*0b57cec5SDimitry Andric __a->__lock(); 1250*0b57cec5SDimitry Andric _Tp temp; 1251*0b57cec5SDimitry Andric __cxx_atomic_assign_volatile(temp, __a->__a_value); 1252*0b57cec5SDimitry Andric bool __ret = temp == *__expected; 1253*0b57cec5SDimitry Andric if(__ret) 1254*0b57cec5SDimitry Andric __cxx_atomic_assign_volatile(__a->__a_value, __value); 1255*0b57cec5SDimitry Andric else 1256*0b57cec5SDimitry Andric __cxx_atomic_assign_volatile(*__expected, __a->__a_value); 1257*0b57cec5SDimitry Andric __a->__unlock(); 1258*0b57cec5SDimitry Andric return __ret; 1259*0b57cec5SDimitry Andric} 1260*0b57cec5SDimitry Andrictemplate <typename _Tp> 1261*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 1262*0b57cec5SDimitry Andricbool __cxx_atomic_compare_exchange_weak(__cxx_atomic_lock_impl<_Tp>* __a, 1263*0b57cec5SDimitry Andric _Tp* __expected, _Tp __value, memory_order, memory_order) { 1264*0b57cec5SDimitry Andric __a->__lock(); 1265*0b57cec5SDimitry Andric bool __ret = __a->__a_value == *__expected; 1266*0b57cec5SDimitry Andric if(__ret) 1267*0b57cec5SDimitry Andric __a->__a_value = __value; 1268*0b57cec5SDimitry Andric else 1269*0b57cec5SDimitry Andric *__expected = __a->__a_value; 1270*0b57cec5SDimitry Andric __a->__unlock(); 1271*0b57cec5SDimitry Andric return __ret; 1272*0b57cec5SDimitry Andric} 1273*0b57cec5SDimitry Andric 1274*0b57cec5SDimitry Andrictemplate <typename _Tp, typename _Td> 1275*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 1276*0b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_add(volatile __cxx_atomic_lock_impl<_Tp>* __a, 1277*0b57cec5SDimitry Andric _Td __delta, memory_order) { 1278*0b57cec5SDimitry Andric __a->__lock(); 1279*0b57cec5SDimitry Andric _Tp __old; 1280*0b57cec5SDimitry Andric __cxx_atomic_assign_volatile(__old, __a->__a_value); 1281*0b57cec5SDimitry Andric __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old + __delta)); 1282*0b57cec5SDimitry Andric __a->__unlock(); 1283*0b57cec5SDimitry Andric return __old; 1284*0b57cec5SDimitry Andric} 1285*0b57cec5SDimitry Andrictemplate <typename _Tp, typename _Td> 1286*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 1287*0b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_add(__cxx_atomic_lock_impl<_Tp>* __a, 1288*0b57cec5SDimitry Andric _Td __delta, memory_order) { 1289*0b57cec5SDimitry Andric __a->__lock(); 1290*0b57cec5SDimitry Andric _Tp __old = __a->__a_value; 1291*0b57cec5SDimitry Andric __a->__a_value += __delta; 1292*0b57cec5SDimitry Andric __a->__unlock(); 1293*0b57cec5SDimitry Andric return __old; 1294*0b57cec5SDimitry Andric} 1295*0b57cec5SDimitry Andric 1296*0b57cec5SDimitry Andrictemplate <typename _Tp, typename _Td> 1297*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 1298*0b57cec5SDimitry Andric_Tp* __cxx_atomic_fetch_add(volatile __cxx_atomic_lock_impl<_Tp*>* __a, 1299*0b57cec5SDimitry Andric ptrdiff_t __delta, memory_order) { 1300*0b57cec5SDimitry Andric __a->__lock(); 1301*0b57cec5SDimitry Andric _Tp* __old; 1302*0b57cec5SDimitry Andric __cxx_atomic_assign_volatile(__old, __a->__a_value); 1303*0b57cec5SDimitry Andric __cxx_atomic_assign_volatile(__a->__a_value, __old + __delta); 1304*0b57cec5SDimitry Andric __a->__unlock(); 1305*0b57cec5SDimitry Andric return __old; 1306*0b57cec5SDimitry Andric} 1307*0b57cec5SDimitry Andrictemplate <typename _Tp, typename _Td> 1308*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 1309*0b57cec5SDimitry Andric_Tp* __cxx_atomic_fetch_add(__cxx_atomic_lock_impl<_Tp*>* __a, 1310*0b57cec5SDimitry Andric ptrdiff_t __delta, memory_order) { 1311*0b57cec5SDimitry Andric __a->__lock(); 1312*0b57cec5SDimitry Andric _Tp* __old = __a->__a_value; 1313*0b57cec5SDimitry Andric __a->__a_value += __delta; 1314*0b57cec5SDimitry Andric __a->__unlock(); 1315*0b57cec5SDimitry Andric return __old; 1316*0b57cec5SDimitry Andric} 1317*0b57cec5SDimitry Andric 1318*0b57cec5SDimitry Andrictemplate <typename _Tp, typename _Td> 1319*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 1320*0b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_sub(volatile __cxx_atomic_lock_impl<_Tp>* __a, 1321*0b57cec5SDimitry Andric _Td __delta, memory_order) { 1322*0b57cec5SDimitry Andric __a->__lock(); 1323*0b57cec5SDimitry Andric _Tp __old; 1324*0b57cec5SDimitry Andric __cxx_atomic_assign_volatile(__old, __a->__a_value); 1325*0b57cec5SDimitry Andric __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old - __delta)); 1326*0b57cec5SDimitry Andric __a->__unlock(); 1327*0b57cec5SDimitry Andric return __old; 1328*0b57cec5SDimitry Andric} 1329*0b57cec5SDimitry Andrictemplate <typename _Tp, typename _Td> 1330*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 1331*0b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_sub(__cxx_atomic_lock_impl<_Tp>* __a, 1332*0b57cec5SDimitry Andric _Td __delta, memory_order) { 1333*0b57cec5SDimitry Andric __a->__lock(); 1334*0b57cec5SDimitry Andric _Tp __old = __a->__a_value; 1335*0b57cec5SDimitry Andric __a->__a_value -= __delta; 1336*0b57cec5SDimitry Andric __a->__unlock(); 1337*0b57cec5SDimitry Andric return __old; 1338*0b57cec5SDimitry Andric} 1339*0b57cec5SDimitry Andric 1340*0b57cec5SDimitry Andrictemplate <typename _Tp> 1341*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 1342*0b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_and(volatile __cxx_atomic_lock_impl<_Tp>* __a, 1343*0b57cec5SDimitry Andric _Tp __pattern, memory_order) { 1344*0b57cec5SDimitry Andric __a->__lock(); 1345*0b57cec5SDimitry Andric _Tp __old; 1346*0b57cec5SDimitry Andric __cxx_atomic_assign_volatile(__old, __a->__a_value); 1347*0b57cec5SDimitry Andric __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old & __pattern)); 1348*0b57cec5SDimitry Andric __a->__unlock(); 1349*0b57cec5SDimitry Andric return __old; 1350*0b57cec5SDimitry Andric} 1351*0b57cec5SDimitry Andrictemplate <typename _Tp> 1352*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 1353*0b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_and(__cxx_atomic_lock_impl<_Tp>* __a, 1354*0b57cec5SDimitry Andric _Tp __pattern, memory_order) { 1355*0b57cec5SDimitry Andric __a->__lock(); 1356*0b57cec5SDimitry Andric _Tp __old = __a->__a_value; 1357*0b57cec5SDimitry Andric __a->__a_value &= __pattern; 1358*0b57cec5SDimitry Andric __a->__unlock(); 1359*0b57cec5SDimitry Andric return __old; 1360*0b57cec5SDimitry Andric} 1361*0b57cec5SDimitry Andric 1362*0b57cec5SDimitry Andrictemplate <typename _Tp> 1363*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 1364*0b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_or(volatile __cxx_atomic_lock_impl<_Tp>* __a, 1365*0b57cec5SDimitry Andric _Tp __pattern, memory_order) { 1366*0b57cec5SDimitry Andric __a->__lock(); 1367*0b57cec5SDimitry Andric _Tp __old; 1368*0b57cec5SDimitry Andric __cxx_atomic_assign_volatile(__old, __a->__a_value); 1369*0b57cec5SDimitry Andric __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old | __pattern)); 1370*0b57cec5SDimitry Andric __a->__unlock(); 1371*0b57cec5SDimitry Andric return __old; 1372*0b57cec5SDimitry Andric} 1373*0b57cec5SDimitry Andrictemplate <typename _Tp> 1374*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 1375*0b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_or(__cxx_atomic_lock_impl<_Tp>* __a, 1376*0b57cec5SDimitry Andric _Tp __pattern, memory_order) { 1377*0b57cec5SDimitry Andric __a->__lock(); 1378*0b57cec5SDimitry Andric _Tp __old = __a->__a_value; 1379*0b57cec5SDimitry Andric __a->__a_value |= __pattern; 1380*0b57cec5SDimitry Andric __a->__unlock(); 1381*0b57cec5SDimitry Andric return __old; 1382*0b57cec5SDimitry Andric} 1383*0b57cec5SDimitry Andric 1384*0b57cec5SDimitry Andrictemplate <typename _Tp> 1385*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 1386*0b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_xor(volatile __cxx_atomic_lock_impl<_Tp>* __a, 1387*0b57cec5SDimitry Andric _Tp __pattern, memory_order) { 1388*0b57cec5SDimitry Andric __a->__lock(); 1389*0b57cec5SDimitry Andric _Tp __old; 1390*0b57cec5SDimitry Andric __cxx_atomic_assign_volatile(__old, __a->__a_value); 1391*0b57cec5SDimitry Andric __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old ^ __pattern)); 1392*0b57cec5SDimitry Andric __a->__unlock(); 1393*0b57cec5SDimitry Andric return __old; 1394*0b57cec5SDimitry Andric} 1395*0b57cec5SDimitry Andrictemplate <typename _Tp> 1396*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 1397*0b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_xor(__cxx_atomic_lock_impl<_Tp>* __a, 1398*0b57cec5SDimitry Andric _Tp __pattern, memory_order) { 1399*0b57cec5SDimitry Andric __a->__lock(); 1400*0b57cec5SDimitry Andric _Tp __old = __a->__a_value; 1401*0b57cec5SDimitry Andric __a->__a_value ^= __pattern; 1402*0b57cec5SDimitry Andric __a->__unlock(); 1403*0b57cec5SDimitry Andric return __old; 1404*0b57cec5SDimitry Andric} 1405*0b57cec5SDimitry Andric 1406*0b57cec5SDimitry Andric#ifdef __cpp_lib_atomic_is_always_lock_free 1407*0b57cec5SDimitry Andric 1408*0b57cec5SDimitry Andrictemplate<typename _Tp> struct __cxx_is_always_lock_free { 1409*0b57cec5SDimitry Andric enum { __value = __atomic_always_lock_free(sizeof(_Tp), 0) }; }; 1410*0b57cec5SDimitry Andric 1411*0b57cec5SDimitry Andric#else 1412*0b57cec5SDimitry Andric 1413*0b57cec5SDimitry Andrictemplate<typename _Tp> struct __cxx_is_always_lock_free { enum { __value = false }; }; 1414*0b57cec5SDimitry Andric// Implementations must match the C ATOMIC_*_LOCK_FREE macro values. 1415*0b57cec5SDimitry Andrictemplate<> struct __cxx_is_always_lock_free<bool> { enum { __value = 2 == ATOMIC_BOOL_LOCK_FREE }; }; 1416*0b57cec5SDimitry Andrictemplate<> struct __cxx_is_always_lock_free<char> { enum { __value = 2 == ATOMIC_CHAR_LOCK_FREE }; }; 1417*0b57cec5SDimitry Andrictemplate<> struct __cxx_is_always_lock_free<signed char> { enum { __value = 2 == ATOMIC_CHAR_LOCK_FREE }; }; 1418*0b57cec5SDimitry Andrictemplate<> struct __cxx_is_always_lock_free<unsigned char> { enum { __value = 2 == ATOMIC_CHAR_LOCK_FREE }; }; 1419*0b57cec5SDimitry Andrictemplate<> struct __cxx_is_always_lock_free<char16_t> { enum { __value = 2 == ATOMIC_CHAR16_T_LOCK_FREE }; }; 1420*0b57cec5SDimitry Andrictemplate<> struct __cxx_is_always_lock_free<char32_t> { enum { __value = 2 == ATOMIC_CHAR32_T_LOCK_FREE }; }; 1421*0b57cec5SDimitry Andrictemplate<> struct __cxx_is_always_lock_free<wchar_t> { enum { __value = 2 == ATOMIC_WCHAR_T_LOCK_FREE }; }; 1422*0b57cec5SDimitry Andrictemplate<> struct __cxx_is_always_lock_free<short> { enum { __value = 2 == ATOMIC_SHORT_LOCK_FREE }; }; 1423*0b57cec5SDimitry Andrictemplate<> struct __cxx_is_always_lock_free<unsigned short> { enum { __value = 2 == ATOMIC_SHORT_LOCK_FREE }; }; 1424*0b57cec5SDimitry Andrictemplate<> struct __cxx_is_always_lock_free<int> { enum { __value = 2 == ATOMIC_INT_LOCK_FREE }; }; 1425*0b57cec5SDimitry Andrictemplate<> struct __cxx_is_always_lock_free<unsigned int> { enum { __value = 2 == ATOMIC_INT_LOCK_FREE }; }; 1426*0b57cec5SDimitry Andrictemplate<> struct __cxx_is_always_lock_free<long> { enum { __value = 2 == ATOMIC_LONG_LOCK_FREE }; }; 1427*0b57cec5SDimitry Andrictemplate<> struct __cxx_is_always_lock_free<unsigned long> { enum { __value = 2 == ATOMIC_LONG_LOCK_FREE }; }; 1428*0b57cec5SDimitry Andrictemplate<> struct __cxx_is_always_lock_free<long long> { enum { __value = 2 == ATOMIC_LLONG_LOCK_FREE }; }; 1429*0b57cec5SDimitry Andrictemplate<> struct __cxx_is_always_lock_free<unsigned long long> { enum { __value = 2 == ATOMIC_LLONG_LOCK_FREE }; }; 1430*0b57cec5SDimitry Andrictemplate<typename _Tp> struct __cxx_is_always_lock_free<_Tp*> { enum { __value = 2 == ATOMIC_POINTER_LOCK_FREE }; }; 1431*0b57cec5SDimitry Andrictemplate<> struct __cxx_is_always_lock_free<std::nullptr_t> { enum { __value = 2 == ATOMIC_POINTER_LOCK_FREE }; }; 1432*0b57cec5SDimitry Andric 1433*0b57cec5SDimitry Andric#endif //__cpp_lib_atomic_is_always_lock_free 1434*0b57cec5SDimitry Andric 1435*0b57cec5SDimitry Andrictemplate <typename _Tp, 1436*0b57cec5SDimitry Andric typename _Base = typename conditional<__cxx_is_always_lock_free<_Tp>::__value, 1437*0b57cec5SDimitry Andric __cxx_atomic_base_impl<_Tp>, 1438*0b57cec5SDimitry Andric __cxx_atomic_lock_impl<_Tp> >::type> 1439*0b57cec5SDimitry Andric#else 1440*0b57cec5SDimitry Andrictemplate <typename _Tp, 1441*0b57cec5SDimitry Andric typename _Base = __cxx_atomic_base_impl<_Tp> > 1442*0b57cec5SDimitry Andric#endif //_LIBCPP_ATOMIC_ONLY_USE_BUILTINS 1443*0b57cec5SDimitry Andricstruct __cxx_atomic_impl : public _Base { 1444*0b57cec5SDimitry Andric 1445*0b57cec5SDimitry Andric#if _GNUC_VER >= 501 1446*0b57cec5SDimitry Andric static_assert(is_trivially_copyable<_Tp>::value, 1447*0b57cec5SDimitry Andric "std::atomic<Tp> requires that 'Tp' be a trivially copyable type"); 1448*0b57cec5SDimitry Andric#endif 1449*0b57cec5SDimitry Andric 1450*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY __cxx_atomic_impl() _NOEXCEPT _LIBCPP_DEFAULT 1451*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR explicit __cxx_atomic_impl(_Tp value) _NOEXCEPT 1452*0b57cec5SDimitry Andric : _Base(value) {} 1453*0b57cec5SDimitry Andric}; 1454*0b57cec5SDimitry Andric 1455*0b57cec5SDimitry Andric// general atomic<T> 1456*0b57cec5SDimitry Andric 1457*0b57cec5SDimitry Andrictemplate <class _Tp, bool = is_integral<_Tp>::value && !is_same<_Tp, bool>::value> 1458*0b57cec5SDimitry Andricstruct __atomic_base // false 1459*0b57cec5SDimitry Andric{ 1460*0b57cec5SDimitry Andric mutable __cxx_atomic_impl<_Tp> __a_; 1461*0b57cec5SDimitry Andric 1462*0b57cec5SDimitry Andric#if defined(__cpp_lib_atomic_is_always_lock_free) 1463*0b57cec5SDimitry Andric static _LIBCPP_CONSTEXPR bool is_always_lock_free = __atomic_always_lock_free(sizeof(__a_), 0); 1464*0b57cec5SDimitry Andric#endif 1465*0b57cec5SDimitry Andric 1466*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1467*0b57cec5SDimitry Andric bool is_lock_free() const volatile _NOEXCEPT 1468*0b57cec5SDimitry Andric {return __cxx_atomic_is_lock_free(sizeof(_Tp));} 1469*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1470*0b57cec5SDimitry Andric bool is_lock_free() const _NOEXCEPT 1471*0b57cec5SDimitry Andric {return static_cast<__atomic_base const volatile*>(this)->is_lock_free();} 1472*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1473*0b57cec5SDimitry Andric void store(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT 1474*0b57cec5SDimitry Andric _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) 1475*0b57cec5SDimitry Andric {__cxx_atomic_store(&__a_, __d, __m);} 1476*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1477*0b57cec5SDimitry Andric void store(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT 1478*0b57cec5SDimitry Andric _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) 1479*0b57cec5SDimitry Andric {__cxx_atomic_store(&__a_, __d, __m);} 1480*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1481*0b57cec5SDimitry Andric _Tp load(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT 1482*0b57cec5SDimitry Andric _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) 1483*0b57cec5SDimitry Andric {return __cxx_atomic_load(&__a_, __m);} 1484*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1485*0b57cec5SDimitry Andric _Tp load(memory_order __m = memory_order_seq_cst) const _NOEXCEPT 1486*0b57cec5SDimitry Andric _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) 1487*0b57cec5SDimitry Andric {return __cxx_atomic_load(&__a_, __m);} 1488*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1489*0b57cec5SDimitry Andric operator _Tp() const volatile _NOEXCEPT {return load();} 1490*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1491*0b57cec5SDimitry Andric operator _Tp() const _NOEXCEPT {return load();} 1492*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1493*0b57cec5SDimitry Andric _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT 1494*0b57cec5SDimitry Andric {return __cxx_atomic_exchange(&__a_, __d, __m);} 1495*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1496*0b57cec5SDimitry Andric _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT 1497*0b57cec5SDimitry Andric {return __cxx_atomic_exchange(&__a_, __d, __m);} 1498*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1499*0b57cec5SDimitry Andric bool compare_exchange_weak(_Tp& __e, _Tp __d, 1500*0b57cec5SDimitry Andric memory_order __s, memory_order __f) volatile _NOEXCEPT 1501*0b57cec5SDimitry Andric _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) 1502*0b57cec5SDimitry Andric {return __cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);} 1503*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1504*0b57cec5SDimitry Andric bool compare_exchange_weak(_Tp& __e, _Tp __d, 1505*0b57cec5SDimitry Andric memory_order __s, memory_order __f) _NOEXCEPT 1506*0b57cec5SDimitry Andric _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) 1507*0b57cec5SDimitry Andric {return __cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);} 1508*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1509*0b57cec5SDimitry Andric bool compare_exchange_strong(_Tp& __e, _Tp __d, 1510*0b57cec5SDimitry Andric memory_order __s, memory_order __f) volatile _NOEXCEPT 1511*0b57cec5SDimitry Andric _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) 1512*0b57cec5SDimitry Andric {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);} 1513*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1514*0b57cec5SDimitry Andric bool compare_exchange_strong(_Tp& __e, _Tp __d, 1515*0b57cec5SDimitry Andric memory_order __s, memory_order __f) _NOEXCEPT 1516*0b57cec5SDimitry Andric _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) 1517*0b57cec5SDimitry Andric {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);} 1518*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1519*0b57cec5SDimitry Andric bool compare_exchange_weak(_Tp& __e, _Tp __d, 1520*0b57cec5SDimitry Andric memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT 1521*0b57cec5SDimitry Andric {return __cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);} 1522*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1523*0b57cec5SDimitry Andric bool compare_exchange_weak(_Tp& __e, _Tp __d, 1524*0b57cec5SDimitry Andric memory_order __m = memory_order_seq_cst) _NOEXCEPT 1525*0b57cec5SDimitry Andric {return __cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);} 1526*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1527*0b57cec5SDimitry Andric bool compare_exchange_strong(_Tp& __e, _Tp __d, 1528*0b57cec5SDimitry Andric memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT 1529*0b57cec5SDimitry Andric {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);} 1530*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1531*0b57cec5SDimitry Andric bool compare_exchange_strong(_Tp& __e, _Tp __d, 1532*0b57cec5SDimitry Andric memory_order __m = memory_order_seq_cst) _NOEXCEPT 1533*0b57cec5SDimitry Andric {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);} 1534*0b57cec5SDimitry Andric 1535*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1536*0b57cec5SDimitry Andric __atomic_base() _NOEXCEPT _LIBCPP_DEFAULT 1537*0b57cec5SDimitry Andric 1538*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 1539*0b57cec5SDimitry Andric __atomic_base(_Tp __d) _NOEXCEPT : __a_(__d) {} 1540*0b57cec5SDimitry Andric 1541*0b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 1542*0b57cec5SDimitry Andric __atomic_base(const __atomic_base&) = delete; 1543*0b57cec5SDimitry Andric __atomic_base& operator=(const __atomic_base&) = delete; 1544*0b57cec5SDimitry Andric __atomic_base& operator=(const __atomic_base&) volatile = delete; 1545*0b57cec5SDimitry Andric#else 1546*0b57cec5SDimitry Andricprivate: 1547*0b57cec5SDimitry Andric __atomic_base(const __atomic_base&); 1548*0b57cec5SDimitry Andric __atomic_base& operator=(const __atomic_base&); 1549*0b57cec5SDimitry Andric __atomic_base& operator=(const __atomic_base&) volatile; 1550*0b57cec5SDimitry Andric#endif 1551*0b57cec5SDimitry Andric}; 1552*0b57cec5SDimitry Andric 1553*0b57cec5SDimitry Andric#if defined(__cpp_lib_atomic_is_always_lock_free) 1554*0b57cec5SDimitry Andrictemplate <class _Tp, bool __b> 1555*0b57cec5SDimitry Andric_LIBCPP_CONSTEXPR bool __atomic_base<_Tp, __b>::is_always_lock_free; 1556*0b57cec5SDimitry Andric#endif 1557*0b57cec5SDimitry Andric 1558*0b57cec5SDimitry Andric// atomic<Integral> 1559*0b57cec5SDimitry Andric 1560*0b57cec5SDimitry Andrictemplate <class _Tp> 1561*0b57cec5SDimitry Andricstruct __atomic_base<_Tp, true> 1562*0b57cec5SDimitry Andric : public __atomic_base<_Tp, false> 1563*0b57cec5SDimitry Andric{ 1564*0b57cec5SDimitry Andric typedef __atomic_base<_Tp, false> __base; 1565*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1566*0b57cec5SDimitry Andric __atomic_base() _NOEXCEPT _LIBCPP_DEFAULT 1567*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1568*0b57cec5SDimitry Andric _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __base(__d) {} 1569*0b57cec5SDimitry Andric 1570*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1571*0b57cec5SDimitry Andric _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT 1572*0b57cec5SDimitry Andric {return __cxx_atomic_fetch_add(&this->__a_, __op, __m);} 1573*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1574*0b57cec5SDimitry Andric _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT 1575*0b57cec5SDimitry Andric {return __cxx_atomic_fetch_add(&this->__a_, __op, __m);} 1576*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1577*0b57cec5SDimitry Andric _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT 1578*0b57cec5SDimitry Andric {return __cxx_atomic_fetch_sub(&this->__a_, __op, __m);} 1579*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1580*0b57cec5SDimitry Andric _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT 1581*0b57cec5SDimitry Andric {return __cxx_atomic_fetch_sub(&this->__a_, __op, __m);} 1582*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1583*0b57cec5SDimitry Andric _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT 1584*0b57cec5SDimitry Andric {return __cxx_atomic_fetch_and(&this->__a_, __op, __m);} 1585*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1586*0b57cec5SDimitry Andric _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT 1587*0b57cec5SDimitry Andric {return __cxx_atomic_fetch_and(&this->__a_, __op, __m);} 1588*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1589*0b57cec5SDimitry Andric _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT 1590*0b57cec5SDimitry Andric {return __cxx_atomic_fetch_or(&this->__a_, __op, __m);} 1591*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1592*0b57cec5SDimitry Andric _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT 1593*0b57cec5SDimitry Andric {return __cxx_atomic_fetch_or(&this->__a_, __op, __m);} 1594*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1595*0b57cec5SDimitry Andric _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT 1596*0b57cec5SDimitry Andric {return __cxx_atomic_fetch_xor(&this->__a_, __op, __m);} 1597*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1598*0b57cec5SDimitry Andric _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT 1599*0b57cec5SDimitry Andric {return __cxx_atomic_fetch_xor(&this->__a_, __op, __m);} 1600*0b57cec5SDimitry Andric 1601*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1602*0b57cec5SDimitry Andric _Tp operator++(int) volatile _NOEXCEPT {return fetch_add(_Tp(1));} 1603*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1604*0b57cec5SDimitry Andric _Tp operator++(int) _NOEXCEPT {return fetch_add(_Tp(1));} 1605*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1606*0b57cec5SDimitry Andric _Tp operator--(int) volatile _NOEXCEPT {return fetch_sub(_Tp(1));} 1607*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1608*0b57cec5SDimitry Andric _Tp operator--(int) _NOEXCEPT {return fetch_sub(_Tp(1));} 1609*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1610*0b57cec5SDimitry Andric _Tp operator++() volatile _NOEXCEPT {return fetch_add(_Tp(1)) + _Tp(1);} 1611*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1612*0b57cec5SDimitry Andric _Tp operator++() _NOEXCEPT {return fetch_add(_Tp(1)) + _Tp(1);} 1613*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1614*0b57cec5SDimitry Andric _Tp operator--() volatile _NOEXCEPT {return fetch_sub(_Tp(1)) - _Tp(1);} 1615*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1616*0b57cec5SDimitry Andric _Tp operator--() _NOEXCEPT {return fetch_sub(_Tp(1)) - _Tp(1);} 1617*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1618*0b57cec5SDimitry Andric _Tp operator+=(_Tp __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;} 1619*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1620*0b57cec5SDimitry Andric _Tp operator+=(_Tp __op) _NOEXCEPT {return fetch_add(__op) + __op;} 1621*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1622*0b57cec5SDimitry Andric _Tp operator-=(_Tp __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;} 1623*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1624*0b57cec5SDimitry Andric _Tp operator-=(_Tp __op) _NOEXCEPT {return fetch_sub(__op) - __op;} 1625*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1626*0b57cec5SDimitry Andric _Tp operator&=(_Tp __op) volatile _NOEXCEPT {return fetch_and(__op) & __op;} 1627*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1628*0b57cec5SDimitry Andric _Tp operator&=(_Tp __op) _NOEXCEPT {return fetch_and(__op) & __op;} 1629*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1630*0b57cec5SDimitry Andric _Tp operator|=(_Tp __op) volatile _NOEXCEPT {return fetch_or(__op) | __op;} 1631*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1632*0b57cec5SDimitry Andric _Tp operator|=(_Tp __op) _NOEXCEPT {return fetch_or(__op) | __op;} 1633*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1634*0b57cec5SDimitry Andric _Tp operator^=(_Tp __op) volatile _NOEXCEPT {return fetch_xor(__op) ^ __op;} 1635*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1636*0b57cec5SDimitry Andric _Tp operator^=(_Tp __op) _NOEXCEPT {return fetch_xor(__op) ^ __op;} 1637*0b57cec5SDimitry Andric}; 1638*0b57cec5SDimitry Andric 1639*0b57cec5SDimitry Andric// atomic<T> 1640*0b57cec5SDimitry Andric 1641*0b57cec5SDimitry Andrictemplate <class _Tp> 1642*0b57cec5SDimitry Andricstruct atomic 1643*0b57cec5SDimitry Andric : public __atomic_base<_Tp> 1644*0b57cec5SDimitry Andric{ 1645*0b57cec5SDimitry Andric typedef __atomic_base<_Tp> __base; 1646*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1647*0b57cec5SDimitry Andric atomic() _NOEXCEPT _LIBCPP_DEFAULT 1648*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1649*0b57cec5SDimitry Andric _LIBCPP_CONSTEXPR atomic(_Tp __d) _NOEXCEPT : __base(__d) {} 1650*0b57cec5SDimitry Andric 1651*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1652*0b57cec5SDimitry Andric _Tp operator=(_Tp __d) volatile _NOEXCEPT 1653*0b57cec5SDimitry Andric {__base::store(__d); return __d;} 1654*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1655*0b57cec5SDimitry Andric _Tp operator=(_Tp __d) _NOEXCEPT 1656*0b57cec5SDimitry Andric {__base::store(__d); return __d;} 1657*0b57cec5SDimitry Andric}; 1658*0b57cec5SDimitry Andric 1659*0b57cec5SDimitry Andric// atomic<T*> 1660*0b57cec5SDimitry Andric 1661*0b57cec5SDimitry Andrictemplate <class _Tp> 1662*0b57cec5SDimitry Andricstruct atomic<_Tp*> 1663*0b57cec5SDimitry Andric : public __atomic_base<_Tp*> 1664*0b57cec5SDimitry Andric{ 1665*0b57cec5SDimitry Andric typedef __atomic_base<_Tp*> __base; 1666*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1667*0b57cec5SDimitry Andric atomic() _NOEXCEPT _LIBCPP_DEFAULT 1668*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1669*0b57cec5SDimitry Andric _LIBCPP_CONSTEXPR atomic(_Tp* __d) _NOEXCEPT : __base(__d) {} 1670*0b57cec5SDimitry Andric 1671*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1672*0b57cec5SDimitry Andric _Tp* operator=(_Tp* __d) volatile _NOEXCEPT 1673*0b57cec5SDimitry Andric {__base::store(__d); return __d;} 1674*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1675*0b57cec5SDimitry Andric _Tp* operator=(_Tp* __d) _NOEXCEPT 1676*0b57cec5SDimitry Andric {__base::store(__d); return __d;} 1677*0b57cec5SDimitry Andric 1678*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1679*0b57cec5SDimitry Andric _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) 1680*0b57cec5SDimitry Andric volatile _NOEXCEPT 1681*0b57cec5SDimitry Andric {return __cxx_atomic_fetch_add(&this->__a_, __op, __m);} 1682*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1683*0b57cec5SDimitry Andric _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT 1684*0b57cec5SDimitry Andric {return __cxx_atomic_fetch_add(&this->__a_, __op, __m);} 1685*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1686*0b57cec5SDimitry Andric _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) 1687*0b57cec5SDimitry Andric volatile _NOEXCEPT 1688*0b57cec5SDimitry Andric {return __cxx_atomic_fetch_sub(&this->__a_, __op, __m);} 1689*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1690*0b57cec5SDimitry Andric _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT 1691*0b57cec5SDimitry Andric {return __cxx_atomic_fetch_sub(&this->__a_, __op, __m);} 1692*0b57cec5SDimitry Andric 1693*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1694*0b57cec5SDimitry Andric _Tp* operator++(int) volatile _NOEXCEPT {return fetch_add(1);} 1695*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1696*0b57cec5SDimitry Andric _Tp* operator++(int) _NOEXCEPT {return fetch_add(1);} 1697*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1698*0b57cec5SDimitry Andric _Tp* operator--(int) volatile _NOEXCEPT {return fetch_sub(1);} 1699*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1700*0b57cec5SDimitry Andric _Tp* operator--(int) _NOEXCEPT {return fetch_sub(1);} 1701*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1702*0b57cec5SDimitry Andric _Tp* operator++() volatile _NOEXCEPT {return fetch_add(1) + 1;} 1703*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1704*0b57cec5SDimitry Andric _Tp* operator++() _NOEXCEPT {return fetch_add(1) + 1;} 1705*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1706*0b57cec5SDimitry Andric _Tp* operator--() volatile _NOEXCEPT {return fetch_sub(1) - 1;} 1707*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1708*0b57cec5SDimitry Andric _Tp* operator--() _NOEXCEPT {return fetch_sub(1) - 1;} 1709*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1710*0b57cec5SDimitry Andric _Tp* operator+=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;} 1711*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1712*0b57cec5SDimitry Andric _Tp* operator+=(ptrdiff_t __op) _NOEXCEPT {return fetch_add(__op) + __op;} 1713*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1714*0b57cec5SDimitry Andric _Tp* operator-=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;} 1715*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1716*0b57cec5SDimitry Andric _Tp* operator-=(ptrdiff_t __op) _NOEXCEPT {return fetch_sub(__op) - __op;} 1717*0b57cec5SDimitry Andric}; 1718*0b57cec5SDimitry Andric 1719*0b57cec5SDimitry Andric// atomic_is_lock_free 1720*0b57cec5SDimitry Andric 1721*0b57cec5SDimitry Andrictemplate <class _Tp> 1722*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 1723*0b57cec5SDimitry Andricbool 1724*0b57cec5SDimitry Andricatomic_is_lock_free(const volatile atomic<_Tp>* __o) _NOEXCEPT 1725*0b57cec5SDimitry Andric{ 1726*0b57cec5SDimitry Andric return __o->is_lock_free(); 1727*0b57cec5SDimitry Andric} 1728*0b57cec5SDimitry Andric 1729*0b57cec5SDimitry Andrictemplate <class _Tp> 1730*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 1731*0b57cec5SDimitry Andricbool 1732*0b57cec5SDimitry Andricatomic_is_lock_free(const atomic<_Tp>* __o) _NOEXCEPT 1733*0b57cec5SDimitry Andric{ 1734*0b57cec5SDimitry Andric return __o->is_lock_free(); 1735*0b57cec5SDimitry Andric} 1736*0b57cec5SDimitry Andric 1737*0b57cec5SDimitry Andric// atomic_init 1738*0b57cec5SDimitry Andric 1739*0b57cec5SDimitry Andrictemplate <class _Tp> 1740*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 1741*0b57cec5SDimitry Andricvoid 1742*0b57cec5SDimitry Andricatomic_init(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT 1743*0b57cec5SDimitry Andric{ 1744*0b57cec5SDimitry Andric __cxx_atomic_init(&__o->__a_, __d); 1745*0b57cec5SDimitry Andric} 1746*0b57cec5SDimitry Andric 1747*0b57cec5SDimitry Andrictemplate <class _Tp> 1748*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 1749*0b57cec5SDimitry Andricvoid 1750*0b57cec5SDimitry Andricatomic_init(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT 1751*0b57cec5SDimitry Andric{ 1752*0b57cec5SDimitry Andric __cxx_atomic_init(&__o->__a_, __d); 1753*0b57cec5SDimitry Andric} 1754*0b57cec5SDimitry Andric 1755*0b57cec5SDimitry Andric// atomic_store 1756*0b57cec5SDimitry Andric 1757*0b57cec5SDimitry Andrictemplate <class _Tp> 1758*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 1759*0b57cec5SDimitry Andricvoid 1760*0b57cec5SDimitry Andricatomic_store(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT 1761*0b57cec5SDimitry Andric{ 1762*0b57cec5SDimitry Andric __o->store(__d); 1763*0b57cec5SDimitry Andric} 1764*0b57cec5SDimitry Andric 1765*0b57cec5SDimitry Andrictemplate <class _Tp> 1766*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 1767*0b57cec5SDimitry Andricvoid 1768*0b57cec5SDimitry Andricatomic_store(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT 1769*0b57cec5SDimitry Andric{ 1770*0b57cec5SDimitry Andric __o->store(__d); 1771*0b57cec5SDimitry Andric} 1772*0b57cec5SDimitry Andric 1773*0b57cec5SDimitry Andric// atomic_store_explicit 1774*0b57cec5SDimitry Andric 1775*0b57cec5SDimitry Andrictemplate <class _Tp> 1776*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 1777*0b57cec5SDimitry Andricvoid 1778*0b57cec5SDimitry Andricatomic_store_explicit(volatile atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT 1779*0b57cec5SDimitry Andric _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) 1780*0b57cec5SDimitry Andric{ 1781*0b57cec5SDimitry Andric __o->store(__d, __m); 1782*0b57cec5SDimitry Andric} 1783*0b57cec5SDimitry Andric 1784*0b57cec5SDimitry Andrictemplate <class _Tp> 1785*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 1786*0b57cec5SDimitry Andricvoid 1787*0b57cec5SDimitry Andricatomic_store_explicit(atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT 1788*0b57cec5SDimitry Andric _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) 1789*0b57cec5SDimitry Andric{ 1790*0b57cec5SDimitry Andric __o->store(__d, __m); 1791*0b57cec5SDimitry Andric} 1792*0b57cec5SDimitry Andric 1793*0b57cec5SDimitry Andric// atomic_load 1794*0b57cec5SDimitry Andric 1795*0b57cec5SDimitry Andrictemplate <class _Tp> 1796*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 1797*0b57cec5SDimitry Andric_Tp 1798*0b57cec5SDimitry Andricatomic_load(const volatile atomic<_Tp>* __o) _NOEXCEPT 1799*0b57cec5SDimitry Andric{ 1800*0b57cec5SDimitry Andric return __o->load(); 1801*0b57cec5SDimitry Andric} 1802*0b57cec5SDimitry Andric 1803*0b57cec5SDimitry Andrictemplate <class _Tp> 1804*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 1805*0b57cec5SDimitry Andric_Tp 1806*0b57cec5SDimitry Andricatomic_load(const atomic<_Tp>* __o) _NOEXCEPT 1807*0b57cec5SDimitry Andric{ 1808*0b57cec5SDimitry Andric return __o->load(); 1809*0b57cec5SDimitry Andric} 1810*0b57cec5SDimitry Andric 1811*0b57cec5SDimitry Andric// atomic_load_explicit 1812*0b57cec5SDimitry Andric 1813*0b57cec5SDimitry Andrictemplate <class _Tp> 1814*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 1815*0b57cec5SDimitry Andric_Tp 1816*0b57cec5SDimitry Andricatomic_load_explicit(const volatile atomic<_Tp>* __o, memory_order __m) _NOEXCEPT 1817*0b57cec5SDimitry Andric _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) 1818*0b57cec5SDimitry Andric{ 1819*0b57cec5SDimitry Andric return __o->load(__m); 1820*0b57cec5SDimitry Andric} 1821*0b57cec5SDimitry Andric 1822*0b57cec5SDimitry Andrictemplate <class _Tp> 1823*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 1824*0b57cec5SDimitry Andric_Tp 1825*0b57cec5SDimitry Andricatomic_load_explicit(const atomic<_Tp>* __o, memory_order __m) _NOEXCEPT 1826*0b57cec5SDimitry Andric _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) 1827*0b57cec5SDimitry Andric{ 1828*0b57cec5SDimitry Andric return __o->load(__m); 1829*0b57cec5SDimitry Andric} 1830*0b57cec5SDimitry Andric 1831*0b57cec5SDimitry Andric// atomic_exchange 1832*0b57cec5SDimitry Andric 1833*0b57cec5SDimitry Andrictemplate <class _Tp> 1834*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 1835*0b57cec5SDimitry Andric_Tp 1836*0b57cec5SDimitry Andricatomic_exchange(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT 1837*0b57cec5SDimitry Andric{ 1838*0b57cec5SDimitry Andric return __o->exchange(__d); 1839*0b57cec5SDimitry Andric} 1840*0b57cec5SDimitry Andric 1841*0b57cec5SDimitry Andrictemplate <class _Tp> 1842*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 1843*0b57cec5SDimitry Andric_Tp 1844*0b57cec5SDimitry Andricatomic_exchange(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT 1845*0b57cec5SDimitry Andric{ 1846*0b57cec5SDimitry Andric return __o->exchange(__d); 1847*0b57cec5SDimitry Andric} 1848*0b57cec5SDimitry Andric 1849*0b57cec5SDimitry Andric// atomic_exchange_explicit 1850*0b57cec5SDimitry Andric 1851*0b57cec5SDimitry Andrictemplate <class _Tp> 1852*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 1853*0b57cec5SDimitry Andric_Tp 1854*0b57cec5SDimitry Andricatomic_exchange_explicit(volatile atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT 1855*0b57cec5SDimitry Andric{ 1856*0b57cec5SDimitry Andric return __o->exchange(__d, __m); 1857*0b57cec5SDimitry Andric} 1858*0b57cec5SDimitry Andric 1859*0b57cec5SDimitry Andrictemplate <class _Tp> 1860*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 1861*0b57cec5SDimitry Andric_Tp 1862*0b57cec5SDimitry Andricatomic_exchange_explicit(atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT 1863*0b57cec5SDimitry Andric{ 1864*0b57cec5SDimitry Andric return __o->exchange(__d, __m); 1865*0b57cec5SDimitry Andric} 1866*0b57cec5SDimitry Andric 1867*0b57cec5SDimitry Andric// atomic_compare_exchange_weak 1868*0b57cec5SDimitry Andric 1869*0b57cec5SDimitry Andrictemplate <class _Tp> 1870*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 1871*0b57cec5SDimitry Andricbool 1872*0b57cec5SDimitry Andricatomic_compare_exchange_weak(volatile atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT 1873*0b57cec5SDimitry Andric{ 1874*0b57cec5SDimitry Andric return __o->compare_exchange_weak(*__e, __d); 1875*0b57cec5SDimitry Andric} 1876*0b57cec5SDimitry Andric 1877*0b57cec5SDimitry Andrictemplate <class _Tp> 1878*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 1879*0b57cec5SDimitry Andricbool 1880*0b57cec5SDimitry Andricatomic_compare_exchange_weak(atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT 1881*0b57cec5SDimitry Andric{ 1882*0b57cec5SDimitry Andric return __o->compare_exchange_weak(*__e, __d); 1883*0b57cec5SDimitry Andric} 1884*0b57cec5SDimitry Andric 1885*0b57cec5SDimitry Andric// atomic_compare_exchange_strong 1886*0b57cec5SDimitry Andric 1887*0b57cec5SDimitry Andrictemplate <class _Tp> 1888*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 1889*0b57cec5SDimitry Andricbool 1890*0b57cec5SDimitry Andricatomic_compare_exchange_strong(volatile atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT 1891*0b57cec5SDimitry Andric{ 1892*0b57cec5SDimitry Andric return __o->compare_exchange_strong(*__e, __d); 1893*0b57cec5SDimitry Andric} 1894*0b57cec5SDimitry Andric 1895*0b57cec5SDimitry Andrictemplate <class _Tp> 1896*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 1897*0b57cec5SDimitry Andricbool 1898*0b57cec5SDimitry Andricatomic_compare_exchange_strong(atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT 1899*0b57cec5SDimitry Andric{ 1900*0b57cec5SDimitry Andric return __o->compare_exchange_strong(*__e, __d); 1901*0b57cec5SDimitry Andric} 1902*0b57cec5SDimitry Andric 1903*0b57cec5SDimitry Andric// atomic_compare_exchange_weak_explicit 1904*0b57cec5SDimitry Andric 1905*0b57cec5SDimitry Andrictemplate <class _Tp> 1906*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 1907*0b57cec5SDimitry Andricbool 1908*0b57cec5SDimitry Andricatomic_compare_exchange_weak_explicit(volatile atomic<_Tp>* __o, _Tp* __e, 1909*0b57cec5SDimitry Andric _Tp __d, 1910*0b57cec5SDimitry Andric memory_order __s, memory_order __f) _NOEXCEPT 1911*0b57cec5SDimitry Andric _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) 1912*0b57cec5SDimitry Andric{ 1913*0b57cec5SDimitry Andric return __o->compare_exchange_weak(*__e, __d, __s, __f); 1914*0b57cec5SDimitry Andric} 1915*0b57cec5SDimitry Andric 1916*0b57cec5SDimitry Andrictemplate <class _Tp> 1917*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 1918*0b57cec5SDimitry Andricbool 1919*0b57cec5SDimitry Andricatomic_compare_exchange_weak_explicit(atomic<_Tp>* __o, _Tp* __e, _Tp __d, 1920*0b57cec5SDimitry Andric memory_order __s, memory_order __f) _NOEXCEPT 1921*0b57cec5SDimitry Andric _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) 1922*0b57cec5SDimitry Andric{ 1923*0b57cec5SDimitry Andric return __o->compare_exchange_weak(*__e, __d, __s, __f); 1924*0b57cec5SDimitry Andric} 1925*0b57cec5SDimitry Andric 1926*0b57cec5SDimitry Andric// atomic_compare_exchange_strong_explicit 1927*0b57cec5SDimitry Andric 1928*0b57cec5SDimitry Andrictemplate <class _Tp> 1929*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 1930*0b57cec5SDimitry Andricbool 1931*0b57cec5SDimitry Andricatomic_compare_exchange_strong_explicit(volatile atomic<_Tp>* __o, 1932*0b57cec5SDimitry Andric _Tp* __e, _Tp __d, 1933*0b57cec5SDimitry Andric memory_order __s, memory_order __f) _NOEXCEPT 1934*0b57cec5SDimitry Andric _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) 1935*0b57cec5SDimitry Andric{ 1936*0b57cec5SDimitry Andric return __o->compare_exchange_strong(*__e, __d, __s, __f); 1937*0b57cec5SDimitry Andric} 1938*0b57cec5SDimitry Andric 1939*0b57cec5SDimitry Andrictemplate <class _Tp> 1940*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 1941*0b57cec5SDimitry Andricbool 1942*0b57cec5SDimitry Andricatomic_compare_exchange_strong_explicit(atomic<_Tp>* __o, _Tp* __e, 1943*0b57cec5SDimitry Andric _Tp __d, 1944*0b57cec5SDimitry Andric memory_order __s, memory_order __f) _NOEXCEPT 1945*0b57cec5SDimitry Andric _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) 1946*0b57cec5SDimitry Andric{ 1947*0b57cec5SDimitry Andric return __o->compare_exchange_strong(*__e, __d, __s, __f); 1948*0b57cec5SDimitry Andric} 1949*0b57cec5SDimitry Andric 1950*0b57cec5SDimitry Andric// atomic_fetch_add 1951*0b57cec5SDimitry Andric 1952*0b57cec5SDimitry Andrictemplate <class _Tp> 1953*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 1954*0b57cec5SDimitry Andrictypename enable_if 1955*0b57cec5SDimitry Andric< 1956*0b57cec5SDimitry Andric is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1957*0b57cec5SDimitry Andric _Tp 1958*0b57cec5SDimitry Andric>::type 1959*0b57cec5SDimitry Andricatomic_fetch_add(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT 1960*0b57cec5SDimitry Andric{ 1961*0b57cec5SDimitry Andric return __o->fetch_add(__op); 1962*0b57cec5SDimitry Andric} 1963*0b57cec5SDimitry Andric 1964*0b57cec5SDimitry Andrictemplate <class _Tp> 1965*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 1966*0b57cec5SDimitry Andrictypename enable_if 1967*0b57cec5SDimitry Andric< 1968*0b57cec5SDimitry Andric is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1969*0b57cec5SDimitry Andric _Tp 1970*0b57cec5SDimitry Andric>::type 1971*0b57cec5SDimitry Andricatomic_fetch_add(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT 1972*0b57cec5SDimitry Andric{ 1973*0b57cec5SDimitry Andric return __o->fetch_add(__op); 1974*0b57cec5SDimitry Andric} 1975*0b57cec5SDimitry Andric 1976*0b57cec5SDimitry Andrictemplate <class _Tp> 1977*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 1978*0b57cec5SDimitry Andric_Tp* 1979*0b57cec5SDimitry Andricatomic_fetch_add(volatile atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT 1980*0b57cec5SDimitry Andric{ 1981*0b57cec5SDimitry Andric return __o->fetch_add(__op); 1982*0b57cec5SDimitry Andric} 1983*0b57cec5SDimitry Andric 1984*0b57cec5SDimitry Andrictemplate <class _Tp> 1985*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 1986*0b57cec5SDimitry Andric_Tp* 1987*0b57cec5SDimitry Andricatomic_fetch_add(atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT 1988*0b57cec5SDimitry Andric{ 1989*0b57cec5SDimitry Andric return __o->fetch_add(__op); 1990*0b57cec5SDimitry Andric} 1991*0b57cec5SDimitry Andric 1992*0b57cec5SDimitry Andric// atomic_fetch_add_explicit 1993*0b57cec5SDimitry Andric 1994*0b57cec5SDimitry Andrictemplate <class _Tp> 1995*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 1996*0b57cec5SDimitry Andrictypename enable_if 1997*0b57cec5SDimitry Andric< 1998*0b57cec5SDimitry Andric is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1999*0b57cec5SDimitry Andric _Tp 2000*0b57cec5SDimitry Andric>::type 2001*0b57cec5SDimitry Andricatomic_fetch_add_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT 2002*0b57cec5SDimitry Andric{ 2003*0b57cec5SDimitry Andric return __o->fetch_add(__op, __m); 2004*0b57cec5SDimitry Andric} 2005*0b57cec5SDimitry Andric 2006*0b57cec5SDimitry Andrictemplate <class _Tp> 2007*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 2008*0b57cec5SDimitry Andrictypename enable_if 2009*0b57cec5SDimitry Andric< 2010*0b57cec5SDimitry Andric is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 2011*0b57cec5SDimitry Andric _Tp 2012*0b57cec5SDimitry Andric>::type 2013*0b57cec5SDimitry Andricatomic_fetch_add_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT 2014*0b57cec5SDimitry Andric{ 2015*0b57cec5SDimitry Andric return __o->fetch_add(__op, __m); 2016*0b57cec5SDimitry Andric} 2017*0b57cec5SDimitry Andric 2018*0b57cec5SDimitry Andrictemplate <class _Tp> 2019*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 2020*0b57cec5SDimitry Andric_Tp* 2021*0b57cec5SDimitry Andricatomic_fetch_add_explicit(volatile atomic<_Tp*>* __o, ptrdiff_t __op, 2022*0b57cec5SDimitry Andric memory_order __m) _NOEXCEPT 2023*0b57cec5SDimitry Andric{ 2024*0b57cec5SDimitry Andric return __o->fetch_add(__op, __m); 2025*0b57cec5SDimitry Andric} 2026*0b57cec5SDimitry Andric 2027*0b57cec5SDimitry Andrictemplate <class _Tp> 2028*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 2029*0b57cec5SDimitry Andric_Tp* 2030*0b57cec5SDimitry Andricatomic_fetch_add_explicit(atomic<_Tp*>* __o, ptrdiff_t __op, memory_order __m) _NOEXCEPT 2031*0b57cec5SDimitry Andric{ 2032*0b57cec5SDimitry Andric return __o->fetch_add(__op, __m); 2033*0b57cec5SDimitry Andric} 2034*0b57cec5SDimitry Andric 2035*0b57cec5SDimitry Andric// atomic_fetch_sub 2036*0b57cec5SDimitry Andric 2037*0b57cec5SDimitry Andrictemplate <class _Tp> 2038*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 2039*0b57cec5SDimitry Andrictypename enable_if 2040*0b57cec5SDimitry Andric< 2041*0b57cec5SDimitry Andric is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 2042*0b57cec5SDimitry Andric _Tp 2043*0b57cec5SDimitry Andric>::type 2044*0b57cec5SDimitry Andricatomic_fetch_sub(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT 2045*0b57cec5SDimitry Andric{ 2046*0b57cec5SDimitry Andric return __o->fetch_sub(__op); 2047*0b57cec5SDimitry Andric} 2048*0b57cec5SDimitry Andric 2049*0b57cec5SDimitry Andrictemplate <class _Tp> 2050*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 2051*0b57cec5SDimitry Andrictypename enable_if 2052*0b57cec5SDimitry Andric< 2053*0b57cec5SDimitry Andric is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 2054*0b57cec5SDimitry Andric _Tp 2055*0b57cec5SDimitry Andric>::type 2056*0b57cec5SDimitry Andricatomic_fetch_sub(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT 2057*0b57cec5SDimitry Andric{ 2058*0b57cec5SDimitry Andric return __o->fetch_sub(__op); 2059*0b57cec5SDimitry Andric} 2060*0b57cec5SDimitry Andric 2061*0b57cec5SDimitry Andrictemplate <class _Tp> 2062*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 2063*0b57cec5SDimitry Andric_Tp* 2064*0b57cec5SDimitry Andricatomic_fetch_sub(volatile atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT 2065*0b57cec5SDimitry Andric{ 2066*0b57cec5SDimitry Andric return __o->fetch_sub(__op); 2067*0b57cec5SDimitry Andric} 2068*0b57cec5SDimitry Andric 2069*0b57cec5SDimitry Andrictemplate <class _Tp> 2070*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 2071*0b57cec5SDimitry Andric_Tp* 2072*0b57cec5SDimitry Andricatomic_fetch_sub(atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT 2073*0b57cec5SDimitry Andric{ 2074*0b57cec5SDimitry Andric return __o->fetch_sub(__op); 2075*0b57cec5SDimitry Andric} 2076*0b57cec5SDimitry Andric 2077*0b57cec5SDimitry Andric// atomic_fetch_sub_explicit 2078*0b57cec5SDimitry Andric 2079*0b57cec5SDimitry Andrictemplate <class _Tp> 2080*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 2081*0b57cec5SDimitry Andrictypename enable_if 2082*0b57cec5SDimitry Andric< 2083*0b57cec5SDimitry Andric is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 2084*0b57cec5SDimitry Andric _Tp 2085*0b57cec5SDimitry Andric>::type 2086*0b57cec5SDimitry Andricatomic_fetch_sub_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT 2087*0b57cec5SDimitry Andric{ 2088*0b57cec5SDimitry Andric return __o->fetch_sub(__op, __m); 2089*0b57cec5SDimitry Andric} 2090*0b57cec5SDimitry Andric 2091*0b57cec5SDimitry Andrictemplate <class _Tp> 2092*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 2093*0b57cec5SDimitry Andrictypename enable_if 2094*0b57cec5SDimitry Andric< 2095*0b57cec5SDimitry Andric is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 2096*0b57cec5SDimitry Andric _Tp 2097*0b57cec5SDimitry Andric>::type 2098*0b57cec5SDimitry Andricatomic_fetch_sub_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT 2099*0b57cec5SDimitry Andric{ 2100*0b57cec5SDimitry Andric return __o->fetch_sub(__op, __m); 2101*0b57cec5SDimitry Andric} 2102*0b57cec5SDimitry Andric 2103*0b57cec5SDimitry Andrictemplate <class _Tp> 2104*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 2105*0b57cec5SDimitry Andric_Tp* 2106*0b57cec5SDimitry Andricatomic_fetch_sub_explicit(volatile atomic<_Tp*>* __o, ptrdiff_t __op, 2107*0b57cec5SDimitry Andric memory_order __m) _NOEXCEPT 2108*0b57cec5SDimitry Andric{ 2109*0b57cec5SDimitry Andric return __o->fetch_sub(__op, __m); 2110*0b57cec5SDimitry Andric} 2111*0b57cec5SDimitry Andric 2112*0b57cec5SDimitry Andrictemplate <class _Tp> 2113*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 2114*0b57cec5SDimitry Andric_Tp* 2115*0b57cec5SDimitry Andricatomic_fetch_sub_explicit(atomic<_Tp*>* __o, ptrdiff_t __op, memory_order __m) _NOEXCEPT 2116*0b57cec5SDimitry Andric{ 2117*0b57cec5SDimitry Andric return __o->fetch_sub(__op, __m); 2118*0b57cec5SDimitry Andric} 2119*0b57cec5SDimitry Andric 2120*0b57cec5SDimitry Andric// atomic_fetch_and 2121*0b57cec5SDimitry Andric 2122*0b57cec5SDimitry Andrictemplate <class _Tp> 2123*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 2124*0b57cec5SDimitry Andrictypename enable_if 2125*0b57cec5SDimitry Andric< 2126*0b57cec5SDimitry Andric is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 2127*0b57cec5SDimitry Andric _Tp 2128*0b57cec5SDimitry Andric>::type 2129*0b57cec5SDimitry Andricatomic_fetch_and(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT 2130*0b57cec5SDimitry Andric{ 2131*0b57cec5SDimitry Andric return __o->fetch_and(__op); 2132*0b57cec5SDimitry Andric} 2133*0b57cec5SDimitry Andric 2134*0b57cec5SDimitry Andrictemplate <class _Tp> 2135*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 2136*0b57cec5SDimitry Andrictypename enable_if 2137*0b57cec5SDimitry Andric< 2138*0b57cec5SDimitry Andric is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 2139*0b57cec5SDimitry Andric _Tp 2140*0b57cec5SDimitry Andric>::type 2141*0b57cec5SDimitry Andricatomic_fetch_and(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT 2142*0b57cec5SDimitry Andric{ 2143*0b57cec5SDimitry Andric return __o->fetch_and(__op); 2144*0b57cec5SDimitry Andric} 2145*0b57cec5SDimitry Andric 2146*0b57cec5SDimitry Andric// atomic_fetch_and_explicit 2147*0b57cec5SDimitry Andric 2148*0b57cec5SDimitry Andrictemplate <class _Tp> 2149*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 2150*0b57cec5SDimitry Andrictypename enable_if 2151*0b57cec5SDimitry Andric< 2152*0b57cec5SDimitry Andric is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 2153*0b57cec5SDimitry Andric _Tp 2154*0b57cec5SDimitry Andric>::type 2155*0b57cec5SDimitry Andricatomic_fetch_and_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT 2156*0b57cec5SDimitry Andric{ 2157*0b57cec5SDimitry Andric return __o->fetch_and(__op, __m); 2158*0b57cec5SDimitry Andric} 2159*0b57cec5SDimitry Andric 2160*0b57cec5SDimitry Andrictemplate <class _Tp> 2161*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 2162*0b57cec5SDimitry Andrictypename enable_if 2163*0b57cec5SDimitry Andric< 2164*0b57cec5SDimitry Andric is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 2165*0b57cec5SDimitry Andric _Tp 2166*0b57cec5SDimitry Andric>::type 2167*0b57cec5SDimitry Andricatomic_fetch_and_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT 2168*0b57cec5SDimitry Andric{ 2169*0b57cec5SDimitry Andric return __o->fetch_and(__op, __m); 2170*0b57cec5SDimitry Andric} 2171*0b57cec5SDimitry Andric 2172*0b57cec5SDimitry Andric// atomic_fetch_or 2173*0b57cec5SDimitry Andric 2174*0b57cec5SDimitry Andrictemplate <class _Tp> 2175*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 2176*0b57cec5SDimitry Andrictypename enable_if 2177*0b57cec5SDimitry Andric< 2178*0b57cec5SDimitry Andric is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 2179*0b57cec5SDimitry Andric _Tp 2180*0b57cec5SDimitry Andric>::type 2181*0b57cec5SDimitry Andricatomic_fetch_or(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT 2182*0b57cec5SDimitry Andric{ 2183*0b57cec5SDimitry Andric return __o->fetch_or(__op); 2184*0b57cec5SDimitry Andric} 2185*0b57cec5SDimitry Andric 2186*0b57cec5SDimitry Andrictemplate <class _Tp> 2187*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 2188*0b57cec5SDimitry Andrictypename enable_if 2189*0b57cec5SDimitry Andric< 2190*0b57cec5SDimitry Andric is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 2191*0b57cec5SDimitry Andric _Tp 2192*0b57cec5SDimitry Andric>::type 2193*0b57cec5SDimitry Andricatomic_fetch_or(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT 2194*0b57cec5SDimitry Andric{ 2195*0b57cec5SDimitry Andric return __o->fetch_or(__op); 2196*0b57cec5SDimitry Andric} 2197*0b57cec5SDimitry Andric 2198*0b57cec5SDimitry Andric// atomic_fetch_or_explicit 2199*0b57cec5SDimitry Andric 2200*0b57cec5SDimitry Andrictemplate <class _Tp> 2201*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 2202*0b57cec5SDimitry Andrictypename enable_if 2203*0b57cec5SDimitry Andric< 2204*0b57cec5SDimitry Andric is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 2205*0b57cec5SDimitry Andric _Tp 2206*0b57cec5SDimitry Andric>::type 2207*0b57cec5SDimitry Andricatomic_fetch_or_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT 2208*0b57cec5SDimitry Andric{ 2209*0b57cec5SDimitry Andric return __o->fetch_or(__op, __m); 2210*0b57cec5SDimitry Andric} 2211*0b57cec5SDimitry Andric 2212*0b57cec5SDimitry Andrictemplate <class _Tp> 2213*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 2214*0b57cec5SDimitry Andrictypename enable_if 2215*0b57cec5SDimitry Andric< 2216*0b57cec5SDimitry Andric is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 2217*0b57cec5SDimitry Andric _Tp 2218*0b57cec5SDimitry Andric>::type 2219*0b57cec5SDimitry Andricatomic_fetch_or_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT 2220*0b57cec5SDimitry Andric{ 2221*0b57cec5SDimitry Andric return __o->fetch_or(__op, __m); 2222*0b57cec5SDimitry Andric} 2223*0b57cec5SDimitry Andric 2224*0b57cec5SDimitry Andric// atomic_fetch_xor 2225*0b57cec5SDimitry Andric 2226*0b57cec5SDimitry Andrictemplate <class _Tp> 2227*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 2228*0b57cec5SDimitry Andrictypename enable_if 2229*0b57cec5SDimitry Andric< 2230*0b57cec5SDimitry Andric is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 2231*0b57cec5SDimitry Andric _Tp 2232*0b57cec5SDimitry Andric>::type 2233*0b57cec5SDimitry Andricatomic_fetch_xor(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT 2234*0b57cec5SDimitry Andric{ 2235*0b57cec5SDimitry Andric return __o->fetch_xor(__op); 2236*0b57cec5SDimitry Andric} 2237*0b57cec5SDimitry Andric 2238*0b57cec5SDimitry Andrictemplate <class _Tp> 2239*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 2240*0b57cec5SDimitry Andrictypename enable_if 2241*0b57cec5SDimitry Andric< 2242*0b57cec5SDimitry Andric is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 2243*0b57cec5SDimitry Andric _Tp 2244*0b57cec5SDimitry Andric>::type 2245*0b57cec5SDimitry Andricatomic_fetch_xor(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT 2246*0b57cec5SDimitry Andric{ 2247*0b57cec5SDimitry Andric return __o->fetch_xor(__op); 2248*0b57cec5SDimitry Andric} 2249*0b57cec5SDimitry Andric 2250*0b57cec5SDimitry Andric// atomic_fetch_xor_explicit 2251*0b57cec5SDimitry Andric 2252*0b57cec5SDimitry Andrictemplate <class _Tp> 2253*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 2254*0b57cec5SDimitry Andrictypename enable_if 2255*0b57cec5SDimitry Andric< 2256*0b57cec5SDimitry Andric is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 2257*0b57cec5SDimitry Andric _Tp 2258*0b57cec5SDimitry Andric>::type 2259*0b57cec5SDimitry Andricatomic_fetch_xor_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT 2260*0b57cec5SDimitry Andric{ 2261*0b57cec5SDimitry Andric return __o->fetch_xor(__op, __m); 2262*0b57cec5SDimitry Andric} 2263*0b57cec5SDimitry Andric 2264*0b57cec5SDimitry Andrictemplate <class _Tp> 2265*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 2266*0b57cec5SDimitry Andrictypename enable_if 2267*0b57cec5SDimitry Andric< 2268*0b57cec5SDimitry Andric is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 2269*0b57cec5SDimitry Andric _Tp 2270*0b57cec5SDimitry Andric>::type 2271*0b57cec5SDimitry Andricatomic_fetch_xor_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT 2272*0b57cec5SDimitry Andric{ 2273*0b57cec5SDimitry Andric return __o->fetch_xor(__op, __m); 2274*0b57cec5SDimitry Andric} 2275*0b57cec5SDimitry Andric 2276*0b57cec5SDimitry Andric// flag type and operations 2277*0b57cec5SDimitry Andric 2278*0b57cec5SDimitry Andrictypedef struct atomic_flag 2279*0b57cec5SDimitry Andric{ 2280*0b57cec5SDimitry Andric __cxx_atomic_impl<_LIBCPP_ATOMIC_FLAG_TYPE> __a_; 2281*0b57cec5SDimitry Andric 2282*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2283*0b57cec5SDimitry Andric bool test_and_set(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT 2284*0b57cec5SDimitry Andric {return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);} 2285*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2286*0b57cec5SDimitry Andric bool test_and_set(memory_order __m = memory_order_seq_cst) _NOEXCEPT 2287*0b57cec5SDimitry Andric {return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);} 2288*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2289*0b57cec5SDimitry Andric void clear(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT 2290*0b57cec5SDimitry Andric {__cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);} 2291*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2292*0b57cec5SDimitry Andric void clear(memory_order __m = memory_order_seq_cst) _NOEXCEPT 2293*0b57cec5SDimitry Andric {__cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);} 2294*0b57cec5SDimitry Andric 2295*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2296*0b57cec5SDimitry Andric atomic_flag() _NOEXCEPT _LIBCPP_DEFAULT 2297*0b57cec5SDimitry Andric 2298*0b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 2299*0b57cec5SDimitry Andric atomic_flag(bool __b) _NOEXCEPT : __a_(__b) {} // EXTENSION 2300*0b57cec5SDimitry Andric 2301*0b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 2302*0b57cec5SDimitry Andric atomic_flag(const atomic_flag&) = delete; 2303*0b57cec5SDimitry Andric atomic_flag& operator=(const atomic_flag&) = delete; 2304*0b57cec5SDimitry Andric atomic_flag& operator=(const atomic_flag&) volatile = delete; 2305*0b57cec5SDimitry Andric#else 2306*0b57cec5SDimitry Andricprivate: 2307*0b57cec5SDimitry Andric atomic_flag(const atomic_flag&); 2308*0b57cec5SDimitry Andric atomic_flag& operator=(const atomic_flag&); 2309*0b57cec5SDimitry Andric atomic_flag& operator=(const atomic_flag&) volatile; 2310*0b57cec5SDimitry Andric#endif 2311*0b57cec5SDimitry Andric} atomic_flag; 2312*0b57cec5SDimitry Andric 2313*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 2314*0b57cec5SDimitry Andricbool 2315*0b57cec5SDimitry Andricatomic_flag_test_and_set(volatile atomic_flag* __o) _NOEXCEPT 2316*0b57cec5SDimitry Andric{ 2317*0b57cec5SDimitry Andric return __o->test_and_set(); 2318*0b57cec5SDimitry Andric} 2319*0b57cec5SDimitry Andric 2320*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 2321*0b57cec5SDimitry Andricbool 2322*0b57cec5SDimitry Andricatomic_flag_test_and_set(atomic_flag* __o) _NOEXCEPT 2323*0b57cec5SDimitry Andric{ 2324*0b57cec5SDimitry Andric return __o->test_and_set(); 2325*0b57cec5SDimitry Andric} 2326*0b57cec5SDimitry Andric 2327*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 2328*0b57cec5SDimitry Andricbool 2329*0b57cec5SDimitry Andricatomic_flag_test_and_set_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT 2330*0b57cec5SDimitry Andric{ 2331*0b57cec5SDimitry Andric return __o->test_and_set(__m); 2332*0b57cec5SDimitry Andric} 2333*0b57cec5SDimitry Andric 2334*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 2335*0b57cec5SDimitry Andricbool 2336*0b57cec5SDimitry Andricatomic_flag_test_and_set_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT 2337*0b57cec5SDimitry Andric{ 2338*0b57cec5SDimitry Andric return __o->test_and_set(__m); 2339*0b57cec5SDimitry Andric} 2340*0b57cec5SDimitry Andric 2341*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 2342*0b57cec5SDimitry Andricvoid 2343*0b57cec5SDimitry Andricatomic_flag_clear(volatile atomic_flag* __o) _NOEXCEPT 2344*0b57cec5SDimitry Andric{ 2345*0b57cec5SDimitry Andric __o->clear(); 2346*0b57cec5SDimitry Andric} 2347*0b57cec5SDimitry Andric 2348*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 2349*0b57cec5SDimitry Andricvoid 2350*0b57cec5SDimitry Andricatomic_flag_clear(atomic_flag* __o) _NOEXCEPT 2351*0b57cec5SDimitry Andric{ 2352*0b57cec5SDimitry Andric __o->clear(); 2353*0b57cec5SDimitry Andric} 2354*0b57cec5SDimitry Andric 2355*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 2356*0b57cec5SDimitry Andricvoid 2357*0b57cec5SDimitry Andricatomic_flag_clear_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT 2358*0b57cec5SDimitry Andric{ 2359*0b57cec5SDimitry Andric __o->clear(__m); 2360*0b57cec5SDimitry Andric} 2361*0b57cec5SDimitry Andric 2362*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 2363*0b57cec5SDimitry Andricvoid 2364*0b57cec5SDimitry Andricatomic_flag_clear_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT 2365*0b57cec5SDimitry Andric{ 2366*0b57cec5SDimitry Andric __o->clear(__m); 2367*0b57cec5SDimitry Andric} 2368*0b57cec5SDimitry Andric 2369*0b57cec5SDimitry Andric// fences 2370*0b57cec5SDimitry Andric 2371*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 2372*0b57cec5SDimitry Andricvoid 2373*0b57cec5SDimitry Andricatomic_thread_fence(memory_order __m) _NOEXCEPT 2374*0b57cec5SDimitry Andric{ 2375*0b57cec5SDimitry Andric __cxx_atomic_thread_fence(__m); 2376*0b57cec5SDimitry Andric} 2377*0b57cec5SDimitry Andric 2378*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 2379*0b57cec5SDimitry Andricvoid 2380*0b57cec5SDimitry Andricatomic_signal_fence(memory_order __m) _NOEXCEPT 2381*0b57cec5SDimitry Andric{ 2382*0b57cec5SDimitry Andric __cxx_atomic_signal_fence(__m); 2383*0b57cec5SDimitry Andric} 2384*0b57cec5SDimitry Andric 2385*0b57cec5SDimitry Andric// Atomics for standard typedef types 2386*0b57cec5SDimitry Andric 2387*0b57cec5SDimitry Andrictypedef atomic<bool> atomic_bool; 2388*0b57cec5SDimitry Andrictypedef atomic<char> atomic_char; 2389*0b57cec5SDimitry Andrictypedef atomic<signed char> atomic_schar; 2390*0b57cec5SDimitry Andrictypedef atomic<unsigned char> atomic_uchar; 2391*0b57cec5SDimitry Andrictypedef atomic<short> atomic_short; 2392*0b57cec5SDimitry Andrictypedef atomic<unsigned short> atomic_ushort; 2393*0b57cec5SDimitry Andrictypedef atomic<int> atomic_int; 2394*0b57cec5SDimitry Andrictypedef atomic<unsigned int> atomic_uint; 2395*0b57cec5SDimitry Andrictypedef atomic<long> atomic_long; 2396*0b57cec5SDimitry Andrictypedef atomic<unsigned long> atomic_ulong; 2397*0b57cec5SDimitry Andrictypedef atomic<long long> atomic_llong; 2398*0b57cec5SDimitry Andrictypedef atomic<unsigned long long> atomic_ullong; 2399*0b57cec5SDimitry Andrictypedef atomic<char16_t> atomic_char16_t; 2400*0b57cec5SDimitry Andrictypedef atomic<char32_t> atomic_char32_t; 2401*0b57cec5SDimitry Andrictypedef atomic<wchar_t> atomic_wchar_t; 2402*0b57cec5SDimitry Andric 2403*0b57cec5SDimitry Andrictypedef atomic<int_least8_t> atomic_int_least8_t; 2404*0b57cec5SDimitry Andrictypedef atomic<uint_least8_t> atomic_uint_least8_t; 2405*0b57cec5SDimitry Andrictypedef atomic<int_least16_t> atomic_int_least16_t; 2406*0b57cec5SDimitry Andrictypedef atomic<uint_least16_t> atomic_uint_least16_t; 2407*0b57cec5SDimitry Andrictypedef atomic<int_least32_t> atomic_int_least32_t; 2408*0b57cec5SDimitry Andrictypedef atomic<uint_least32_t> atomic_uint_least32_t; 2409*0b57cec5SDimitry Andrictypedef atomic<int_least64_t> atomic_int_least64_t; 2410*0b57cec5SDimitry Andrictypedef atomic<uint_least64_t> atomic_uint_least64_t; 2411*0b57cec5SDimitry Andric 2412*0b57cec5SDimitry Andrictypedef atomic<int_fast8_t> atomic_int_fast8_t; 2413*0b57cec5SDimitry Andrictypedef atomic<uint_fast8_t> atomic_uint_fast8_t; 2414*0b57cec5SDimitry Andrictypedef atomic<int_fast16_t> atomic_int_fast16_t; 2415*0b57cec5SDimitry Andrictypedef atomic<uint_fast16_t> atomic_uint_fast16_t; 2416*0b57cec5SDimitry Andrictypedef atomic<int_fast32_t> atomic_int_fast32_t; 2417*0b57cec5SDimitry Andrictypedef atomic<uint_fast32_t> atomic_uint_fast32_t; 2418*0b57cec5SDimitry Andrictypedef atomic<int_fast64_t> atomic_int_fast64_t; 2419*0b57cec5SDimitry Andrictypedef atomic<uint_fast64_t> atomic_uint_fast64_t; 2420*0b57cec5SDimitry Andric 2421*0b57cec5SDimitry Andrictypedef atomic< int8_t> atomic_int8_t; 2422*0b57cec5SDimitry Andrictypedef atomic<uint8_t> atomic_uint8_t; 2423*0b57cec5SDimitry Andrictypedef atomic< int16_t> atomic_int16_t; 2424*0b57cec5SDimitry Andrictypedef atomic<uint16_t> atomic_uint16_t; 2425*0b57cec5SDimitry Andrictypedef atomic< int32_t> atomic_int32_t; 2426*0b57cec5SDimitry Andrictypedef atomic<uint32_t> atomic_uint32_t; 2427*0b57cec5SDimitry Andrictypedef atomic< int64_t> atomic_int64_t; 2428*0b57cec5SDimitry Andrictypedef atomic<uint64_t> atomic_uint64_t; 2429*0b57cec5SDimitry Andric 2430*0b57cec5SDimitry Andrictypedef atomic<intptr_t> atomic_intptr_t; 2431*0b57cec5SDimitry Andrictypedef atomic<uintptr_t> atomic_uintptr_t; 2432*0b57cec5SDimitry Andrictypedef atomic<size_t> atomic_size_t; 2433*0b57cec5SDimitry Andrictypedef atomic<ptrdiff_t> atomic_ptrdiff_t; 2434*0b57cec5SDimitry Andrictypedef atomic<intmax_t> atomic_intmax_t; 2435*0b57cec5SDimitry Andrictypedef atomic<uintmax_t> atomic_uintmax_t; 2436*0b57cec5SDimitry Andric 2437*0b57cec5SDimitry Andric#define ATOMIC_FLAG_INIT {false} 2438*0b57cec5SDimitry Andric#define ATOMIC_VAR_INIT(__v) {__v} 2439*0b57cec5SDimitry Andric 2440*0b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_STD 2441*0b57cec5SDimitry Andric 2442*0b57cec5SDimitry Andric#endif // _LIBCPP_ATOMIC 2443