atomic revision 288943
10SN/A// -*- C++ -*- 216989Srriggs//===--------------------------- atomic -----------------------------------===// 30SN/A// 40SN/A// The LLVM Compiler Infrastructure 50SN/A// 60SN/A// This file is distributed under the University of Illinois Open Source 72362SN/A// License. See LICENSE.TXT for details. 80SN/A// 92362SN/A//===----------------------------------------------------------------------===// 100SN/A 110SN/A#ifndef _LIBCPP_ATOMIC 120SN/A#define _LIBCPP_ATOMIC 130SN/A 140SN/A/* 150SN/A atomic synopsis 160SN/A 170SN/Anamespace std 180SN/A{ 190SN/A 200SN/A// order and consistency 212362SN/A 222362SN/Atypedef enum memory_order 232362SN/A{ 240SN/A memory_order_relaxed, 250SN/A memory_order_consume, // load-consume 260SN/A memory_order_acquire, // load-acquire 270SN/A memory_order_release, // store-release 28471SN/A memory_order_acq_rel, // store-release load-acquire 290SN/A memory_order_seq_cst // store-release load-acquire 300SN/A} memory_order; 310SN/A 320SN/Atemplate <class T> T kill_dependency(T y) noexcept; 330SN/A 340SN/A// lock-free property 3512546Savstepan 360SN/A#define ATOMIC_BOOL_LOCK_FREE unspecified 370SN/A#define ATOMIC_CHAR_LOCK_FREE unspecified 380SN/A#define ATOMIC_CHAR16_T_LOCK_FREE unspecified 390SN/A#define ATOMIC_CHAR32_T_LOCK_FREE unspecified 400SN/A#define ATOMIC_WCHAR_T_LOCK_FREE unspecified 410SN/A#define ATOMIC_SHORT_LOCK_FREE unspecified 420SN/A#define ATOMIC_INT_LOCK_FREE unspecified 4312546Savstepan#define ATOMIC_LONG_LOCK_FREE unspecified 440SN/A#define ATOMIC_LLONG_LOCK_FREE unspecified 450SN/A#define ATOMIC_POINTER_LOCK_FREE unspecified 460SN/A 470SN/A// flag type and operations 480SN/A 490SN/Atypedef struct atomic_flag 5012546Savstepan{ 510SN/A bool test_and_set(memory_order m = memory_order_seq_cst) volatile noexcept; 520SN/A bool test_and_set(memory_order m = memory_order_seq_cst) noexcept; 5312546Savstepan void clear(memory_order m = memory_order_seq_cst) volatile noexcept; 540SN/A void clear(memory_order m = memory_order_seq_cst) noexcept; 5512546Savstepan atomic_flag() noexcept = default; 560SN/A atomic_flag(const atomic_flag&) = delete; 570SN/A atomic_flag& operator=(const atomic_flag&) = delete; 580SN/A atomic_flag& operator=(const atomic_flag&) volatile = delete; 5912546Savstepan} atomic_flag; 600SN/A 610SN/Abool 6212546Savstepan atomic_flag_test_and_set(volatile atomic_flag* obj) noexcept; 630SN/A 640SN/Abool 650SN/A atomic_flag_test_and_set(atomic_flag* obj) noexcept; 660SN/A 670SN/Abool 680SN/A atomic_flag_test_and_set_explicit(volatile atomic_flag* obj, 690SN/A memory_order m) noexcept; 700SN/A 710SN/Abool 720SN/A atomic_flag_test_and_set_explicit(atomic_flag* obj, memory_order m) noexcept; 730SN/A 740SN/Avoid 750SN/A atomic_flag_clear(volatile atomic_flag* obj) noexcept; 760SN/A 770SN/Avoid 780SN/A atomic_flag_clear(atomic_flag* obj) noexcept; 790SN/A 800SN/Avoid 810SN/A atomic_flag_clear_explicit(volatile atomic_flag* obj, memory_order m) noexcept; 820SN/A 830SN/Avoid 840SN/A atomic_flag_clear_explicit(atomic_flag* obj, memory_order m) noexcept; 850SN/A 860SN/A#define ATOMIC_FLAG_INIT see below 870SN/A#define ATOMIC_VAR_INIT(value) see below 880SN/A 890SN/Atemplate <class T> 900SN/Astruct atomic 910SN/A{ 920SN/A bool is_lock_free() const volatile noexcept; 930SN/A bool is_lock_free() const noexcept; 940SN/A void store(T desr, memory_order m = memory_order_seq_cst) volatile noexcept; 950SN/A void store(T desr, memory_order m = memory_order_seq_cst) noexcept; 96479SN/A T load(memory_order m = memory_order_seq_cst) const volatile noexcept; 970SN/A T load(memory_order m = memory_order_seq_cst) const noexcept; 980SN/A operator T() const volatile noexcept; 990SN/A operator T() const noexcept; 1000SN/A T exchange(T desr, memory_order m = memory_order_seq_cst) volatile noexcept; 101479SN/A T exchange(T desr, memory_order m = memory_order_seq_cst) noexcept; 1020SN/A bool compare_exchange_weak(T& expc, T desr, 1030SN/A memory_order s, memory_order f) volatile noexcept; 1040SN/A bool compare_exchange_weak(T& expc, T desr, memory_order s, memory_order f) noexcept; 1050SN/A bool compare_exchange_strong(T& expc, T desr, 1060SN/A memory_order s, memory_order f) volatile noexcept; 1070SN/A bool compare_exchange_strong(T& expc, T desr, 1080SN/A memory_order s, memory_order f) noexcept; 1090SN/A bool compare_exchange_weak(T& expc, T desr, 110479SN/A memory_order m = memory_order_seq_cst) volatile noexcept; 11116989Srriggs bool compare_exchange_weak(T& expc, T desr, 1120SN/A memory_order m = memory_order_seq_cst) noexcept; 1130SN/A bool compare_exchange_strong(T& expc, T desr, 1140SN/A memory_order m = memory_order_seq_cst) volatile noexcept; 1150SN/A bool compare_exchange_strong(T& expc, T desr, 1160SN/A memory_order m = memory_order_seq_cst) noexcept; 1170SN/A 1180SN/A atomic() noexcept = default; 1190SN/A constexpr atomic(T desr) noexcept; 1200SN/A atomic(const atomic&) = delete; 121471SN/A atomic& operator=(const atomic&) = delete; 1220SN/A atomic& operator=(const atomic&) volatile = delete; 12312745Smartin T operator=(T) volatile noexcept; 124471SN/A T operator=(T) noexcept; 125471SN/A}; 1260SN/A 1270SN/Atemplate <> 1280SN/Astruct atomic<integral> 1290SN/A{ 1300SN/A bool is_lock_free() const volatile noexcept; 1310SN/A bool is_lock_free() const noexcept; 1320SN/A void store(integral desr, memory_order m = memory_order_seq_cst) volatile noexcept; 1330SN/A void store(integral desr, memory_order m = memory_order_seq_cst) noexcept; 1340SN/A integral load(memory_order m = memory_order_seq_cst) const volatile noexcept; 1350SN/A integral load(memory_order m = memory_order_seq_cst) const noexcept; 1360SN/A operator integral() const volatile noexcept; 1370SN/A operator integral() const noexcept; 1380SN/A integral exchange(integral desr, 1390SN/A memory_order m = memory_order_seq_cst) volatile noexcept; 1400SN/A integral exchange(integral desr, memory_order m = memory_order_seq_cst) noexcept; 1410SN/A bool compare_exchange_weak(integral& expc, integral desr, 1420SN/A memory_order s, memory_order f) volatile noexcept; 1430SN/A bool compare_exchange_weak(integral& expc, integral desr, 1440SN/A memory_order s, memory_order f) noexcept; 1450SN/A bool compare_exchange_strong(integral& expc, integral desr, 1460SN/A memory_order s, memory_order f) volatile noexcept; 1470SN/A bool compare_exchange_strong(integral& expc, integral desr, 1480SN/A memory_order s, memory_order f) noexcept; 1490SN/A bool compare_exchange_weak(integral& expc, integral desr, 1500SN/A memory_order m = memory_order_seq_cst) volatile noexcept; 1510SN/A bool compare_exchange_weak(integral& expc, integral desr, 1520SN/A memory_order m = memory_order_seq_cst) noexcept; 1530SN/A bool compare_exchange_strong(integral& expc, integral desr, 1540SN/A memory_order m = memory_order_seq_cst) volatile noexcept; 1550SN/A bool compare_exchange_strong(integral& expc, integral desr, 1560SN/A memory_order m = memory_order_seq_cst) noexcept; 1570SN/A 1580SN/A integral 1590SN/A fetch_add(integral op, memory_order m = memory_order_seq_cst) volatile noexcept; 1600SN/A integral fetch_add(integral op, memory_order m = memory_order_seq_cst) noexcept; 1610SN/A integral 1620SN/A fetch_sub(integral op, memory_order m = memory_order_seq_cst) volatile noexcept; 1630SN/A integral fetch_sub(integral op, memory_order m = memory_order_seq_cst) noexcept; 1640SN/A integral 1650SN/A fetch_and(integral op, memory_order m = memory_order_seq_cst) volatile noexcept; 1660SN/A integral fetch_and(integral op, memory_order m = memory_order_seq_cst) noexcept; 1670SN/A integral 1680SN/A fetch_or(integral op, memory_order m = memory_order_seq_cst) volatile noexcept; 1690SN/A integral fetch_or(integral op, memory_order m = memory_order_seq_cst) noexcept; 1700SN/A integral 1710SN/A fetch_xor(integral op, memory_order m = memory_order_seq_cst) volatile noexcept; 1720SN/A integral fetch_xor(integral op, memory_order m = memory_order_seq_cst) noexcept; 1730SN/A 1740SN/A atomic() noexcept = default; 1750SN/A constexpr atomic(integral desr) noexcept; 1760SN/A atomic(const atomic&) = delete; 1770SN/A atomic& operator=(const atomic&) = delete; 1780SN/A atomic& operator=(const atomic&) volatile = delete; 1790SN/A integral operator=(integral desr) volatile noexcept; 1800SN/A integral operator=(integral desr) noexcept; 1810SN/A 1820SN/A integral operator++(int) volatile noexcept; 1830SN/A integral operator++(int) noexcept; 1840SN/A integral operator--(int) volatile noexcept; 18512546Savstepan integral operator--(int) noexcept; 18612546Savstepan integral operator++() volatile noexcept; 1870SN/A integral operator++() noexcept; 1880SN/A integral operator--() volatile noexcept; 1890SN/A integral operator--() noexcept; 1900SN/A integral operator+=(integral op) volatile noexcept; 1910SN/A integral operator+=(integral op) noexcept; 1920SN/A integral operator-=(integral op) volatile noexcept; 1930SN/A integral operator-=(integral op) noexcept; 1940SN/A integral operator&=(integral op) volatile noexcept; 1950SN/A integral operator&=(integral op) noexcept; 1960SN/A integral operator|=(integral op) volatile noexcept; 1970SN/A integral operator|=(integral op) noexcept; 1980SN/A integral operator^=(integral op) volatile noexcept; 1990SN/A integral operator^=(integral op) noexcept; 2000SN/A}; 2010SN/A 2020SN/Atemplate <class T> 20312546Savstepanstruct atomic<T*> 2040SN/A{ 2050SN/A bool is_lock_free() const volatile noexcept; 2060SN/A bool is_lock_free() const noexcept; 2070SN/A void store(T* desr, memory_order m = memory_order_seq_cst) volatile noexcept; 2080SN/A void store(T* desr, memory_order m = memory_order_seq_cst) noexcept; 2090SN/A T* load(memory_order m = memory_order_seq_cst) const volatile noexcept; 2100SN/A T* load(memory_order m = memory_order_seq_cst) const noexcept; 2110SN/A operator T*() const volatile noexcept; 2120SN/A operator T*() const noexcept; 2130SN/A T* exchange(T* desr, memory_order m = memory_order_seq_cst) volatile noexcept; 2140SN/A T* exchange(T* desr, memory_order m = memory_order_seq_cst) noexcept; 2150SN/A bool compare_exchange_weak(T*& expc, T* desr, 2160SN/A memory_order s, memory_order f) volatile noexcept; 2170SN/A bool compare_exchange_weak(T*& expc, T* desr, 2180SN/A memory_order s, memory_order f) noexcept; 2190SN/A bool compare_exchange_strong(T*& expc, T* desr, 2200SN/A memory_order s, memory_order f) volatile noexcept; 2210SN/A bool compare_exchange_strong(T*& expc, T* desr, 2220SN/A memory_order s, memory_order f) noexcept; 22312546Savstepan bool compare_exchange_weak(T*& expc, T* desr, 2240SN/A memory_order m = memory_order_seq_cst) volatile noexcept; 2250SN/A bool compare_exchange_weak(T*& expc, T* desr, 2260SN/A memory_order m = memory_order_seq_cst) noexcept; 2270SN/A bool compare_exchange_strong(T*& expc, T* desr, 2280SN/A memory_order m = memory_order_seq_cst) volatile noexcept; 2290SN/A bool compare_exchange_strong(T*& expc, T* desr, 2300SN/A memory_order m = memory_order_seq_cst) noexcept; 2310SN/A T* fetch_add(ptrdiff_t op, memory_order m = memory_order_seq_cst) volatile noexcept; 2320SN/A T* fetch_add(ptrdiff_t op, memory_order m = memory_order_seq_cst) noexcept; 2330SN/A T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst) volatile noexcept; 2340SN/A T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst) noexcept; 2350SN/A 2360SN/A atomic() noexcept = default; 2370SN/A constexpr atomic(T* desr) noexcept; 2380SN/A atomic(const atomic&) = delete; 2390SN/A atomic& operator=(const atomic&) = delete; 2400SN/A atomic& operator=(const atomic&) volatile = delete; 2410SN/A 2420SN/A T* operator=(T*) volatile noexcept; 2430SN/A T* operator=(T*) noexcept; 2440SN/A T* operator++(int) volatile noexcept; 2450SN/A T* operator++(int) noexcept; 2460SN/A T* operator--(int) volatile noexcept; 2470SN/A T* operator--(int) noexcept; 2480SN/A T* operator++() volatile noexcept; 2490SN/A T* operator++() noexcept; 2500SN/A T* operator--() volatile noexcept; 2510SN/A T* operator--() noexcept; 2520SN/A T* operator+=(ptrdiff_t op) volatile noexcept; 2530SN/A T* operator+=(ptrdiff_t op) noexcept; 2540SN/A T* operator-=(ptrdiff_t op) volatile noexcept; 2550SN/A T* operator-=(ptrdiff_t op) noexcept; 2560SN/A}; 2570SN/A 2580SN/A 2590SN/Atemplate <class T> 2600SN/A bool 2610SN/A atomic_is_lock_free(const volatile atomic<T>* obj) noexcept; 2620SN/A 26312546Savstepantemplate <class T> 2640SN/A bool 2650SN/A atomic_is_lock_free(const atomic<T>* obj) noexcept; 2660SN/A 2670SN/Atemplate <class T> 2680SN/A void 2690SN/A atomic_init(volatile atomic<T>* obj, T desr) noexcept; 2700SN/A 2710SN/Atemplate <class T> 2720SN/A void 2730SN/A atomic_init(atomic<T>* obj, T desr) noexcept; 2740SN/A 2750SN/Atemplate <class T> 2760SN/A void 2770SN/A atomic_store(volatile atomic<T>* obj, T desr) noexcept; 2780SN/A 2790SN/Atemplate <class T> 2800SN/A void 2810SN/A atomic_store(atomic<T>* obj, T desr) noexcept; 2820SN/A 2830SN/Atemplate <class T> 2840SN/A void 2850SN/A atomic_store_explicit(volatile atomic<T>* obj, T desr, memory_order m) noexcept; 2860SN/A 2870SN/Atemplate <class T> 2880SN/A void 2890SN/A atomic_store_explicit(atomic<T>* obj, T desr, memory_order m) noexcept; 2900SN/A 2910SN/Atemplate <class T> 2920SN/A T 2930SN/A atomic_load(const volatile atomic<T>* obj) noexcept; 2940SN/A 2950SN/Atemplate <class T> 2960SN/A T 2970SN/A atomic_load(const atomic<T>* obj) noexcept; 2980SN/A 2990SN/Atemplate <class T> 3000SN/A T 3010SN/A atomic_load_explicit(const volatile atomic<T>* obj, memory_order m) noexcept; 30212546Savstepan 3030SN/Atemplate <class T> 3040SN/A T 3050SN/A atomic_load_explicit(const atomic<T>* obj, memory_order m) noexcept; 3060SN/A 3070SN/Atemplate <class T> 3080SN/A T 3090SN/A atomic_exchange(volatile atomic<T>* obj, T desr) noexcept; 3100SN/A 3110SN/Atemplate <class T> 3120SN/A T 3130SN/A atomic_exchange(atomic<T>* obj, T desr) noexcept; 3140SN/A 3150SN/Atemplate <class T> 3160SN/A T 3170SN/A atomic_exchange_explicit(volatile atomic<T>* obj, T desr, memory_order m) noexcept; 3180SN/A 3190SN/Atemplate <class T> 3200SN/A T 3210SN/A atomic_exchange_explicit(atomic<T>* obj, T desr, memory_order m) noexcept; 3220SN/A 3230SN/Atemplate <class T> 3240SN/A bool 3250SN/A atomic_compare_exchange_weak(volatile atomic<T>* obj, T* expc, T desr) noexcept; 3260SN/A 3270SN/Atemplate <class T> 3280SN/A bool 3290SN/A atomic_compare_exchange_weak(atomic<T>* obj, T* expc, T desr) noexcept; 3300SN/A 3310SN/Atemplate <class T> 3320SN/A bool 3330SN/A atomic_compare_exchange_strong(volatile atomic<T>* obj, T* expc, T desr) noexcept; 3340SN/A 3350SN/Atemplate <class T> 3360SN/A bool 3370SN/A atomic_compare_exchange_strong(atomic<T>* obj, T* expc, T desr) noexcept; 3380SN/A 3390SN/Atemplate <class T> 3400SN/A bool 3410SN/A atomic_compare_exchange_weak_explicit(volatile atomic<T>* obj, T* expc, 3420SN/A T desr, 34312546Savstepan memory_order s, memory_order f) noexcept; 3440SN/A 3450SN/Atemplate <class T> 3460SN/A bool 3470SN/A atomic_compare_exchange_weak_explicit(atomic<T>* obj, T* expc, T desr, 3480SN/A memory_order s, memory_order f) noexcept; 3490SN/A 3500SN/Atemplate <class T> 3510SN/A bool 3520SN/A atomic_compare_exchange_strong_explicit(volatile atomic<T>* obj, 3530SN/A T* expc, T desr, 3540SN/A memory_order s, memory_order f) noexcept; 3550SN/A 3560SN/Atemplate <class T> 3570SN/A bool 3580SN/A atomic_compare_exchange_strong_explicit(atomic<T>* obj, T* expc, 3590SN/A T desr, 3600SN/A memory_order s, memory_order f) noexcept; 3610SN/A 3620SN/Atemplate <class Integral> 3630SN/A Integral 3640SN/A atomic_fetch_add(volatile atomic<Integral>* obj, Integral op) noexcept; 3650SN/A 3660SN/Atemplate <class Integral> 3670SN/A Integral 3680SN/A atomic_fetch_add(atomic<Integral>* obj, Integral op) noexcept; 3690SN/A 3700SN/Atemplate <class Integral> 3710SN/A Integral 3720SN/A atomic_fetch_add_explicit(volatile atomic<Integral>* obj, Integral op, 3730SN/A memory_order m) noexcept; 3740SN/Atemplate <class Integral> 3750SN/A Integral 3760SN/A atomic_fetch_add_explicit(atomic<Integral>* obj, Integral op, 3770SN/A memory_order m) noexcept; 3780SN/Atemplate <class Integral> 3790SN/A Integral 3800SN/A atomic_fetch_sub(volatile atomic<Integral>* obj, Integral op) noexcept; 3810SN/A 38212546Savstepantemplate <class Integral> 3830SN/A Integral 3840SN/A atomic_fetch_sub(atomic<Integral>* obj, Integral op) noexcept; 3850SN/A 3860SN/Atemplate <class Integral> 3870SN/A Integral 3880SN/A atomic_fetch_sub_explicit(volatile atomic<Integral>* obj, Integral op, 3890SN/A memory_order m) noexcept; 3900SN/Atemplate <class Integral> 391479SN/A Integral 392479SN/A atomic_fetch_sub_explicit(atomic<Integral>* obj, Integral op, 393479SN/A memory_order m) noexcept; 394479SN/Atemplate <class Integral> 395479SN/A Integral 3960SN/A atomic_fetch_and(volatile atomic<Integral>* obj, Integral op) noexcept; 3970SN/A 3980SN/Atemplate <class Integral> 3990SN/A Integral 4000SN/A atomic_fetch_and(atomic<Integral>* obj, Integral op) noexcept; 4010SN/A 4020SN/Atemplate <class Integral> 4030SN/A Integral 4040SN/A atomic_fetch_and_explicit(volatile atomic<Integral>* obj, Integral op, 4050SN/A memory_order m) noexcept; 4060SN/Atemplate <class Integral> 4070SN/A Integral 4080SN/A atomic_fetch_and_explicit(atomic<Integral>* obj, Integral op, 4090SN/A memory_order m) noexcept; 4100SN/Atemplate <class Integral> 4110SN/A Integral 4120SN/A atomic_fetch_or(volatile atomic<Integral>* obj, Integral op) noexcept; 4130SN/A 4140SN/Atemplate <class Integral> 4150SN/A Integral 4160SN/A atomic_fetch_or(atomic<Integral>* obj, Integral op) noexcept; 4170SN/A 4180SN/Atemplate <class Integral> 4190SN/A Integral 4200SN/A atomic_fetch_or_explicit(volatile atomic<Integral>* obj, Integral op, 4210SN/A memory_order m) noexcept; 4220SN/Atemplate <class Integral> 4230SN/A Integral 4240SN/A atomic_fetch_or_explicit(atomic<Integral>* obj, Integral op, 4250SN/A memory_order m) noexcept; 4260SN/Atemplate <class Integral> 4270SN/A Integral 4280SN/A atomic_fetch_xor(volatile atomic<Integral>* obj, Integral op) noexcept; 4290SN/A 4300SN/Atemplate <class Integral> 4310SN/A Integral 4320SN/A atomic_fetch_xor(atomic<Integral>* obj, Integral op) noexcept; 4330SN/A 4340SN/Atemplate <class Integral> 4350SN/A Integral 4360SN/A atomic_fetch_xor_explicit(volatile atomic<Integral>* obj, Integral op, 4370SN/A memory_order m) noexcept; 4380SN/Atemplate <class Integral> 4390SN/A Integral 4400SN/A atomic_fetch_xor_explicit(atomic<Integral>* obj, Integral op, 4410SN/A memory_order m) noexcept; 4420SN/A 4430SN/Atemplate <class T> 4440SN/A T* 4450SN/A atomic_fetch_add(volatile atomic<T*>* obj, ptrdiff_t op) noexcept; 4460SN/A 4470SN/Atemplate <class T> 4480SN/A T* 4490SN/A atomic_fetch_add(atomic<T*>* obj, ptrdiff_t op) noexcept; 4500SN/A 45113217Ssmarkstemplate <class T> 4520SN/A T* 4530SN/A atomic_fetch_add_explicit(volatile atomic<T*>* obj, ptrdiff_t op, 4540SN/A memory_order m) noexcept; 4550SN/Atemplate <class T> 4560SN/A T* 4570SN/A atomic_fetch_add_explicit(atomic<T*>* obj, ptrdiff_t op, memory_order m) noexcept; 4580SN/A 4590SN/Atemplate <class T> 4600SN/A T* 4610SN/A atomic_fetch_sub(volatile atomic<T*>* obj, ptrdiff_t op) noexcept; 4620SN/A 4630SN/Atemplate <class T> 4640SN/A T* 4650SN/A atomic_fetch_sub(atomic<T*>* obj, ptrdiff_t op) noexcept; 4660SN/A 4670SN/Atemplate <class T> 4680SN/A T* 4690SN/A atomic_fetch_sub_explicit(volatile atomic<T*>* obj, ptrdiff_t op, 4700SN/A memory_order m) noexcept; 4710SN/Atemplate <class T> 4720SN/A T* 4730SN/A atomic_fetch_sub_explicit(atomic<T*>* obj, ptrdiff_t op, memory_order m) noexcept; 4740SN/A 4750SN/A// Atomics for standard typedef types 4760SN/A 4770SN/Atypedef atomic<bool> atomic_bool; 4780SN/Atypedef atomic<char> atomic_char; 4790SN/Atypedef atomic<signed char> atomic_schar; 4800SN/Atypedef atomic<unsigned char> atomic_uchar; 4810SN/Atypedef atomic<short> atomic_short; 4820SN/Atypedef atomic<unsigned short> atomic_ushort; 4830SN/Atypedef atomic<int> atomic_int; 4840SN/Atypedef atomic<unsigned int> atomic_uint; 4850SN/Atypedef atomic<long> atomic_long; 4860SN/Atypedef atomic<unsigned long> atomic_ulong; 4870SN/Atypedef atomic<long long> atomic_llong; 4880SN/Atypedef atomic<unsigned long long> atomic_ullong; 4890SN/Atypedef atomic<char16_t> atomic_char16_t; 4900SN/Atypedef atomic<char32_t> atomic_char32_t; 4910SN/Atypedef atomic<wchar_t> atomic_wchar_t; 4920SN/A 4930SN/Atypedef atomic<int_least8_t> atomic_int_least8_t; 4940SN/Atypedef atomic<uint_least8_t> atomic_uint_least8_t; 4950SN/Atypedef atomic<int_least16_t> atomic_int_least16_t; 4960SN/Atypedef atomic<uint_least16_t> atomic_uint_least16_t; 4970SN/Atypedef atomic<int_least32_t> atomic_int_least32_t; 4980SN/Atypedef atomic<uint_least32_t> atomic_uint_least32_t; 4990SN/Atypedef atomic<int_least64_t> atomic_int_least64_t; 5000SN/Atypedef atomic<uint_least64_t> atomic_uint_least64_t; 5010SN/A 5020SN/Atypedef atomic<int_fast8_t> atomic_int_fast8_t; 5030SN/Atypedef atomic<uint_fast8_t> atomic_uint_fast8_t; 5040SN/Atypedef atomic<int_fast16_t> atomic_int_fast16_t; 5050SN/Atypedef atomic<uint_fast16_t> atomic_uint_fast16_t; 5060SN/Atypedef atomic<int_fast32_t> atomic_int_fast32_t; 5070SN/Atypedef atomic<uint_fast32_t> atomic_uint_fast32_t; 5080SN/Atypedef atomic<int_fast64_t> atomic_int_fast64_t; 5090SN/Atypedef atomic<uint_fast64_t> atomic_uint_fast64_t; 5100SN/A 5110SN/Atypedef atomic<intptr_t> atomic_intptr_t; 5120SN/Atypedef atomic<uintptr_t> atomic_uintptr_t; 5130SN/Atypedef atomic<size_t> atomic_size_t; 5140SN/Atypedef atomic<ptrdiff_t> atomic_ptrdiff_t; 5150SN/Atypedef atomic<intmax_t> atomic_intmax_t; 5160SN/Atypedef atomic<uintmax_t> atomic_uintmax_t; 5170SN/A 5180SN/A// fences 5190SN/A 5200SN/Avoid atomic_thread_fence(memory_order m) noexcept; 5210SN/Avoid atomic_signal_fence(memory_order m) noexcept; 5220SN/A 5230SN/A} // std 5240SN/A 5250SN/A*/ 5260SN/A 5270SN/A#include <__config> 5280SN/A#include <cstddef> 5290SN/A#include <cstdint> 5300SN/A#include <type_traits> 5310SN/A 5320SN/A#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 5330SN/A#pragma GCC system_header 5340SN/A#endif 5350SN/A 5360SN/A#ifdef _LIBCPP_HAS_NO_THREADS 5370SN/A#error <atomic> is not supported on this single threaded system 5380SN/A#else // !_LIBCPP_HAS_NO_THREADS 5390SN/A 5400SN/A_LIBCPP_BEGIN_NAMESPACE_STD 5410SN/A 5420SN/A#if !__has_feature(cxx_atomic) && _GNUC_VER < 407 5430SN/A#error <atomic> is not implemented 5440SN/A#else 5450SN/A 5460SN/Atypedef enum memory_order 5470SN/A{ 5480SN/A memory_order_relaxed, memory_order_consume, memory_order_acquire, 5490SN/A memory_order_release, memory_order_acq_rel, memory_order_seq_cst 5500SN/A} memory_order; 5510SN/A 5520SN/A#if _GNUC_VER >= 407 5530SN/Anamespace __gcc_atomic { 5540SN/Atemplate <typename _Tp> 5550SN/Astruct __gcc_atomic_t { 5560SN/A __gcc_atomic_t() _NOEXCEPT {} 5570SN/A _LIBCPP_CONSTEXPR explicit __gcc_atomic_t(_Tp value) _NOEXCEPT 5580SN/A : __a_value(value) {} 5590SN/A _Tp __a_value; 5600SN/A}; 5610SN/A#define _Atomic(x) __gcc_atomic::__gcc_atomic_t<x> 5620SN/A 5630SN/Atemplate <typename _Tp> _Tp __create(); 5640SN/A 5650SN/Atemplate <typename _Tp, typename _Td> 5660SN/Atypename enable_if<sizeof(_Tp()->__a_value = __create<_Td>()), char>::type 5670SN/A __test_atomic_assignable(int); 5680SN/Atemplate <typename _Tp, typename _Up> 5690SN/A__two __test_atomic_assignable(...); 5700SN/A 5710SN/Atemplate <typename _Tp, typename _Td> 5720SN/Astruct __can_assign { 5730SN/A static const bool value = 5740SN/A sizeof(__test_atomic_assignable<_Tp, _Td>(1)) == sizeof(char); 5750SN/A}; 5760SN/A 5770SN/Astatic inline constexpr int __to_gcc_order(memory_order __order) { 5780SN/A // Avoid switch statement to make this a constexpr. 5790SN/A return __order == memory_order_relaxed ? __ATOMIC_RELAXED: 5800SN/A (__order == memory_order_acquire ? __ATOMIC_ACQUIRE: 5810SN/A (__order == memory_order_release ? __ATOMIC_RELEASE: 5820SN/A (__order == memory_order_seq_cst ? __ATOMIC_SEQ_CST: 5830SN/A (__order == memory_order_acq_rel ? __ATOMIC_ACQ_REL: 5840SN/A __ATOMIC_CONSUME)))); 5850SN/A} 5860SN/A 5870SN/Astatic inline constexpr int __to_gcc_failure_order(memory_order __order) { 5880SN/A // Avoid switch statement to make this a constexpr. 5890SN/A return __order == memory_order_relaxed ? __ATOMIC_RELAXED: 5900SN/A (__order == memory_order_acquire ? __ATOMIC_ACQUIRE: 5910SN/A (__order == memory_order_release ? __ATOMIC_RELAXED: 5920SN/A (__order == memory_order_seq_cst ? __ATOMIC_SEQ_CST: 5930SN/A (__order == memory_order_acq_rel ? __ATOMIC_ACQUIRE: 5940SN/A __ATOMIC_CONSUME)))); 5950SN/A} 5960SN/A 5970SN/A} // namespace __gcc_atomic 5980SN/A 5990SN/Atemplate <typename _Tp> 6000SN/Astatic inline 6010SN/Atypename enable_if< 6020SN/A __gcc_atomic::__can_assign<volatile _Atomic(_Tp)*, _Tp>::value>::type 6030SN/A__c11_atomic_init(volatile _Atomic(_Tp)* __a, _Tp __val) { 6040SN/A __a->__a_value = __val; 6050SN/A} 6060SN/A 6070SN/Atemplate <typename _Tp> 6080SN/Astatic inline 6090SN/Atypename enable_if< 6100SN/A !__gcc_atomic::__can_assign<volatile _Atomic(_Tp)*, _Tp>::value && 6110SN/A __gcc_atomic::__can_assign< _Atomic(_Tp)*, _Tp>::value>::type 6120SN/A__c11_atomic_init(volatile _Atomic(_Tp)* __a, _Tp __val) { 6130SN/A // [atomics.types.generic]p1 guarantees _Tp is trivially copyable. Because 6140SN/A // the default operator= in an object is not volatile, a byte-by-byte copy 6150SN/A // is required. 6160SN/A volatile char* to = reinterpret_cast<volatile char*>(&__a->__a_value); 6170SN/A volatile char* end = to + sizeof(_Tp); 6180SN/A char* from = reinterpret_cast<char*>(&__val); 6190SN/A while (to != end) { 6200SN/A *to++ = *from++; 6210SN/A } 6220SN/A} 6230SN/A 6240SN/Atemplate <typename _Tp> 6250SN/Astatic inline void __c11_atomic_init(_Atomic(_Tp)* __a, _Tp __val) { 6260SN/A __a->__a_value = __val; 6270SN/A} 6280SN/A 6290SN/Astatic inline void __c11_atomic_thread_fence(memory_order __order) { 6300SN/A __atomic_thread_fence(__gcc_atomic::__to_gcc_order(__order)); 6310SN/A} 6320SN/A 6330SN/Astatic inline void __c11_atomic_signal_fence(memory_order __order) { 6340SN/A __atomic_signal_fence(__gcc_atomic::__to_gcc_order(__order)); 6350SN/A} 6360SN/A 6370SN/Atemplate <typename _Tp> 6380SN/Astatic inline void __c11_atomic_store(volatile _Atomic(_Tp)* __a, _Tp __val, 6390SN/A memory_order __order) { 6400SN/A return __atomic_store(&__a->__a_value, &__val, 6410SN/A __gcc_atomic::__to_gcc_order(__order)); 6420SN/A} 6430SN/A 6440SN/Atemplate <typename _Tp> 6450SN/Astatic inline void __c11_atomic_store(_Atomic(_Tp)* __a, _Tp __val, 6460SN/A memory_order __order) { 6470SN/A __atomic_store(&__a->__a_value, &__val, 6480SN/A __gcc_atomic::__to_gcc_order(__order)); 6490SN/A} 6500SN/A 6510SN/Atemplate <typename _Tp> 6520SN/Astatic inline _Tp __c11_atomic_load(volatile _Atomic(_Tp)* __a, 6530SN/A memory_order __order) { 6540SN/A _Tp __ret; 6550SN/A __atomic_load(&__a->__a_value, &__ret, 6560SN/A __gcc_atomic::__to_gcc_order(__order)); 6570SN/A return __ret; 6580SN/A} 6590SN/A 6600SN/Atemplate <typename _Tp> 6610SN/Astatic inline _Tp __c11_atomic_load(_Atomic(_Tp)* __a, memory_order __order) { 6620SN/A _Tp __ret; 6630SN/A __atomic_load(&__a->__a_value, &__ret, 6640SN/A __gcc_atomic::__to_gcc_order(__order)); 6650SN/A return __ret; 6660SN/A} 6670SN/A 6680SN/Atemplate <typename _Tp> 6690SN/Astatic inline _Tp __c11_atomic_exchange(volatile _Atomic(_Tp)* __a, 6700SN/A _Tp __value, memory_order __order) { 6710SN/A _Tp __ret; 6720SN/A __atomic_exchange(&__a->__a_value, &__value, &__ret, 6730SN/A __gcc_atomic::__to_gcc_order(__order)); 6740SN/A return __ret; 6750SN/A} 6760SN/A 6770SN/Atemplate <typename _Tp> 6780SN/Astatic inline _Tp __c11_atomic_exchange(_Atomic(_Tp)* __a, _Tp __value, 6790SN/A memory_order __order) { 6800SN/A _Tp __ret; 6810SN/A __atomic_exchange(&__a->__a_value, &__value, &__ret, 6820SN/A __gcc_atomic::__to_gcc_order(__order)); 6830SN/A return __ret; 6840SN/A} 6850SN/A 6860SN/Atemplate <typename _Tp> 6870SN/Astatic inline bool __c11_atomic_compare_exchange_strong( 6880SN/A volatile _Atomic(_Tp)* __a, _Tp* __expected, _Tp __value, 6890SN/A memory_order __success, memory_order __failure) { 6900SN/A return __atomic_compare_exchange(&__a->__a_value, __expected, &__value, 6910SN/A false, 6920SN/A __gcc_atomic::__to_gcc_order(__success), 6930SN/A __gcc_atomic::__to_gcc_failure_order(__failure)); 6940SN/A} 6950SN/A 6960SN/Atemplate <typename _Tp> 6970SN/Astatic inline bool __c11_atomic_compare_exchange_strong( 6980SN/A _Atomic(_Tp)* __a, _Tp* __expected, _Tp __value, memory_order __success, 6990SN/A memory_order __failure) { 7000SN/A return __atomic_compare_exchange(&__a->__a_value, __expected, &__value, 7010SN/A false, 7020SN/A __gcc_atomic::__to_gcc_order(__success), 7030SN/A __gcc_atomic::__to_gcc_failure_order(__failure)); 7040SN/A} 7050SN/A 7060SN/Atemplate <typename _Tp> 7070SN/Astatic inline bool __c11_atomic_compare_exchange_weak( 7080SN/A volatile _Atomic(_Tp)* __a, _Tp* __expected, _Tp __value, 7090SN/A memory_order __success, memory_order __failure) { 7100SN/A return __atomic_compare_exchange(&__a->__a_value, __expected, &__value, 7110SN/A true, 7120SN/A __gcc_atomic::__to_gcc_order(__success), 7130SN/A __gcc_atomic::__to_gcc_failure_order(__failure)); 7140SN/A} 7150SN/A 7160SN/Atemplate <typename _Tp> 7170SN/Astatic inline bool __c11_atomic_compare_exchange_weak( 7180SN/A _Atomic(_Tp)* __a, _Tp* __expected, _Tp __value, memory_order __success, 7190SN/A memory_order __failure) { 7200SN/A return __atomic_compare_exchange(&__a->__a_value, __expected, &__value, 7210SN/A true, 722 __gcc_atomic::__to_gcc_order(__success), 723 __gcc_atomic::__to_gcc_failure_order(__failure)); 724} 725 726template <typename _Tp> 727struct __skip_amt { enum {value = 1}; }; 728 729template <typename _Tp> 730struct __skip_amt<_Tp*> { enum {value = sizeof(_Tp)}; }; 731 732// FIXME: Haven't figured out what the spec says about using arrays with 733// atomic_fetch_add. Force a failure rather than creating bad behavior. 734template <typename _Tp> 735struct __skip_amt<_Tp[]> { }; 736template <typename _Tp, int n> 737struct __skip_amt<_Tp[n]> { }; 738 739template <typename _Tp, typename _Td> 740static inline _Tp __c11_atomic_fetch_add(volatile _Atomic(_Tp)* __a, 741 _Td __delta, memory_order __order) { 742 return __atomic_fetch_add(&__a->__a_value, __delta * __skip_amt<_Tp>::value, 743 __gcc_atomic::__to_gcc_order(__order)); 744} 745 746template <typename _Tp, typename _Td> 747static inline _Tp __c11_atomic_fetch_add(_Atomic(_Tp)* __a, _Td __delta, 748 memory_order __order) { 749 return __atomic_fetch_add(&__a->__a_value, __delta * __skip_amt<_Tp>::value, 750 __gcc_atomic::__to_gcc_order(__order)); 751} 752 753template <typename _Tp, typename _Td> 754static inline _Tp __c11_atomic_fetch_sub(volatile _Atomic(_Tp)* __a, 755 _Td __delta, memory_order __order) { 756 return __atomic_fetch_sub(&__a->__a_value, __delta * __skip_amt<_Tp>::value, 757 __gcc_atomic::__to_gcc_order(__order)); 758} 759 760template <typename _Tp, typename _Td> 761static inline _Tp __c11_atomic_fetch_sub(_Atomic(_Tp)* __a, _Td __delta, 762 memory_order __order) { 763 return __atomic_fetch_sub(&__a->__a_value, __delta * __skip_amt<_Tp>::value, 764 __gcc_atomic::__to_gcc_order(__order)); 765} 766 767template <typename _Tp> 768static inline _Tp __c11_atomic_fetch_and(volatile _Atomic(_Tp)* __a, 769 _Tp __pattern, memory_order __order) { 770 return __atomic_fetch_and(&__a->__a_value, __pattern, 771 __gcc_atomic::__to_gcc_order(__order)); 772} 773 774template <typename _Tp> 775static inline _Tp __c11_atomic_fetch_and(_Atomic(_Tp)* __a, 776 _Tp __pattern, memory_order __order) { 777 return __atomic_fetch_and(&__a->__a_value, __pattern, 778 __gcc_atomic::__to_gcc_order(__order)); 779} 780 781template <typename _Tp> 782static inline _Tp __c11_atomic_fetch_or(volatile _Atomic(_Tp)* __a, 783 _Tp __pattern, memory_order __order) { 784 return __atomic_fetch_or(&__a->__a_value, __pattern, 785 __gcc_atomic::__to_gcc_order(__order)); 786} 787 788template <typename _Tp> 789static inline _Tp __c11_atomic_fetch_or(_Atomic(_Tp)* __a, _Tp __pattern, 790 memory_order __order) { 791 return __atomic_fetch_or(&__a->__a_value, __pattern, 792 __gcc_atomic::__to_gcc_order(__order)); 793} 794 795template <typename _Tp> 796static inline _Tp __c11_atomic_fetch_xor(volatile _Atomic(_Tp)* __a, 797 _Tp __pattern, memory_order __order) { 798 return __atomic_fetch_xor(&__a->__a_value, __pattern, 799 __gcc_atomic::__to_gcc_order(__order)); 800} 801 802template <typename _Tp> 803static inline _Tp __c11_atomic_fetch_xor(_Atomic(_Tp)* __a, _Tp __pattern, 804 memory_order __order) { 805 return __atomic_fetch_xor(&__a->__a_value, __pattern, 806 __gcc_atomic::__to_gcc_order(__order)); 807} 808#endif // _GNUC_VER >= 407 809 810template <class _Tp> 811inline _LIBCPP_INLINE_VISIBILITY 812_Tp 813kill_dependency(_Tp __y) _NOEXCEPT 814{ 815 return __y; 816} 817 818// general atomic<T> 819 820template <class _Tp, bool = is_integral<_Tp>::value && !is_same<_Tp, bool>::value> 821struct __atomic_base // false 822{ 823 mutable _Atomic(_Tp) __a_; 824 825 _LIBCPP_INLINE_VISIBILITY 826 bool is_lock_free() const volatile _NOEXCEPT 827 { 828#if __has_feature(cxx_atomic) 829 return __c11_atomic_is_lock_free(sizeof(_Tp)); 830#else 831 return __atomic_is_lock_free(sizeof(_Tp), 0); 832#endif 833 } 834 _LIBCPP_INLINE_VISIBILITY 835 bool is_lock_free() const _NOEXCEPT 836 {return static_cast<__atomic_base const volatile*>(this)->is_lock_free();} 837 _LIBCPP_INLINE_VISIBILITY 838 void store(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT 839 {__c11_atomic_store(&__a_, __d, __m);} 840 _LIBCPP_INLINE_VISIBILITY 841 void store(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT 842 {__c11_atomic_store(&__a_, __d, __m);} 843 _LIBCPP_INLINE_VISIBILITY 844 _Tp load(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT 845 {return __c11_atomic_load(&__a_, __m);} 846 _LIBCPP_INLINE_VISIBILITY 847 _Tp load(memory_order __m = memory_order_seq_cst) const _NOEXCEPT 848 {return __c11_atomic_load(&__a_, __m);} 849 _LIBCPP_INLINE_VISIBILITY 850 operator _Tp() const volatile _NOEXCEPT {return load();} 851 _LIBCPP_INLINE_VISIBILITY 852 operator _Tp() const _NOEXCEPT {return load();} 853 _LIBCPP_INLINE_VISIBILITY 854 _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT 855 {return __c11_atomic_exchange(&__a_, __d, __m);} 856 _LIBCPP_INLINE_VISIBILITY 857 _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT 858 {return __c11_atomic_exchange(&__a_, __d, __m);} 859 _LIBCPP_INLINE_VISIBILITY 860 bool compare_exchange_weak(_Tp& __e, _Tp __d, 861 memory_order __s, memory_order __f) volatile _NOEXCEPT 862 {return __c11_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);} 863 _LIBCPP_INLINE_VISIBILITY 864 bool compare_exchange_weak(_Tp& __e, _Tp __d, 865 memory_order __s, memory_order __f) _NOEXCEPT 866 {return __c11_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);} 867 _LIBCPP_INLINE_VISIBILITY 868 bool compare_exchange_strong(_Tp& __e, _Tp __d, 869 memory_order __s, memory_order __f) volatile _NOEXCEPT 870 {return __c11_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);} 871 _LIBCPP_INLINE_VISIBILITY 872 bool compare_exchange_strong(_Tp& __e, _Tp __d, 873 memory_order __s, memory_order __f) _NOEXCEPT 874 {return __c11_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);} 875 _LIBCPP_INLINE_VISIBILITY 876 bool compare_exchange_weak(_Tp& __e, _Tp __d, 877 memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT 878 {return __c11_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);} 879 _LIBCPP_INLINE_VISIBILITY 880 bool compare_exchange_weak(_Tp& __e, _Tp __d, 881 memory_order __m = memory_order_seq_cst) _NOEXCEPT 882 {return __c11_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);} 883 _LIBCPP_INLINE_VISIBILITY 884 bool compare_exchange_strong(_Tp& __e, _Tp __d, 885 memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT 886 {return __c11_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);} 887 _LIBCPP_INLINE_VISIBILITY 888 bool compare_exchange_strong(_Tp& __e, _Tp __d, 889 memory_order __m = memory_order_seq_cst) _NOEXCEPT 890 {return __c11_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);} 891 892 _LIBCPP_INLINE_VISIBILITY 893#ifndef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS 894 __atomic_base() _NOEXCEPT = default; 895#else 896 __atomic_base() _NOEXCEPT : __a_() {} 897#endif // _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS 898 899 _LIBCPP_INLINE_VISIBILITY 900 _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __a_(__d) {} 901#ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS 902 __atomic_base(const __atomic_base&) = delete; 903 __atomic_base& operator=(const __atomic_base&) = delete; 904 __atomic_base& operator=(const __atomic_base&) volatile = delete; 905#else // _LIBCPP_HAS_NO_DELETED_FUNCTIONS 906private: 907 __atomic_base(const __atomic_base&); 908 __atomic_base& operator=(const __atomic_base&); 909 __atomic_base& operator=(const __atomic_base&) volatile; 910#endif // _LIBCPP_HAS_NO_DELETED_FUNCTIONS 911}; 912 913// atomic<Integral> 914 915template <class _Tp> 916struct __atomic_base<_Tp, true> 917 : public __atomic_base<_Tp, false> 918{ 919 typedef __atomic_base<_Tp, false> __base; 920 _LIBCPP_INLINE_VISIBILITY 921 __atomic_base() _NOEXCEPT _LIBCPP_DEFAULT 922 _LIBCPP_INLINE_VISIBILITY 923 _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __base(__d) {} 924 925 _LIBCPP_INLINE_VISIBILITY 926 _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT 927 {return __c11_atomic_fetch_add(&this->__a_, __op, __m);} 928 _LIBCPP_INLINE_VISIBILITY 929 _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT 930 {return __c11_atomic_fetch_add(&this->__a_, __op, __m);} 931 _LIBCPP_INLINE_VISIBILITY 932 _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT 933 {return __c11_atomic_fetch_sub(&this->__a_, __op, __m);} 934 _LIBCPP_INLINE_VISIBILITY 935 _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT 936 {return __c11_atomic_fetch_sub(&this->__a_, __op, __m);} 937 _LIBCPP_INLINE_VISIBILITY 938 _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT 939 {return __c11_atomic_fetch_and(&this->__a_, __op, __m);} 940 _LIBCPP_INLINE_VISIBILITY 941 _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT 942 {return __c11_atomic_fetch_and(&this->__a_, __op, __m);} 943 _LIBCPP_INLINE_VISIBILITY 944 _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT 945 {return __c11_atomic_fetch_or(&this->__a_, __op, __m);} 946 _LIBCPP_INLINE_VISIBILITY 947 _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT 948 {return __c11_atomic_fetch_or(&this->__a_, __op, __m);} 949 _LIBCPP_INLINE_VISIBILITY 950 _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT 951 {return __c11_atomic_fetch_xor(&this->__a_, __op, __m);} 952 _LIBCPP_INLINE_VISIBILITY 953 _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT 954 {return __c11_atomic_fetch_xor(&this->__a_, __op, __m);} 955 956 _LIBCPP_INLINE_VISIBILITY 957 _Tp operator++(int) volatile _NOEXCEPT {return fetch_add(_Tp(1));} 958 _LIBCPP_INLINE_VISIBILITY 959 _Tp operator++(int) _NOEXCEPT {return fetch_add(_Tp(1));} 960 _LIBCPP_INLINE_VISIBILITY 961 _Tp operator--(int) volatile _NOEXCEPT {return fetch_sub(_Tp(1));} 962 _LIBCPP_INLINE_VISIBILITY 963 _Tp operator--(int) _NOEXCEPT {return fetch_sub(_Tp(1));} 964 _LIBCPP_INLINE_VISIBILITY 965 _Tp operator++() volatile _NOEXCEPT {return fetch_add(_Tp(1)) + _Tp(1);} 966 _LIBCPP_INLINE_VISIBILITY 967 _Tp operator++() _NOEXCEPT {return fetch_add(_Tp(1)) + _Tp(1);} 968 _LIBCPP_INLINE_VISIBILITY 969 _Tp operator--() volatile _NOEXCEPT {return fetch_sub(_Tp(1)) - _Tp(1);} 970 _LIBCPP_INLINE_VISIBILITY 971 _Tp operator--() _NOEXCEPT {return fetch_sub(_Tp(1)) - _Tp(1);} 972 _LIBCPP_INLINE_VISIBILITY 973 _Tp operator+=(_Tp __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;} 974 _LIBCPP_INLINE_VISIBILITY 975 _Tp operator+=(_Tp __op) _NOEXCEPT {return fetch_add(__op) + __op;} 976 _LIBCPP_INLINE_VISIBILITY 977 _Tp operator-=(_Tp __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;} 978 _LIBCPP_INLINE_VISIBILITY 979 _Tp operator-=(_Tp __op) _NOEXCEPT {return fetch_sub(__op) - __op;} 980 _LIBCPP_INLINE_VISIBILITY 981 _Tp operator&=(_Tp __op) volatile _NOEXCEPT {return fetch_and(__op) & __op;} 982 _LIBCPP_INLINE_VISIBILITY 983 _Tp operator&=(_Tp __op) _NOEXCEPT {return fetch_and(__op) & __op;} 984 _LIBCPP_INLINE_VISIBILITY 985 _Tp operator|=(_Tp __op) volatile _NOEXCEPT {return fetch_or(__op) | __op;} 986 _LIBCPP_INLINE_VISIBILITY 987 _Tp operator|=(_Tp __op) _NOEXCEPT {return fetch_or(__op) | __op;} 988 _LIBCPP_INLINE_VISIBILITY 989 _Tp operator^=(_Tp __op) volatile _NOEXCEPT {return fetch_xor(__op) ^ __op;} 990 _LIBCPP_INLINE_VISIBILITY 991 _Tp operator^=(_Tp __op) _NOEXCEPT {return fetch_xor(__op) ^ __op;} 992}; 993 994// atomic<T> 995 996template <class _Tp> 997struct atomic 998 : public __atomic_base<_Tp> 999{ 1000 typedef __atomic_base<_Tp> __base; 1001 _LIBCPP_INLINE_VISIBILITY 1002 atomic() _NOEXCEPT _LIBCPP_DEFAULT 1003 _LIBCPP_INLINE_VISIBILITY 1004 _LIBCPP_CONSTEXPR atomic(_Tp __d) _NOEXCEPT : __base(__d) {} 1005 1006 _LIBCPP_INLINE_VISIBILITY 1007 _Tp operator=(_Tp __d) volatile _NOEXCEPT 1008 {__base::store(__d); return __d;} 1009 _LIBCPP_INLINE_VISIBILITY 1010 _Tp operator=(_Tp __d) _NOEXCEPT 1011 {__base::store(__d); return __d;} 1012}; 1013 1014// atomic<T*> 1015 1016template <class _Tp> 1017struct atomic<_Tp*> 1018 : public __atomic_base<_Tp*> 1019{ 1020 typedef __atomic_base<_Tp*> __base; 1021 _LIBCPP_INLINE_VISIBILITY 1022 atomic() _NOEXCEPT _LIBCPP_DEFAULT 1023 _LIBCPP_INLINE_VISIBILITY 1024 _LIBCPP_CONSTEXPR atomic(_Tp* __d) _NOEXCEPT : __base(__d) {} 1025 1026 _LIBCPP_INLINE_VISIBILITY 1027 _Tp* operator=(_Tp* __d) volatile _NOEXCEPT 1028 {__base::store(__d); return __d;} 1029 _LIBCPP_INLINE_VISIBILITY 1030 _Tp* operator=(_Tp* __d) _NOEXCEPT 1031 {__base::store(__d); return __d;} 1032 1033 _LIBCPP_INLINE_VISIBILITY 1034 _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) 1035 volatile _NOEXCEPT 1036 {return __c11_atomic_fetch_add(&this->__a_, __op, __m);} 1037 _LIBCPP_INLINE_VISIBILITY 1038 _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT 1039 {return __c11_atomic_fetch_add(&this->__a_, __op, __m);} 1040 _LIBCPP_INLINE_VISIBILITY 1041 _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) 1042 volatile _NOEXCEPT 1043 {return __c11_atomic_fetch_sub(&this->__a_, __op, __m);} 1044 _LIBCPP_INLINE_VISIBILITY 1045 _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT 1046 {return __c11_atomic_fetch_sub(&this->__a_, __op, __m);} 1047 1048 _LIBCPP_INLINE_VISIBILITY 1049 _Tp* operator++(int) volatile _NOEXCEPT {return fetch_add(1);} 1050 _LIBCPP_INLINE_VISIBILITY 1051 _Tp* operator++(int) _NOEXCEPT {return fetch_add(1);} 1052 _LIBCPP_INLINE_VISIBILITY 1053 _Tp* operator--(int) volatile _NOEXCEPT {return fetch_sub(1);} 1054 _LIBCPP_INLINE_VISIBILITY 1055 _Tp* operator--(int) _NOEXCEPT {return fetch_sub(1);} 1056 _LIBCPP_INLINE_VISIBILITY 1057 _Tp* operator++() volatile _NOEXCEPT {return fetch_add(1) + 1;} 1058 _LIBCPP_INLINE_VISIBILITY 1059 _Tp* operator++() _NOEXCEPT {return fetch_add(1) + 1;} 1060 _LIBCPP_INLINE_VISIBILITY 1061 _Tp* operator--() volatile _NOEXCEPT {return fetch_sub(1) - 1;} 1062 _LIBCPP_INLINE_VISIBILITY 1063 _Tp* operator--() _NOEXCEPT {return fetch_sub(1) - 1;} 1064 _LIBCPP_INLINE_VISIBILITY 1065 _Tp* operator+=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;} 1066 _LIBCPP_INLINE_VISIBILITY 1067 _Tp* operator+=(ptrdiff_t __op) _NOEXCEPT {return fetch_add(__op) + __op;} 1068 _LIBCPP_INLINE_VISIBILITY 1069 _Tp* operator-=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;} 1070 _LIBCPP_INLINE_VISIBILITY 1071 _Tp* operator-=(ptrdiff_t __op) _NOEXCEPT {return fetch_sub(__op) - __op;} 1072}; 1073 1074// atomic_is_lock_free 1075 1076template <class _Tp> 1077inline _LIBCPP_INLINE_VISIBILITY 1078bool 1079atomic_is_lock_free(const volatile atomic<_Tp>* __o) _NOEXCEPT 1080{ 1081 return __o->is_lock_free(); 1082} 1083 1084template <class _Tp> 1085inline _LIBCPP_INLINE_VISIBILITY 1086bool 1087atomic_is_lock_free(const atomic<_Tp>* __o) _NOEXCEPT 1088{ 1089 return __o->is_lock_free(); 1090} 1091 1092// atomic_init 1093 1094template <class _Tp> 1095inline _LIBCPP_INLINE_VISIBILITY 1096void 1097atomic_init(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT 1098{ 1099 __c11_atomic_init(&__o->__a_, __d); 1100} 1101 1102template <class _Tp> 1103inline _LIBCPP_INLINE_VISIBILITY 1104void 1105atomic_init(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT 1106{ 1107 __c11_atomic_init(&__o->__a_, __d); 1108} 1109 1110// atomic_store 1111 1112template <class _Tp> 1113inline _LIBCPP_INLINE_VISIBILITY 1114void 1115atomic_store(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT 1116{ 1117 __o->store(__d); 1118} 1119 1120template <class _Tp> 1121inline _LIBCPP_INLINE_VISIBILITY 1122void 1123atomic_store(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT 1124{ 1125 __o->store(__d); 1126} 1127 1128// atomic_store_explicit 1129 1130template <class _Tp> 1131inline _LIBCPP_INLINE_VISIBILITY 1132void 1133atomic_store_explicit(volatile atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT 1134{ 1135 __o->store(__d, __m); 1136} 1137 1138template <class _Tp> 1139inline _LIBCPP_INLINE_VISIBILITY 1140void 1141atomic_store_explicit(atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT 1142{ 1143 __o->store(__d, __m); 1144} 1145 1146// atomic_load 1147 1148template <class _Tp> 1149inline _LIBCPP_INLINE_VISIBILITY 1150_Tp 1151atomic_load(const volatile atomic<_Tp>* __o) _NOEXCEPT 1152{ 1153 return __o->load(); 1154} 1155 1156template <class _Tp> 1157inline _LIBCPP_INLINE_VISIBILITY 1158_Tp 1159atomic_load(const atomic<_Tp>* __o) _NOEXCEPT 1160{ 1161 return __o->load(); 1162} 1163 1164// atomic_load_explicit 1165 1166template <class _Tp> 1167inline _LIBCPP_INLINE_VISIBILITY 1168_Tp 1169atomic_load_explicit(const volatile atomic<_Tp>* __o, memory_order __m) _NOEXCEPT 1170{ 1171 return __o->load(__m); 1172} 1173 1174template <class _Tp> 1175inline _LIBCPP_INLINE_VISIBILITY 1176_Tp 1177atomic_load_explicit(const atomic<_Tp>* __o, memory_order __m) _NOEXCEPT 1178{ 1179 return __o->load(__m); 1180} 1181 1182// atomic_exchange 1183 1184template <class _Tp> 1185inline _LIBCPP_INLINE_VISIBILITY 1186_Tp 1187atomic_exchange(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT 1188{ 1189 return __o->exchange(__d); 1190} 1191 1192template <class _Tp> 1193inline _LIBCPP_INLINE_VISIBILITY 1194_Tp 1195atomic_exchange(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT 1196{ 1197 return __o->exchange(__d); 1198} 1199 1200// atomic_exchange_explicit 1201 1202template <class _Tp> 1203inline _LIBCPP_INLINE_VISIBILITY 1204_Tp 1205atomic_exchange_explicit(volatile atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT 1206{ 1207 return __o->exchange(__d, __m); 1208} 1209 1210template <class _Tp> 1211inline _LIBCPP_INLINE_VISIBILITY 1212_Tp 1213atomic_exchange_explicit(atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT 1214{ 1215 return __o->exchange(__d, __m); 1216} 1217 1218// atomic_compare_exchange_weak 1219 1220template <class _Tp> 1221inline _LIBCPP_INLINE_VISIBILITY 1222bool 1223atomic_compare_exchange_weak(volatile atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT 1224{ 1225 return __o->compare_exchange_weak(*__e, __d); 1226} 1227 1228template <class _Tp> 1229inline _LIBCPP_INLINE_VISIBILITY 1230bool 1231atomic_compare_exchange_weak(atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT 1232{ 1233 return __o->compare_exchange_weak(*__e, __d); 1234} 1235 1236// atomic_compare_exchange_strong 1237 1238template <class _Tp> 1239inline _LIBCPP_INLINE_VISIBILITY 1240bool 1241atomic_compare_exchange_strong(volatile atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT 1242{ 1243 return __o->compare_exchange_strong(*__e, __d); 1244} 1245 1246template <class _Tp> 1247inline _LIBCPP_INLINE_VISIBILITY 1248bool 1249atomic_compare_exchange_strong(atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT 1250{ 1251 return __o->compare_exchange_strong(*__e, __d); 1252} 1253 1254// atomic_compare_exchange_weak_explicit 1255 1256template <class _Tp> 1257inline _LIBCPP_INLINE_VISIBILITY 1258bool 1259atomic_compare_exchange_weak_explicit(volatile atomic<_Tp>* __o, _Tp* __e, 1260 _Tp __d, 1261 memory_order __s, memory_order __f) _NOEXCEPT 1262{ 1263 return __o->compare_exchange_weak(*__e, __d, __s, __f); 1264} 1265 1266template <class _Tp> 1267inline _LIBCPP_INLINE_VISIBILITY 1268bool 1269atomic_compare_exchange_weak_explicit(atomic<_Tp>* __o, _Tp* __e, _Tp __d, 1270 memory_order __s, memory_order __f) _NOEXCEPT 1271{ 1272 return __o->compare_exchange_weak(*__e, __d, __s, __f); 1273} 1274 1275// atomic_compare_exchange_strong_explicit 1276 1277template <class _Tp> 1278inline _LIBCPP_INLINE_VISIBILITY 1279bool 1280atomic_compare_exchange_strong_explicit(volatile atomic<_Tp>* __o, 1281 _Tp* __e, _Tp __d, 1282 memory_order __s, memory_order __f) _NOEXCEPT 1283{ 1284 return __o->compare_exchange_strong(*__e, __d, __s, __f); 1285} 1286 1287template <class _Tp> 1288inline _LIBCPP_INLINE_VISIBILITY 1289bool 1290atomic_compare_exchange_strong_explicit(atomic<_Tp>* __o, _Tp* __e, 1291 _Tp __d, 1292 memory_order __s, memory_order __f) _NOEXCEPT 1293{ 1294 return __o->compare_exchange_strong(*__e, __d, __s, __f); 1295} 1296 1297// atomic_fetch_add 1298 1299template <class _Tp> 1300inline _LIBCPP_INLINE_VISIBILITY 1301typename enable_if 1302< 1303 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1304 _Tp 1305>::type 1306atomic_fetch_add(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT 1307{ 1308 return __o->fetch_add(__op); 1309} 1310 1311template <class _Tp> 1312inline _LIBCPP_INLINE_VISIBILITY 1313typename enable_if 1314< 1315 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1316 _Tp 1317>::type 1318atomic_fetch_add(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT 1319{ 1320 return __o->fetch_add(__op); 1321} 1322 1323template <class _Tp> 1324inline _LIBCPP_INLINE_VISIBILITY 1325_Tp* 1326atomic_fetch_add(volatile atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT 1327{ 1328 return __o->fetch_add(__op); 1329} 1330 1331template <class _Tp> 1332inline _LIBCPP_INLINE_VISIBILITY 1333_Tp* 1334atomic_fetch_add(atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT 1335{ 1336 return __o->fetch_add(__op); 1337} 1338 1339// atomic_fetch_add_explicit 1340 1341template <class _Tp> 1342inline _LIBCPP_INLINE_VISIBILITY 1343typename enable_if 1344< 1345 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1346 _Tp 1347>::type 1348atomic_fetch_add_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT 1349{ 1350 return __o->fetch_add(__op, __m); 1351} 1352 1353template <class _Tp> 1354inline _LIBCPP_INLINE_VISIBILITY 1355typename enable_if 1356< 1357 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1358 _Tp 1359>::type 1360atomic_fetch_add_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT 1361{ 1362 return __o->fetch_add(__op, __m); 1363} 1364 1365template <class _Tp> 1366inline _LIBCPP_INLINE_VISIBILITY 1367_Tp* 1368atomic_fetch_add_explicit(volatile atomic<_Tp*>* __o, ptrdiff_t __op, 1369 memory_order __m) _NOEXCEPT 1370{ 1371 return __o->fetch_add(__op, __m); 1372} 1373 1374template <class _Tp> 1375inline _LIBCPP_INLINE_VISIBILITY 1376_Tp* 1377atomic_fetch_add_explicit(atomic<_Tp*>* __o, ptrdiff_t __op, memory_order __m) _NOEXCEPT 1378{ 1379 return __o->fetch_add(__op, __m); 1380} 1381 1382// atomic_fetch_sub 1383 1384template <class _Tp> 1385inline _LIBCPP_INLINE_VISIBILITY 1386typename enable_if 1387< 1388 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1389 _Tp 1390>::type 1391atomic_fetch_sub(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT 1392{ 1393 return __o->fetch_sub(__op); 1394} 1395 1396template <class _Tp> 1397inline _LIBCPP_INLINE_VISIBILITY 1398typename enable_if 1399< 1400 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1401 _Tp 1402>::type 1403atomic_fetch_sub(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT 1404{ 1405 return __o->fetch_sub(__op); 1406} 1407 1408template <class _Tp> 1409inline _LIBCPP_INLINE_VISIBILITY 1410_Tp* 1411atomic_fetch_sub(volatile atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT 1412{ 1413 return __o->fetch_sub(__op); 1414} 1415 1416template <class _Tp> 1417inline _LIBCPP_INLINE_VISIBILITY 1418_Tp* 1419atomic_fetch_sub(atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT 1420{ 1421 return __o->fetch_sub(__op); 1422} 1423 1424// atomic_fetch_sub_explicit 1425 1426template <class _Tp> 1427inline _LIBCPP_INLINE_VISIBILITY 1428typename enable_if 1429< 1430 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1431 _Tp 1432>::type 1433atomic_fetch_sub_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT 1434{ 1435 return __o->fetch_sub(__op, __m); 1436} 1437 1438template <class _Tp> 1439inline _LIBCPP_INLINE_VISIBILITY 1440typename enable_if 1441< 1442 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1443 _Tp 1444>::type 1445atomic_fetch_sub_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT 1446{ 1447 return __o->fetch_sub(__op, __m); 1448} 1449 1450template <class _Tp> 1451inline _LIBCPP_INLINE_VISIBILITY 1452_Tp* 1453atomic_fetch_sub_explicit(volatile atomic<_Tp*>* __o, ptrdiff_t __op, 1454 memory_order __m) _NOEXCEPT 1455{ 1456 return __o->fetch_sub(__op, __m); 1457} 1458 1459template <class _Tp> 1460inline _LIBCPP_INLINE_VISIBILITY 1461_Tp* 1462atomic_fetch_sub_explicit(atomic<_Tp*>* __o, ptrdiff_t __op, memory_order __m) _NOEXCEPT 1463{ 1464 return __o->fetch_sub(__op, __m); 1465} 1466 1467// atomic_fetch_and 1468 1469template <class _Tp> 1470inline _LIBCPP_INLINE_VISIBILITY 1471typename enable_if 1472< 1473 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1474 _Tp 1475>::type 1476atomic_fetch_and(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT 1477{ 1478 return __o->fetch_and(__op); 1479} 1480 1481template <class _Tp> 1482inline _LIBCPP_INLINE_VISIBILITY 1483typename enable_if 1484< 1485 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1486 _Tp 1487>::type 1488atomic_fetch_and(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT 1489{ 1490 return __o->fetch_and(__op); 1491} 1492 1493// atomic_fetch_and_explicit 1494 1495template <class _Tp> 1496inline _LIBCPP_INLINE_VISIBILITY 1497typename enable_if 1498< 1499 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1500 _Tp 1501>::type 1502atomic_fetch_and_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT 1503{ 1504 return __o->fetch_and(__op, __m); 1505} 1506 1507template <class _Tp> 1508inline _LIBCPP_INLINE_VISIBILITY 1509typename enable_if 1510< 1511 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1512 _Tp 1513>::type 1514atomic_fetch_and_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT 1515{ 1516 return __o->fetch_and(__op, __m); 1517} 1518 1519// atomic_fetch_or 1520 1521template <class _Tp> 1522inline _LIBCPP_INLINE_VISIBILITY 1523typename enable_if 1524< 1525 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1526 _Tp 1527>::type 1528atomic_fetch_or(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT 1529{ 1530 return __o->fetch_or(__op); 1531} 1532 1533template <class _Tp> 1534inline _LIBCPP_INLINE_VISIBILITY 1535typename enable_if 1536< 1537 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1538 _Tp 1539>::type 1540atomic_fetch_or(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT 1541{ 1542 return __o->fetch_or(__op); 1543} 1544 1545// atomic_fetch_or_explicit 1546 1547template <class _Tp> 1548inline _LIBCPP_INLINE_VISIBILITY 1549typename enable_if 1550< 1551 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1552 _Tp 1553>::type 1554atomic_fetch_or_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT 1555{ 1556 return __o->fetch_or(__op, __m); 1557} 1558 1559template <class _Tp> 1560inline _LIBCPP_INLINE_VISIBILITY 1561typename enable_if 1562< 1563 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1564 _Tp 1565>::type 1566atomic_fetch_or_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT 1567{ 1568 return __o->fetch_or(__op, __m); 1569} 1570 1571// atomic_fetch_xor 1572 1573template <class _Tp> 1574inline _LIBCPP_INLINE_VISIBILITY 1575typename enable_if 1576< 1577 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1578 _Tp 1579>::type 1580atomic_fetch_xor(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT 1581{ 1582 return __o->fetch_xor(__op); 1583} 1584 1585template <class _Tp> 1586inline _LIBCPP_INLINE_VISIBILITY 1587typename enable_if 1588< 1589 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1590 _Tp 1591>::type 1592atomic_fetch_xor(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT 1593{ 1594 return __o->fetch_xor(__op); 1595} 1596 1597// atomic_fetch_xor_explicit 1598 1599template <class _Tp> 1600inline _LIBCPP_INLINE_VISIBILITY 1601typename enable_if 1602< 1603 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1604 _Tp 1605>::type 1606atomic_fetch_xor_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT 1607{ 1608 return __o->fetch_xor(__op, __m); 1609} 1610 1611template <class _Tp> 1612inline _LIBCPP_INLINE_VISIBILITY 1613typename enable_if 1614< 1615 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1616 _Tp 1617>::type 1618atomic_fetch_xor_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT 1619{ 1620 return __o->fetch_xor(__op, __m); 1621} 1622 1623// flag type and operations 1624 1625typedef struct atomic_flag 1626{ 1627 _Atomic(bool) __a_; 1628 1629 _LIBCPP_INLINE_VISIBILITY 1630 bool test_and_set(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT 1631 {return __c11_atomic_exchange(&__a_, true, __m);} 1632 _LIBCPP_INLINE_VISIBILITY 1633 bool test_and_set(memory_order __m = memory_order_seq_cst) _NOEXCEPT 1634 {return __c11_atomic_exchange(&__a_, true, __m);} 1635 _LIBCPP_INLINE_VISIBILITY 1636 void clear(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT 1637 {__c11_atomic_store(&__a_, false, __m);} 1638 _LIBCPP_INLINE_VISIBILITY 1639 void clear(memory_order __m = memory_order_seq_cst) _NOEXCEPT 1640 {__c11_atomic_store(&__a_, false, __m);} 1641 1642 _LIBCPP_INLINE_VISIBILITY 1643#ifndef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS 1644 atomic_flag() _NOEXCEPT = default; 1645#else 1646 atomic_flag() _NOEXCEPT : __a_() {} 1647#endif // _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS 1648 1649 _LIBCPP_INLINE_VISIBILITY 1650 atomic_flag(bool __b) _NOEXCEPT : __a_(__b) {} 1651 1652#ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS 1653 atomic_flag(const atomic_flag&) = delete; 1654 atomic_flag& operator=(const atomic_flag&) = delete; 1655 atomic_flag& operator=(const atomic_flag&) volatile = delete; 1656#else // _LIBCPP_HAS_NO_DELETED_FUNCTIONS 1657private: 1658 atomic_flag(const atomic_flag&); 1659 atomic_flag& operator=(const atomic_flag&); 1660 atomic_flag& operator=(const atomic_flag&) volatile; 1661#endif // _LIBCPP_HAS_NO_DELETED_FUNCTIONS 1662} atomic_flag; 1663 1664inline _LIBCPP_INLINE_VISIBILITY 1665bool 1666atomic_flag_test_and_set(volatile atomic_flag* __o) _NOEXCEPT 1667{ 1668 return __o->test_and_set(); 1669} 1670 1671inline _LIBCPP_INLINE_VISIBILITY 1672bool 1673atomic_flag_test_and_set(atomic_flag* __o) _NOEXCEPT 1674{ 1675 return __o->test_and_set(); 1676} 1677 1678inline _LIBCPP_INLINE_VISIBILITY 1679bool 1680atomic_flag_test_and_set_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT 1681{ 1682 return __o->test_and_set(__m); 1683} 1684 1685inline _LIBCPP_INLINE_VISIBILITY 1686bool 1687atomic_flag_test_and_set_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT 1688{ 1689 return __o->test_and_set(__m); 1690} 1691 1692inline _LIBCPP_INLINE_VISIBILITY 1693void 1694atomic_flag_clear(volatile atomic_flag* __o) _NOEXCEPT 1695{ 1696 __o->clear(); 1697} 1698 1699inline _LIBCPP_INLINE_VISIBILITY 1700void 1701atomic_flag_clear(atomic_flag* __o) _NOEXCEPT 1702{ 1703 __o->clear(); 1704} 1705 1706inline _LIBCPP_INLINE_VISIBILITY 1707void 1708atomic_flag_clear_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT 1709{ 1710 __o->clear(__m); 1711} 1712 1713inline _LIBCPP_INLINE_VISIBILITY 1714void 1715atomic_flag_clear_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT 1716{ 1717 __o->clear(__m); 1718} 1719 1720// fences 1721 1722inline _LIBCPP_INLINE_VISIBILITY 1723void 1724atomic_thread_fence(memory_order __m) _NOEXCEPT 1725{ 1726 __c11_atomic_thread_fence(__m); 1727} 1728 1729inline _LIBCPP_INLINE_VISIBILITY 1730void 1731atomic_signal_fence(memory_order __m) _NOEXCEPT 1732{ 1733 __c11_atomic_signal_fence(__m); 1734} 1735 1736// Atomics for standard typedef types 1737 1738typedef atomic<bool> atomic_bool; 1739typedef atomic<char> atomic_char; 1740typedef atomic<signed char> atomic_schar; 1741typedef atomic<unsigned char> atomic_uchar; 1742typedef atomic<short> atomic_short; 1743typedef atomic<unsigned short> atomic_ushort; 1744typedef atomic<int> atomic_int; 1745typedef atomic<unsigned int> atomic_uint; 1746typedef atomic<long> atomic_long; 1747typedef atomic<unsigned long> atomic_ulong; 1748typedef atomic<long long> atomic_llong; 1749typedef atomic<unsigned long long> atomic_ullong; 1750typedef atomic<char16_t> atomic_char16_t; 1751typedef atomic<char32_t> atomic_char32_t; 1752typedef atomic<wchar_t> atomic_wchar_t; 1753 1754typedef atomic<int_least8_t> atomic_int_least8_t; 1755typedef atomic<uint_least8_t> atomic_uint_least8_t; 1756typedef atomic<int_least16_t> atomic_int_least16_t; 1757typedef atomic<uint_least16_t> atomic_uint_least16_t; 1758typedef atomic<int_least32_t> atomic_int_least32_t; 1759typedef atomic<uint_least32_t> atomic_uint_least32_t; 1760typedef atomic<int_least64_t> atomic_int_least64_t; 1761typedef atomic<uint_least64_t> atomic_uint_least64_t; 1762 1763typedef atomic<int_fast8_t> atomic_int_fast8_t; 1764typedef atomic<uint_fast8_t> atomic_uint_fast8_t; 1765typedef atomic<int_fast16_t> atomic_int_fast16_t; 1766typedef atomic<uint_fast16_t> atomic_uint_fast16_t; 1767typedef atomic<int_fast32_t> atomic_int_fast32_t; 1768typedef atomic<uint_fast32_t> atomic_uint_fast32_t; 1769typedef atomic<int_fast64_t> atomic_int_fast64_t; 1770typedef atomic<uint_fast64_t> atomic_uint_fast64_t; 1771 1772typedef atomic<intptr_t> atomic_intptr_t; 1773typedef atomic<uintptr_t> atomic_uintptr_t; 1774typedef atomic<size_t> atomic_size_t; 1775typedef atomic<ptrdiff_t> atomic_ptrdiff_t; 1776typedef atomic<intmax_t> atomic_intmax_t; 1777typedef atomic<uintmax_t> atomic_uintmax_t; 1778 1779#define ATOMIC_FLAG_INIT {false} 1780#define ATOMIC_VAR_INIT(__v) {__v} 1781 1782// lock-free property 1783 1784#define ATOMIC_BOOL_LOCK_FREE __GCC_ATOMIC_BOOL_LOCK_FREE 1785#define ATOMIC_CHAR_LOCK_FREE __GCC_ATOMIC_CHAR_LOCK_FREE 1786#define ATOMIC_CHAR16_T_LOCK_FREE __GCC_ATOMIC_CHAR16_T_LOCK_FREE 1787#define ATOMIC_CHAR32_T_LOCK_FREE __GCC_ATOMIC_CHAR32_T_LOCK_FREE 1788#define ATOMIC_WCHAR_T_LOCK_FREE __GCC_ATOMIC_WCHAR_T_LOCK_FREE 1789#define ATOMIC_SHORT_LOCK_FREE __GCC_ATOMIC_SHORT_LOCK_FREE 1790#define ATOMIC_INT_LOCK_FREE __GCC_ATOMIC_INT_LOCK_FREE 1791#define ATOMIC_LONG_LOCK_FREE __GCC_ATOMIC_LONG_LOCK_FREE 1792#define ATOMIC_LLONG_LOCK_FREE __GCC_ATOMIC_LLONG_LOCK_FREE 1793#define ATOMIC_POINTER_LOCK_FREE __GCC_ATOMIC_POINTER_LOCK_FREE 1794 1795#endif // !__has_feature(cxx_atomic) 1796 1797_LIBCPP_END_NAMESPACE_STD 1798 1799#endif // !_LIBCPP_HAS_NO_THREADS 1800 1801#endif // _LIBCPP_ATOMIC 1802