atomic revision 241903
150476Speter// -*- C++ -*- 217446Swollman//===--------------------------- atomic -----------------------------------===// 3198948Sru// 4198948Sru// The LLVM Compiler Infrastructure 5198948Sru// 617446Swollman// This file is distributed under the University of Illinois Open Source 7101944Sblackend// License. See LICENSE.TXT for details. 817446Swollman// 917446Swollman//===----------------------------------------------------------------------===// 1017446Swollman 1117446Swollman#ifndef _LIBCPP_ATOMIC 1217446Swollman#define _LIBCPP_ATOMIC 1317446Swollman 1417446Swollman/* 1517446Swollman atomic synopsis 16101944Sblackend 1717446Swollmannamespace std 1868639Snik{ 19189767Sru 2017446Swollman// order and consistency 2117446Swollman 2217446Swollmantypedef enum memory_order 2317446Swollman{ 24130446Swollman memory_order_relaxed, 2517446Swollman memory_order_consume, // load-consume 2617446Swollman memory_order_acquire, // load-acquire 2717446Swollman memory_order_release, // store-release 2817446Swollman memory_order_acq_rel, // store-release load-acquire 2917446Swollman memory_order_seq_cst // store-release load-acquire 3017446Swollman} memory_order; 3117446Swollman 3217446Swollmantemplate <class T> T kill_dependency(T y) noexcept; 3317446Swollman 3417446Swollman// lock-free property 3517446Swollman 3617446Swollman#define ATOMIC_CHAR_LOCK_FREE unspecified 3717446Swollman#define ATOMIC_CHAR16_T_LOCK_FREE unspecified 3817446Swollman#define ATOMIC_CHAR32_T_LOCK_FREE unspecified 3917446Swollman#define ATOMIC_WCHAR_T_LOCK_FREE unspecified 4017446Swollman#define ATOMIC_SHORT_LOCK_FREE unspecified 4117446Swollman#define ATOMIC_INT_LOCK_FREE unspecified 4217446Swollman#define ATOMIC_LONG_LOCK_FREE unspecified 4317446Swollman#define ATOMIC_LLONG_LOCK_FREE unspecified 4417446Swollman 4517446Swollman// flag type and operations 4617446Swollman 4717446Swollmantypedef struct atomic_flag 48197392Sru{ 49226283Sedwin bool test_and_set(memory_order m = memory_order_seq_cst) volatile noexcept; 50189767Sru bool test_and_set(memory_order m = memory_order_seq_cst) noexcept; 5117446Swollman void clear(memory_order m = memory_order_seq_cst) volatile noexcept; 5217446Swollman void clear(memory_order m = memory_order_seq_cst) noexcept; 5317446Swollman atomic_flag() noexcept = default; 5417446Swollman atomic_flag(const atomic_flag&) = delete; 5517446Swollman atomic_flag& operator=(const atomic_flag&) = delete; 5617446Swollman atomic_flag& operator=(const atomic_flag&) volatile = delete; 5717446Swollman} atomic_flag; 5817446Swollman 5917446Swollmanbool 6017446Swollman atomic_flag_test_and_set(volatile atomic_flag* obj) noexcept; 6117446Swollman 6217446Swollmanbool 6317446Swollman atomic_flag_test_and_set(atomic_flag* obj) noexcept; 6417446Swollman 6517446Swollmanbool 6617446Swollman atomic_flag_test_and_set_explicit(volatile atomic_flag* obj, 6717446Swollman memory_order m) noexcept; 6817446Swollman 6917446Swollmanbool 7017446Swollman atomic_flag_test_and_set_explicit(atomic_flag* obj, memory_order m) noexcept; 7117446Swollman 72189767Sruvoid 73189767Sru atomic_flag_clear(volatile atomic_flag* obj) noexcept; 7417446Swollman 7517446Swollmanvoid 7617446Swollman atomic_flag_clear(atomic_flag* obj) noexcept; 7717446Swollman 7817446Swollmanvoid 79222011Suqs atomic_flag_clear_explicit(volatile atomic_flag* obj, memory_order m) noexcept; 8017446Swollman 8117446Swollmanvoid 8217446Swollman atomic_flag_clear_explicit(atomic_flag* obj, memory_order m) noexcept; 8317446Swollman 8417446Swollman#define ATOMIC_FLAG_INIT see below 8517446Swollman#define ATOMIC_VAR_INIT(value) see below 86113541Swollman 8717446Swollmantemplate <class T> 8817446Swollmanstruct atomic 8917446Swollman{ 9017446Swollman bool is_lock_free() const volatile noexcept; 9117446Swollman bool is_lock_free() const noexcept; 9217446Swollman void store(T desr, memory_order m = memory_order_seq_cst) volatile noexcept; 9317446Swollman void store(T desr, memory_order m = memory_order_seq_cst) noexcept; 94189767Sru T load(memory_order m = memory_order_seq_cst) const volatile noexcept; 9517446Swollman T load(memory_order m = memory_order_seq_cst) const noexcept; 9617446Swollman operator T() const volatile noexcept; 9717446Swollman operator T() const noexcept; 9817446Swollman T exchange(T desr, memory_order m = memory_order_seq_cst) volatile noexcept; 9917446Swollman T exchange(T desr, memory_order m = memory_order_seq_cst) noexcept; 10017446Swollman bool compare_exchange_weak(T& expc, T desr, 10117446Swollman memory_order s, memory_order f) volatile noexcept; 10217446Swollman bool compare_exchange_weak(T& expc, T desr, memory_order s, memory_order f) noexcept; 10317446Swollman bool compare_exchange_strong(T& expc, T desr, 10417446Swollman memory_order s, memory_order f) volatile noexcept; 10517446Swollman bool compare_exchange_strong(T& expc, T desr, 10617446Swollman memory_order s, memory_order f) noexcept; 10717446Swollman bool compare_exchange_weak(T& expc, T desr, 10817446Swollman memory_order m = memory_order_seq_cst) volatile noexcept; 10917446Swollman bool compare_exchange_weak(T& expc, T desr, 11017446Swollman memory_order m = memory_order_seq_cst) noexcept; 11117446Swollman bool compare_exchange_strong(T& expc, T desr, 11217446Swollman memory_order m = memory_order_seq_cst) volatile noexcept; 11317446Swollman bool compare_exchange_strong(T& expc, T desr, 114158863Swollman memory_order m = memory_order_seq_cst) noexcept; 11517446Swollman 11617446Swollman atomic() noexcept = default; 11717446Swollman constexpr atomic(T desr) noexcept; 11817446Swollman atomic(const atomic&) = delete; 119189767Sru atomic& operator=(const atomic&) = delete; 12017446Swollman atomic& operator=(const atomic&) volatile = delete; 12117446Swollman T operator=(T) volatile noexcept; 12217446Swollman T operator=(T) noexcept; 12317446Swollman}; 12417446Swollman 12517446Swollmantemplate <> 126189767Srustruct atomic<integral> 12717446Swollman{ 12817446Swollman bool is_lock_free() const volatile noexcept; 129158863Swollman bool is_lock_free() const noexcept; 13017446Swollman void store(integral desr, memory_order m = memory_order_seq_cst) volatile noexcept; 13117446Swollman void store(integral desr, memory_order m = memory_order_seq_cst) noexcept; 13217446Swollman integral load(memory_order m = memory_order_seq_cst) const volatile noexcept; 13317446Swollman integral load(memory_order m = memory_order_seq_cst) const noexcept; 134158863Swollman operator integral() const volatile noexcept; 13517446Swollman operator integral() const noexcept; 13617446Swollman integral exchange(integral desr, 13717446Swollman memory_order m = memory_order_seq_cst) volatile noexcept; 13817446Swollman integral exchange(integral desr, memory_order m = memory_order_seq_cst) noexcept; 139189767Sru bool compare_exchange_weak(integral& expc, integral desr, 140189767Sru memory_order s, memory_order f) volatile noexcept; 14117446Swollman bool compare_exchange_weak(integral& expc, integral desr, 14217446Swollman memory_order s, memory_order f) noexcept; 14317446Swollman bool compare_exchange_strong(integral& expc, integral desr, 14417446Swollman memory_order s, memory_order f) volatile noexcept; 14517446Swollman bool compare_exchange_strong(integral& expc, integral desr, 14617446Swollman memory_order s, memory_order f) noexcept; 14717446Swollman bool compare_exchange_weak(integral& expc, integral desr, 14817446Swollman memory_order m = memory_order_seq_cst) volatile noexcept; 14917446Swollman bool compare_exchange_weak(integral& expc, integral desr, 15017446Swollman memory_order m = memory_order_seq_cst) noexcept; 15117446Swollman bool compare_exchange_strong(integral& expc, integral desr, 15297614Swollman memory_order m = memory_order_seq_cst) volatile noexcept; 153189767Sru bool compare_exchange_strong(integral& expc, integral desr, 15417446Swollman memory_order m = memory_order_seq_cst) noexcept; 15517446Swollman 15617446Swollman integral 15717446Swollman fetch_add(integral op, memory_order m = memory_order_seq_cst) volatile noexcept; 15817446Swollman integral fetch_add(integral op, memory_order m = memory_order_seq_cst) noexcept; 15917446Swollman integral 16017446Swollman fetch_sub(integral op, memory_order m = memory_order_seq_cst) volatile noexcept; 16117446Swollman integral fetch_sub(integral op, memory_order m = memory_order_seq_cst) noexcept; 16217446Swollman integral 16317446Swollman fetch_and(integral op, memory_order m = memory_order_seq_cst) volatile noexcept; 16417446Swollman integral fetch_and(integral op, memory_order m = memory_order_seq_cst) noexcept; 16517446Swollman integral 166189767Sru fetch_or(integral op, memory_order m = memory_order_seq_cst) volatile noexcept; 167189767Sru integral fetch_or(integral op, memory_order m = memory_order_seq_cst) noexcept; 16817446Swollman integral 16917446Swollman fetch_xor(integral op, memory_order m = memory_order_seq_cst) volatile noexcept; 170163477Sru integral fetch_xor(integral op, memory_order m = memory_order_seq_cst) noexcept; 17117446Swollman 17217446Swollman atomic() noexcept = default; 17317446Swollman constexpr atomic(integral desr) noexcept; 17417446Swollman atomic(const atomic&) = delete; 17517446Swollman atomic& operator=(const atomic&) = delete; 17617446Swollman atomic& operator=(const atomic&) volatile = delete; 17717446Swollman integral operator=(integral desr) volatile noexcept; 17817446Swollman integral operator=(integral desr) noexcept; 17917446Swollman 18017446Swollman integral operator++(int) volatile noexcept; 18117446Swollman integral operator++(int) noexcept; 18217446Swollman integral operator--(int) volatile noexcept; 18317446Swollman integral operator--(int) noexcept; 18417446Swollman integral operator++() volatile noexcept; 18517446Swollman integral operator++() noexcept; 18617446Swollman integral operator--() volatile noexcept; 18717446Swollman integral operator--() noexcept; 18817446Swollman integral operator+=(integral op) volatile noexcept; 18917446Swollman integral operator+=(integral op) noexcept; 19017446Swollman integral operator-=(integral op) volatile noexcept; 191189767Sru integral operator-=(integral op) noexcept; 19217446Swollman integral operator&=(integral op) volatile noexcept; 193189767Sru integral operator&=(integral op) noexcept; 19417446Swollman integral operator|=(integral op) volatile noexcept; 19517446Swollman integral operator|=(integral op) noexcept; 19617446Swollman integral operator^=(integral op) volatile noexcept; 19717446Swollman integral operator^=(integral op) noexcept; 19817446Swollman}; 19917446Swollman 20017446Swollmantemplate <class T> 20117446Swollmanstruct atomic<T*> 20217446Swollman{ 20390196Swollman bool is_lock_free() const volatile noexcept; 20417446Swollman bool is_lock_free() const noexcept; 20517446Swollman void store(T* desr, memory_order m = memory_order_seq_cst) volatile noexcept; 206174241Sedwin void store(T* desr, memory_order m = memory_order_seq_cst) noexcept; 20717446Swollman T* load(memory_order m = memory_order_seq_cst) const volatile noexcept; 20817446Swollman T* load(memory_order m = memory_order_seq_cst) const noexcept; 209222014Sru operator T*() const volatile noexcept; 21017446Swollman operator T*() const noexcept; 21117446Swollman T* exchange(T* desr, memory_order m = memory_order_seq_cst) volatile noexcept; 21217446Swollman T* exchange(T* desr, memory_order m = memory_order_seq_cst) noexcept; 21317446Swollman bool compare_exchange_weak(T*& expc, T* desr, 21417446Swollman memory_order s, memory_order f) volatile noexcept; 21517446Swollman bool compare_exchange_weak(T*& expc, T* desr, 216163477Sru memory_order s, memory_order f) noexcept; 21717446Swollman bool compare_exchange_strong(T*& expc, T* desr, 21817446Swollman memory_order s, memory_order f) volatile noexcept; 21917446Swollman bool compare_exchange_strong(T*& expc, T* desr, 220222011Suqs memory_order s, memory_order f) noexcept; 22117446Swollman bool compare_exchange_weak(T*& expc, T* desr, 22217446Swollman memory_order m = memory_order_seq_cst) volatile noexcept; 22317446Swollman bool compare_exchange_weak(T*& expc, T* desr, 22417446Swollman memory_order m = memory_order_seq_cst) noexcept; 22517446Swollman bool compare_exchange_strong(T*& expc, T* desr, 22617446Swollman memory_order m = memory_order_seq_cst) volatile noexcept; 227226283Sedwin bool compare_exchange_strong(T*& expc, T* desr, 22817446Swollman memory_order m = memory_order_seq_cst) noexcept; 22917446Swollman T* fetch_add(ptrdiff_t op, memory_order m = memory_order_seq_cst) volatile noexcept; 230222011Suqs T* fetch_add(ptrdiff_t op, memory_order m = memory_order_seq_cst) noexcept; 231189767Sru T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst) volatile noexcept; 232226283Sedwin T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst) noexcept; 23317446Swollman 234189767Sru atomic() noexcept = default; 23517446Swollman constexpr atomic(T* desr) noexcept; 23617446Swollman atomic(const atomic&) = delete; 23717446Swollman atomic& operator=(const atomic&) = delete; 23817446Swollman atomic& operator=(const atomic&) volatile = delete; 239198948Sru 24017446Swollman T* operator=(T*) volatile noexcept; 241189767Sru T* operator=(T*) noexcept; 24217446Swollman T* operator++(int) volatile noexcept; 24317446Swollman T* operator++(int) noexcept; 24417446Swollman T* operator--(int) volatile noexcept; 24517446Swollman T* operator--(int) noexcept; 24617446Swollman T* operator++() volatile noexcept; 24717446Swollman T* operator++() noexcept; 24817446Swollman T* operator--() volatile noexcept; 24917446Swollman T* operator--() noexcept; 25017446Swollman T* operator+=(ptrdiff_t op) volatile noexcept; 25117446Swollman T* operator+=(ptrdiff_t op) noexcept; 25217446Swollman T* operator-=(ptrdiff_t op) volatile noexcept; 25317446Swollman T* operator-=(ptrdiff_t op) noexcept; 25417446Swollman}; 25517446Swollman 25617446Swollman 25717446Swollmantemplate <class T> 25817446Swollman bool 25917446Swollman atomic_is_lock_free(const volatile atomic<T>* obj) noexcept; 26017446Swollman 261189767Srutemplate <class T> 262197392Sru bool 26317446Swollman atomic_is_lock_free(const atomic<T>* obj) noexcept; 264189767Sru 265189767Srutemplate <class T> 266189767Sru void 26717446Swollman atomic_init(volatile atomic<T>* obj, T desr) noexcept; 26817446Swollman 26917446Swollmantemplate <class T> 27017446Swollman void 27117446Swollman atomic_init(atomic<T>* obj, T desr) noexcept; 27217446Swollman 27317446Swollmantemplate <class T> 27417446Swollman void 27517446Swollman atomic_store(volatile atomic<T>* obj, T desr) noexcept; 27617446Swollman 27717446Swollmantemplate <class T> 27817446Swollman void 27917446Swollman atomic_store(atomic<T>* obj, T desr) noexcept; 28017446Swollman 28117446Swollmantemplate <class T> 28217446Swollman void 28317446Swollman atomic_store_explicit(volatile atomic<T>* obj, T desr, memory_order m) noexcept; 28417446Swollman 28517446Swollmantemplate <class T> 28617446Swollman void 28717446Swollman atomic_store_explicit(atomic<T>* obj, T desr, memory_order m) noexcept; 28817446Swollman 28917446Swollmantemplate <class T> 29017446Swollman T 29117446Swollman atomic_load(const volatile atomic<T>* obj) noexcept; 29217446Swollman 29317446Swollmantemplate <class T> 29417446Swollman T 29517446Swollman atomic_load(const atomic<T>* obj) noexcept; 29617446Swollman 29717446Swollmantemplate <class T> 29817446Swollman T 29917446Swollman atomic_load_explicit(const volatile atomic<T>* obj, memory_order m) noexcept; 30017446Swollman 30117446Swollmantemplate <class T> 30217446Swollman T 30317446Swollman atomic_load_explicit(const atomic<T>* obj, memory_order m) noexcept; 30417446Swollman 30517446Swollmantemplate <class T> 30617446Swollman T 30717446Swollman atomic_exchange(volatile atomic<T>* obj, T desr) noexcept; 30817446Swollman 30917446Swollmantemplate <class T> 31017446Swollman T 31117446Swollman atomic_exchange(atomic<T>* obj, T desr) noexcept; 31217446Swollman 31317446Swollmantemplate <class T> 31417446Swollman T 31517446Swollman atomic_exchange_explicit(volatile atomic<T>* obj, T desr, memory_order m) noexcept; 31617446Swollman 31717446Swollmantemplate <class T> 31817446Swollman T 31917446Swollman atomic_exchange_explicit(atomic<T>* obj, T desr, memory_order m) noexcept; 32017446Swollman 32117446Swollmantemplate <class T> 32217446Swollman bool 32317446Swollman atomic_compare_exchange_weak(volatile atomic<T>* obj, T* expc, T desr) noexcept; 32417446Swollman 32517446Swollmantemplate <class T> 32617446Swollman bool 32717446Swollman atomic_compare_exchange_weak(atomic<T>* obj, T* expc, T desr) noexcept; 32817446Swollman 32917446Swollmantemplate <class T> 33017446Swollman bool 33117446Swollman atomic_compare_exchange_strong(volatile atomic<T>* obj, T* expc, T desr) noexcept; 33217446Swollman 33317446Swollmantemplate <class T> 33417446Swollman bool 33517446Swollman atomic_compare_exchange_strong(atomic<T>* obj, T* expc, T desr) noexcept; 33617446Swollman 33717446Swollmantemplate <class T> 33817446Swollman bool 33917446Swollman atomic_compare_exchange_weak_explicit(volatile atomic<T>* obj, T* expc, 34017446Swollman T desr, 34117446Swollman memory_order s, memory_order f) noexcept; 34217446Swollman 34317446Swollmantemplate <class T> 34417446Swollman bool 34517446Swollman atomic_compare_exchange_weak_explicit(atomic<T>* obj, T* expc, T desr, 34617446Swollman memory_order s, memory_order f) noexcept; 34717446Swollman 34817446Swollmantemplate <class T> 34917446Swollman bool 35017446Swollman atomic_compare_exchange_strong_explicit(volatile atomic<T>* obj, 35117446Swollman T* expc, T desr, 35217446Swollman memory_order s, memory_order f) noexcept; 35317446Swollman 35417446Swollmantemplate <class T> 35517446Swollman bool 35617446Swollman atomic_compare_exchange_strong_explicit(atomic<T>* obj, T* expc, 35717446Swollman T desr, 35817446Swollman memory_order s, memory_order f) noexcept; 35917446Swollman 36017446Swollmantemplate <class Integral> 36117446Swollman Integral 36217446Swollman atomic_fetch_add(volatile atomic<Integral>* obj, Integral op) noexcept; 36317446Swollman 36417446Swollmantemplate <class Integral> 36517446Swollman Integral 36617446Swollman atomic_fetch_add(atomic<Integral>* obj, Integral op) noexcept; 36717446Swollman 36817446Swollmantemplate <class Integral> 36917446Swollman Integral 37017446Swollman atomic_fetch_add_explicit(volatile atomic<Integral>* obj, Integral op, 37117446Swollman memory_order m) noexcept; 37217446Swollmantemplate <class Integral> 37317446Swollman Integral 37417446Swollman atomic_fetch_add_explicit(atomic<Integral>* obj, Integral op, 37517446Swollman memory_order m) noexcept; 37617446Swollmantemplate <class Integral> 37717446Swollman Integral 37817446Swollman atomic_fetch_sub(volatile atomic<Integral>* obj, Integral op) noexcept; 37917446Swollman 38017446Swollmantemplate <class Integral> 38117446Swollman Integral 38217446Swollman atomic_fetch_sub(atomic<Integral>* obj, Integral op) noexcept; 38317446Swollman 38417446Swollmantemplate <class Integral> 38517446Swollman Integral 38617446Swollman atomic_fetch_sub_explicit(volatile atomic<Integral>* obj, Integral op, 38717446Swollman memory_order m) noexcept; 38817446Swollmantemplate <class Integral> 38917446Swollman Integral 39017446Swollman atomic_fetch_sub_explicit(atomic<Integral>* obj, Integral op, 39117446Swollman memory_order m) noexcept; 39217446Swollmantemplate <class Integral> 39317446Swollman Integral 39417446Swollman atomic_fetch_and(volatile atomic<Integral>* obj, Integral op) noexcept; 39517446Swollman 39617446Swollmantemplate <class Integral> 39717446Swollman Integral 39817446Swollman atomic_fetch_and(atomic<Integral>* obj, Integral op) noexcept; 39917446Swollman 40017446Swollmantemplate <class Integral> 401222010Suqs Integral 40217446Swollman atomic_fetch_and_explicit(volatile atomic<Integral>* obj, Integral op, 40317446Swollman memory_order m) noexcept; 40417446Swollmantemplate <class Integral> 40517446Swollman Integral 40617446Swollman atomic_fetch_and_explicit(atomic<Integral>* obj, Integral op, 40717446Swollman memory_order m) noexcept; 40817446Swollmantemplate <class Integral> 40917446Swollman Integral 41017446Swollman atomic_fetch_or(volatile atomic<Integral>* obj, Integral op) noexcept; 41117446Swollman 41217446Swollmantemplate <class Integral> 41317446Swollman Integral 41417446Swollman atomic_fetch_or(atomic<Integral>* obj, Integral op) noexcept; 41517446Swollman 41617446Swollmantemplate <class Integral> 41717446Swollman Integral 41817446Swollman atomic_fetch_or_explicit(volatile atomic<Integral>* obj, Integral op, 41917446Swollman memory_order m) noexcept; 42017446Swollmantemplate <class Integral> 42117446Swollman Integral 42217446Swollman atomic_fetch_or_explicit(atomic<Integral>* obj, Integral op, 42317446Swollman memory_order m) noexcept; 42417446Swollmantemplate <class Integral> 42517446Swollman Integral 42617446Swollman atomic_fetch_xor(volatile atomic<Integral>* obj, Integral op) noexcept; 42717446Swollman 42817446Swollmantemplate <class Integral> 42917446Swollman Integral 43017446Swollman atomic_fetch_xor(atomic<Integral>* obj, Integral op) noexcept; 43117446Swollman 432222010Suqstemplate <class Integral> 43317446Swollman Integral 43417446Swollman atomic_fetch_xor_explicit(volatile atomic<Integral>* obj, Integral op, 43517446Swollman memory_order m) noexcept; 436222010Suqstemplate <class Integral> 43717446Swollman Integral 43817446Swollman atomic_fetch_xor_explicit(atomic<Integral>* obj, Integral op, 43917446Swollman memory_order m) noexcept; 440222010Suqs 44117446Swollmantemplate <class T> 44217446Swollman T* 44317446Swollman atomic_fetch_add(volatile atomic<T*>* obj, ptrdiff_t op) noexcept; 44417446Swollman 44517446Swollmantemplate <class T> 44617446Swollman T* 44717446Swollman atomic_fetch_add(atomic<T*>* obj, ptrdiff_t op) noexcept; 44817446Swollman 44917446Swollmantemplate <class T> 45017446Swollman T* 451174014Skeramida atomic_fetch_add_explicit(volatile atomic<T*>* obj, ptrdiff_t op, 452174014Skeramida memory_order m) noexcept; 45317446Swollmantemplate <class T> 45417446Swollman T* 45517446Swollman atomic_fetch_add_explicit(atomic<T*>* obj, ptrdiff_t op, memory_order m) noexcept; 456222010Suqs 45717446Swollmantemplate <class T> 458222010Suqs T* 459222010Suqs atomic_fetch_sub(volatile atomic<T*>* obj, ptrdiff_t op) noexcept; 46017446Swollman 46117446Swollmantemplate <class T> 46217446Swollman T* 463222010Suqs atomic_fetch_sub(atomic<T*>* obj, ptrdiff_t op) noexcept; 46417446Swollman 46517446Swollmantemplate <class T> 46617446Swollman T* 467222010Suqs atomic_fetch_sub_explicit(volatile atomic<T*>* obj, ptrdiff_t op, 46817446Swollman memory_order m) noexcept; 46917446Swollmantemplate <class T> 47017446Swollman T* 47117446Swollman atomic_fetch_sub_explicit(atomic<T*>* obj, ptrdiff_t op, memory_order m) noexcept; 472222010Suqs 47317446Swollman// Atomics for standard typedef types 47417446Swollman 47530812Swollmantypedef atomic<char> atomic_char; 47630812Swollmantypedef atomic<signed char> atomic_schar; 47730812Swollmantypedef atomic<unsigned char> atomic_uchar; 47830812Swollmantypedef atomic<short> atomic_short; 47990196Swollmantypedef atomic<unsigned short> atomic_ushort; 48090196Swollmantypedef atomic<int> atomic_int; 48190196Swollmantypedef atomic<unsigned int> atomic_uint; 48290196Swollmantypedef atomic<long> atomic_long; 48397614Swollmantypedef atomic<unsigned long> atomic_ulong; 48497614Swollmantypedef atomic<long long> atomic_llong; 48597614Swollmantypedef atomic<unsigned long long> atomic_ullong; 48697614Swollmantypedef atomic<char16_t> atomic_char16_t; 48797614Swollmantypedef atomic<char32_t> atomic_char32_t; 48897614Swollmantypedef atomic<wchar_t> atomic_wchar_t; 48997614Swollman 49097614Swollmantypedef atomic<int_least8_t> atomic_int_least8_t; 49197614Swollmantypedef atomic<uint_least8_t> atomic_uint_least8_t; 49297614Swollmantypedef atomic<int_least16_t> atomic_int_least16_t; 49397614Swollmantypedef atomic<uint_least16_t> atomic_uint_least16_t; 49497614Swollmantypedef atomic<int_least32_t> atomic_int_least32_t; 495113541Swollmantypedef atomic<uint_least32_t> atomic_uint_least32_t; 496113541Swollmantypedef atomic<int_least64_t> atomic_int_least64_t; 497113541Swollmantypedef atomic<uint_least64_t> atomic_uint_least64_t; 498113541Swollman 499113541Swollmantypedef atomic<int_fast8_t> atomic_int_fast8_t; 500113541Swollmantypedef atomic<uint_fast8_t> atomic_uint_fast8_t; 501113541Swollmantypedef atomic<int_fast16_t> atomic_int_fast16_t; 502118970Swollmantypedef atomic<uint_fast16_t> atomic_uint_fast16_t; 503118970Swollmantypedef atomic<int_fast32_t> atomic_int_fast32_t; 504118970Swollmantypedef atomic<uint_fast32_t> atomic_uint_fast32_t; 505130446Swollmantypedef atomic<int_fast64_t> atomic_int_fast64_t; 506130446Swollmantypedef atomic<uint_fast64_t> atomic_uint_fast64_t; 507130446Swollman 508130446Swollmantypedef atomic<intptr_t> atomic_intptr_t; 509158863Swollmantypedef atomic<uintptr_t> atomic_uintptr_t; 510130446Swollmantypedef atomic<size_t> atomic_size_t; 511130446Swollmantypedef atomic<ptrdiff_t> atomic_ptrdiff_t; 512130446Swollmantypedef atomic<intmax_t> atomic_intmax_t; 513130446Swollmantypedef atomic<uintmax_t> atomic_uintmax_t; 514130446Swollman 515130446Swollman// fences 516130446Swollman 517158863Swollmanvoid atomic_thread_fence(memory_order m) noexcept; 518158863Swollmanvoid atomic_signal_fence(memory_order m) noexcept; 519158863Swollman 520158863Swollman} // std 521163477Sru 522163477Sru*/ 523163477Sru 524174241Sedwin#include <__config> 525174241Sedwin#include <cstddef> 526174241Sedwin#include <cstdint> 527197392Sru#include <type_traits> 528197392Sru 529197392Sru#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 530197392Sru#pragma GCC system_header 531197392Sru#endif 532197392Sru 533197392Sru_LIBCPP_BEGIN_NAMESPACE_STD 534197392Sru 535197392Sru#if !__has_feature(cxx_atomic) 536197392Sru#error <atomic> is not implemented 537197392Sru#else 538197392Sru 539197392Srutypedef enum memory_order 540197392Sru{ 541197392Sru memory_order_relaxed, memory_order_consume, memory_order_acquire, 542197392Sru memory_order_release, memory_order_acq_rel, memory_order_seq_cst 543222011Suqs} memory_order; 544222011Suqs 545222011Suqstemplate <class _Tp> 546222011Suqsinline _LIBCPP_INLINE_VISIBILITY 547222011Suqs_Tp 548222011Suqskill_dependency(_Tp __y) _NOEXCEPT 549222011Suqs{ 550222011Suqs return __y; 551226283Sedwin} 552226283Sedwin 553226283Sedwin// general atomic<T> 554226283Sedwin 555226283Sedwintemplate <class _Tp, bool = is_integral<_Tp>::value && !is_same<_Tp, bool>::value> 556226283Sedwinstruct __atomic_base // false 557226283Sedwin{ 558 mutable _Atomic(_Tp) __a_; 559 560 _LIBCPP_INLINE_VISIBILITY 561 bool is_lock_free() const volatile _NOEXCEPT 562 {return __c11_atomic_is_lock_free(sizeof(_Tp));} 563 _LIBCPP_INLINE_VISIBILITY 564 bool is_lock_free() const _NOEXCEPT 565 {return __c11_atomic_is_lock_free(sizeof(_Tp));} 566 _LIBCPP_INLINE_VISIBILITY 567 void store(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT 568 {__c11_atomic_store(&__a_, __d, __m);} 569 _LIBCPP_INLINE_VISIBILITY 570 void store(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT 571 {__c11_atomic_store(&__a_, __d, __m);} 572 _LIBCPP_INLINE_VISIBILITY 573 _Tp load(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT 574 {return __c11_atomic_load(&__a_, __m);} 575 _LIBCPP_INLINE_VISIBILITY 576 _Tp load(memory_order __m = memory_order_seq_cst) const _NOEXCEPT 577 {return __c11_atomic_load(&__a_, __m);} 578 _LIBCPP_INLINE_VISIBILITY 579 operator _Tp() const volatile _NOEXCEPT {return load();} 580 _LIBCPP_INLINE_VISIBILITY 581 operator _Tp() const _NOEXCEPT {return load();} 582 _LIBCPP_INLINE_VISIBILITY 583 _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT 584 {return __c11_atomic_exchange(&__a_, __d, __m);} 585 _LIBCPP_INLINE_VISIBILITY 586 _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT 587 {return __c11_atomic_exchange(&__a_, __d, __m);} 588 _LIBCPP_INLINE_VISIBILITY 589 bool compare_exchange_weak(_Tp& __e, _Tp __d, 590 memory_order __s, memory_order __f) volatile _NOEXCEPT 591 {return __c11_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);} 592 _LIBCPP_INLINE_VISIBILITY 593 bool compare_exchange_weak(_Tp& __e, _Tp __d, 594 memory_order __s, memory_order __f) _NOEXCEPT 595 {return __c11_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);} 596 _LIBCPP_INLINE_VISIBILITY 597 bool compare_exchange_strong(_Tp& __e, _Tp __d, 598 memory_order __s, memory_order __f) volatile _NOEXCEPT 599 {return __c11_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);} 600 _LIBCPP_INLINE_VISIBILITY 601 bool compare_exchange_strong(_Tp& __e, _Tp __d, 602 memory_order __s, memory_order __f) _NOEXCEPT 603 {return __c11_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);} 604 _LIBCPP_INLINE_VISIBILITY 605 bool compare_exchange_weak(_Tp& __e, _Tp __d, 606 memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT 607 {return __c11_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);} 608 _LIBCPP_INLINE_VISIBILITY 609 bool compare_exchange_weak(_Tp& __e, _Tp __d, 610 memory_order __m = memory_order_seq_cst) _NOEXCEPT 611 {return __c11_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);} 612 _LIBCPP_INLINE_VISIBILITY 613 bool compare_exchange_strong(_Tp& __e, _Tp __d, 614 memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT 615 {return __c11_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);} 616 _LIBCPP_INLINE_VISIBILITY 617 bool compare_exchange_strong(_Tp& __e, _Tp __d, 618 memory_order __m = memory_order_seq_cst) _NOEXCEPT 619 {return __c11_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);} 620 621 _LIBCPP_INLINE_VISIBILITY 622 __atomic_base() _NOEXCEPT {} // = default; 623 _LIBCPP_INLINE_VISIBILITY 624 _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __a_(__d) {} 625#ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS 626 __atomic_base(const __atomic_base&) = delete; 627 __atomic_base& operator=(const __atomic_base&) = delete; 628 __atomic_base& operator=(const __atomic_base&) volatile = delete; 629#else // _LIBCPP_HAS_NO_DELETED_FUNCTIONS 630private: 631 __atomic_base(const __atomic_base&); 632 __atomic_base& operator=(const __atomic_base&); 633 __atomic_base& operator=(const __atomic_base&) volatile; 634#endif // _LIBCPP_HAS_NO_DELETED_FUNCTIONS 635}; 636 637// atomic<Integral> 638 639template <class _Tp> 640struct __atomic_base<_Tp, true> 641 : public __atomic_base<_Tp, false> 642{ 643 typedef __atomic_base<_Tp, false> __base; 644 _LIBCPP_INLINE_VISIBILITY 645 __atomic_base() _NOEXCEPT {} // = default; 646 _LIBCPP_INLINE_VISIBILITY 647 _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __base(__d) {} 648 649 _LIBCPP_INLINE_VISIBILITY 650 _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT 651 {return __c11_atomic_fetch_add(&this->__a_, __op, __m);} 652 _LIBCPP_INLINE_VISIBILITY 653 _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT 654 {return __c11_atomic_fetch_add(&this->__a_, __op, __m);} 655 _LIBCPP_INLINE_VISIBILITY 656 _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT 657 {return __c11_atomic_fetch_sub(&this->__a_, __op, __m);} 658 _LIBCPP_INLINE_VISIBILITY 659 _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT 660 {return __c11_atomic_fetch_sub(&this->__a_, __op, __m);} 661 _LIBCPP_INLINE_VISIBILITY 662 _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT 663 {return __c11_atomic_fetch_and(&this->__a_, __op, __m);} 664 _LIBCPP_INLINE_VISIBILITY 665 _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT 666 {return __c11_atomic_fetch_and(&this->__a_, __op, __m);} 667 _LIBCPP_INLINE_VISIBILITY 668 _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT 669 {return __c11_atomic_fetch_or(&this->__a_, __op, __m);} 670 _LIBCPP_INLINE_VISIBILITY 671 _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT 672 {return __c11_atomic_fetch_or(&this->__a_, __op, __m);} 673 _LIBCPP_INLINE_VISIBILITY 674 _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT 675 {return __c11_atomic_fetch_xor(&this->__a_, __op, __m);} 676 _LIBCPP_INLINE_VISIBILITY 677 _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT 678 {return __c11_atomic_fetch_xor(&this->__a_, __op, __m);} 679 680 _LIBCPP_INLINE_VISIBILITY 681 _Tp operator++(int) volatile _NOEXCEPT {return fetch_add(_Tp(1));} 682 _LIBCPP_INLINE_VISIBILITY 683 _Tp operator++(int) _NOEXCEPT {return fetch_add(_Tp(1));} 684 _LIBCPP_INLINE_VISIBILITY 685 _Tp operator--(int) volatile _NOEXCEPT {return fetch_sub(_Tp(1));} 686 _LIBCPP_INLINE_VISIBILITY 687 _Tp operator--(int) _NOEXCEPT {return fetch_sub(_Tp(1));} 688 _LIBCPP_INLINE_VISIBILITY 689 _Tp operator++() volatile _NOEXCEPT {return fetch_add(_Tp(1)) + _Tp(1);} 690 _LIBCPP_INLINE_VISIBILITY 691 _Tp operator++() _NOEXCEPT {return fetch_add(_Tp(1)) + _Tp(1);} 692 _LIBCPP_INLINE_VISIBILITY 693 _Tp operator--() volatile _NOEXCEPT {return fetch_sub(_Tp(1)) - _Tp(1);} 694 _LIBCPP_INLINE_VISIBILITY 695 _Tp operator--() _NOEXCEPT {return fetch_sub(_Tp(1)) - _Tp(1);} 696 _LIBCPP_INLINE_VISIBILITY 697 _Tp operator+=(_Tp __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;} 698 _LIBCPP_INLINE_VISIBILITY 699 _Tp operator+=(_Tp __op) _NOEXCEPT {return fetch_add(__op) + __op;} 700 _LIBCPP_INLINE_VISIBILITY 701 _Tp operator-=(_Tp __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;} 702 _LIBCPP_INLINE_VISIBILITY 703 _Tp operator-=(_Tp __op) _NOEXCEPT {return fetch_sub(__op) - __op;} 704 _LIBCPP_INLINE_VISIBILITY 705 _Tp operator&=(_Tp __op) volatile _NOEXCEPT {return fetch_and(__op) & __op;} 706 _LIBCPP_INLINE_VISIBILITY 707 _Tp operator&=(_Tp __op) _NOEXCEPT {return fetch_and(__op) & __op;} 708 _LIBCPP_INLINE_VISIBILITY 709 _Tp operator|=(_Tp __op) volatile _NOEXCEPT {return fetch_or(__op) | __op;} 710 _LIBCPP_INLINE_VISIBILITY 711 _Tp operator|=(_Tp __op) _NOEXCEPT {return fetch_or(__op) | __op;} 712 _LIBCPP_INLINE_VISIBILITY 713 _Tp operator^=(_Tp __op) volatile _NOEXCEPT {return fetch_xor(__op) ^ __op;} 714 _LIBCPP_INLINE_VISIBILITY 715 _Tp operator^=(_Tp __op) _NOEXCEPT {return fetch_xor(__op) ^ __op;} 716}; 717 718// atomic<T> 719 720template <class _Tp> 721struct atomic 722 : public __atomic_base<_Tp> 723{ 724 typedef __atomic_base<_Tp> __base; 725 _LIBCPP_INLINE_VISIBILITY 726 atomic() _NOEXCEPT {} // = default; 727 _LIBCPP_INLINE_VISIBILITY 728 _LIBCPP_CONSTEXPR atomic(_Tp __d) _NOEXCEPT : __base(__d) {} 729 730 _LIBCPP_INLINE_VISIBILITY 731 _Tp operator=(_Tp __d) volatile _NOEXCEPT 732 {__base::store(__d); return __d;} 733 _LIBCPP_INLINE_VISIBILITY 734 _Tp operator=(_Tp __d) _NOEXCEPT 735 {__base::store(__d); return __d;} 736}; 737 738// atomic<T*> 739 740template <class _Tp> 741struct atomic<_Tp*> 742 : public __atomic_base<_Tp*> 743{ 744 typedef __atomic_base<_Tp*> __base; 745 _LIBCPP_INLINE_VISIBILITY 746 atomic() _NOEXCEPT {} // = default; 747 _LIBCPP_INLINE_VISIBILITY 748 _LIBCPP_CONSTEXPR atomic(_Tp* __d) _NOEXCEPT : __base(__d) {} 749 750 _LIBCPP_INLINE_VISIBILITY 751 _Tp* operator=(_Tp* __d) volatile _NOEXCEPT 752 {__base::store(__d); return __d;} 753 _LIBCPP_INLINE_VISIBILITY 754 _Tp* operator=(_Tp* __d) _NOEXCEPT 755 {__base::store(__d); return __d;} 756 757 _LIBCPP_INLINE_VISIBILITY 758 _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) 759 volatile _NOEXCEPT 760 {return __c11_atomic_fetch_add(&this->__a_, __op, __m);} 761 _LIBCPP_INLINE_VISIBILITY 762 _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT 763 {return __c11_atomic_fetch_add(&this->__a_, __op, __m);} 764 _LIBCPP_INLINE_VISIBILITY 765 _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) 766 volatile _NOEXCEPT 767 {return __c11_atomic_fetch_sub(&this->__a_, __op, __m);} 768 _LIBCPP_INLINE_VISIBILITY 769 _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT 770 {return __c11_atomic_fetch_sub(&this->__a_, __op, __m);} 771 772 _LIBCPP_INLINE_VISIBILITY 773 _Tp* operator++(int) volatile _NOEXCEPT {return fetch_add(1);} 774 _LIBCPP_INLINE_VISIBILITY 775 _Tp* operator++(int) _NOEXCEPT {return fetch_add(1);} 776 _LIBCPP_INLINE_VISIBILITY 777 _Tp* operator--(int) volatile _NOEXCEPT {return fetch_sub(1);} 778 _LIBCPP_INLINE_VISIBILITY 779 _Tp* operator--(int) _NOEXCEPT {return fetch_sub(1);} 780 _LIBCPP_INLINE_VISIBILITY 781 _Tp* operator++() volatile _NOEXCEPT {return fetch_add(1) + 1;} 782 _LIBCPP_INLINE_VISIBILITY 783 _Tp* operator++() _NOEXCEPT {return fetch_add(1) + 1;} 784 _LIBCPP_INLINE_VISIBILITY 785 _Tp* operator--() volatile _NOEXCEPT {return fetch_sub(1) - 1;} 786 _LIBCPP_INLINE_VISIBILITY 787 _Tp* operator--() _NOEXCEPT {return fetch_sub(1) - 1;} 788 _LIBCPP_INLINE_VISIBILITY 789 _Tp* operator+=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;} 790 _LIBCPP_INLINE_VISIBILITY 791 _Tp* operator+=(ptrdiff_t __op) _NOEXCEPT {return fetch_add(__op) + __op;} 792 _LIBCPP_INLINE_VISIBILITY 793 _Tp* operator-=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;} 794 _LIBCPP_INLINE_VISIBILITY 795 _Tp* operator-=(ptrdiff_t __op) _NOEXCEPT {return fetch_sub(__op) - __op;} 796}; 797 798// atomic_is_lock_free 799 800template <class _Tp> 801inline _LIBCPP_INLINE_VISIBILITY 802bool 803atomic_is_lock_free(const volatile atomic<_Tp>* __o) _NOEXCEPT 804{ 805 return __o->is_lock_free(); 806} 807 808template <class _Tp> 809inline _LIBCPP_INLINE_VISIBILITY 810bool 811atomic_is_lock_free(const atomic<_Tp>* __o) _NOEXCEPT 812{ 813 return __o->is_lock_free(); 814} 815 816// atomic_init 817 818template <class _Tp> 819inline _LIBCPP_INLINE_VISIBILITY 820void 821atomic_init(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT 822{ 823 __c11_atomic_init(&__o->__a_, __d); 824} 825 826template <class _Tp> 827inline _LIBCPP_INLINE_VISIBILITY 828void 829atomic_init(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT 830{ 831 __c11_atomic_init(&__o->__a_, __d); 832} 833 834// atomic_store 835 836template <class _Tp> 837inline _LIBCPP_INLINE_VISIBILITY 838void 839atomic_store(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT 840{ 841 __o->store(__d); 842} 843 844template <class _Tp> 845inline _LIBCPP_INLINE_VISIBILITY 846void 847atomic_store(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT 848{ 849 __o->store(__d); 850} 851 852// atomic_store_explicit 853 854template <class _Tp> 855inline _LIBCPP_INLINE_VISIBILITY 856void 857atomic_store_explicit(volatile atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT 858{ 859 __o->store(__d, __m); 860} 861 862template <class _Tp> 863inline _LIBCPP_INLINE_VISIBILITY 864void 865atomic_store_explicit(atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT 866{ 867 __o->store(__d, __m); 868} 869 870// atomic_load 871 872template <class _Tp> 873inline _LIBCPP_INLINE_VISIBILITY 874_Tp 875atomic_load(const volatile atomic<_Tp>* __o) _NOEXCEPT 876{ 877 return __o->load(); 878} 879 880template <class _Tp> 881inline _LIBCPP_INLINE_VISIBILITY 882_Tp 883atomic_load(const atomic<_Tp>* __o) _NOEXCEPT 884{ 885 return __o->load(); 886} 887 888// atomic_load_explicit 889 890template <class _Tp> 891inline _LIBCPP_INLINE_VISIBILITY 892_Tp 893atomic_load_explicit(const volatile atomic<_Tp>* __o, memory_order __m) _NOEXCEPT 894{ 895 return __o->load(__m); 896} 897 898template <class _Tp> 899inline _LIBCPP_INLINE_VISIBILITY 900_Tp 901atomic_load_explicit(const atomic<_Tp>* __o, memory_order __m) _NOEXCEPT 902{ 903 return __o->load(__m); 904} 905 906// atomic_exchange 907 908template <class _Tp> 909inline _LIBCPP_INLINE_VISIBILITY 910_Tp 911atomic_exchange(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT 912{ 913 return __o->exchange(__d); 914} 915 916template <class _Tp> 917inline _LIBCPP_INLINE_VISIBILITY 918_Tp 919atomic_exchange(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT 920{ 921 return __o->exchange(__d); 922} 923 924// atomic_exchange_explicit 925 926template <class _Tp> 927inline _LIBCPP_INLINE_VISIBILITY 928_Tp 929atomic_exchange_explicit(volatile atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT 930{ 931 return __o->exchange(__d, __m); 932} 933 934template <class _Tp> 935inline _LIBCPP_INLINE_VISIBILITY 936_Tp 937atomic_exchange_explicit(atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT 938{ 939 return __o->exchange(__d, __m); 940} 941 942// atomic_compare_exchange_weak 943 944template <class _Tp> 945inline _LIBCPP_INLINE_VISIBILITY 946bool 947atomic_compare_exchange_weak(volatile atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT 948{ 949 return __o->compare_exchange_weak(*__e, __d); 950} 951 952template <class _Tp> 953inline _LIBCPP_INLINE_VISIBILITY 954bool 955atomic_compare_exchange_weak(atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT 956{ 957 return __o->compare_exchange_weak(*__e, __d); 958} 959 960// atomic_compare_exchange_strong 961 962template <class _Tp> 963inline _LIBCPP_INLINE_VISIBILITY 964bool 965atomic_compare_exchange_strong(volatile atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT 966{ 967 return __o->compare_exchange_strong(*__e, __d); 968} 969 970template <class _Tp> 971inline _LIBCPP_INLINE_VISIBILITY 972bool 973atomic_compare_exchange_strong(atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT 974{ 975 return __o->compare_exchange_strong(*__e, __d); 976} 977 978// atomic_compare_exchange_weak_explicit 979 980template <class _Tp> 981inline _LIBCPP_INLINE_VISIBILITY 982bool 983atomic_compare_exchange_weak_explicit(volatile atomic<_Tp>* __o, _Tp* __e, 984 _Tp __d, 985 memory_order __s, memory_order __f) _NOEXCEPT 986{ 987 return __o->compare_exchange_weak(*__e, __d, __s, __f); 988} 989 990template <class _Tp> 991inline _LIBCPP_INLINE_VISIBILITY 992bool 993atomic_compare_exchange_weak_explicit(atomic<_Tp>* __o, _Tp* __e, _Tp __d, 994 memory_order __s, memory_order __f) _NOEXCEPT 995{ 996 return __o->compare_exchange_weak(*__e, __d, __s, __f); 997} 998 999// atomic_compare_exchange_strong_explicit 1000 1001template <class _Tp> 1002inline _LIBCPP_INLINE_VISIBILITY 1003bool 1004atomic_compare_exchange_strong_explicit(volatile atomic<_Tp>* __o, 1005 _Tp* __e, _Tp __d, 1006 memory_order __s, memory_order __f) _NOEXCEPT 1007{ 1008 return __o->compare_exchange_strong(*__e, __d, __s, __f); 1009} 1010 1011template <class _Tp> 1012inline _LIBCPP_INLINE_VISIBILITY 1013bool 1014atomic_compare_exchange_strong_explicit(atomic<_Tp>* __o, _Tp* __e, 1015 _Tp __d, 1016 memory_order __s, memory_order __f) _NOEXCEPT 1017{ 1018 return __o->compare_exchange_strong(*__e, __d, __s, __f); 1019} 1020 1021// atomic_fetch_add 1022 1023template <class _Tp> 1024inline _LIBCPP_INLINE_VISIBILITY 1025typename enable_if 1026< 1027 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1028 _Tp 1029>::type 1030atomic_fetch_add(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT 1031{ 1032 return __o->fetch_add(__op); 1033} 1034 1035template <class _Tp> 1036inline _LIBCPP_INLINE_VISIBILITY 1037typename enable_if 1038< 1039 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1040 _Tp 1041>::type 1042atomic_fetch_add(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT 1043{ 1044 return __o->fetch_add(__op); 1045} 1046 1047template <class _Tp> 1048inline _LIBCPP_INLINE_VISIBILITY 1049_Tp* 1050atomic_fetch_add(volatile atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT 1051{ 1052 return __o->fetch_add(__op); 1053} 1054 1055template <class _Tp> 1056inline _LIBCPP_INLINE_VISIBILITY 1057_Tp* 1058atomic_fetch_add(atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT 1059{ 1060 return __o->fetch_add(__op); 1061} 1062 1063// atomic_fetch_add_explicit 1064 1065template <class _Tp> 1066inline _LIBCPP_INLINE_VISIBILITY 1067typename enable_if 1068< 1069 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1070 _Tp 1071>::type 1072atomic_fetch_add_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT 1073{ 1074 return __o->fetch_add(__op, __m); 1075} 1076 1077template <class _Tp> 1078inline _LIBCPP_INLINE_VISIBILITY 1079typename enable_if 1080< 1081 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1082 _Tp 1083>::type 1084atomic_fetch_add_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT 1085{ 1086 return __o->fetch_add(__op, __m); 1087} 1088 1089template <class _Tp> 1090inline _LIBCPP_INLINE_VISIBILITY 1091_Tp* 1092atomic_fetch_add_explicit(volatile atomic<_Tp*>* __o, ptrdiff_t __op, 1093 memory_order __m) _NOEXCEPT 1094{ 1095 return __o->fetch_add(__op, __m); 1096} 1097 1098template <class _Tp> 1099inline _LIBCPP_INLINE_VISIBILITY 1100_Tp* 1101atomic_fetch_add_explicit(atomic<_Tp*>* __o, ptrdiff_t __op, memory_order __m) _NOEXCEPT 1102{ 1103 return __o->fetch_add(__op, __m); 1104} 1105 1106// atomic_fetch_sub 1107 1108template <class _Tp> 1109inline _LIBCPP_INLINE_VISIBILITY 1110typename enable_if 1111< 1112 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1113 _Tp 1114>::type 1115atomic_fetch_sub(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT 1116{ 1117 return __o->fetch_sub(__op); 1118} 1119 1120template <class _Tp> 1121inline _LIBCPP_INLINE_VISIBILITY 1122typename enable_if 1123< 1124 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1125 _Tp 1126>::type 1127atomic_fetch_sub(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT 1128{ 1129 return __o->fetch_sub(__op); 1130} 1131 1132template <class _Tp> 1133inline _LIBCPP_INLINE_VISIBILITY 1134_Tp* 1135atomic_fetch_sub(volatile atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT 1136{ 1137 return __o->fetch_sub(__op); 1138} 1139 1140template <class _Tp> 1141inline _LIBCPP_INLINE_VISIBILITY 1142_Tp* 1143atomic_fetch_sub(atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT 1144{ 1145 return __o->fetch_sub(__op); 1146} 1147 1148// atomic_fetch_sub_explicit 1149 1150template <class _Tp> 1151inline _LIBCPP_INLINE_VISIBILITY 1152typename enable_if 1153< 1154 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1155 _Tp 1156>::type 1157atomic_fetch_sub_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT 1158{ 1159 return __o->fetch_sub(__op, __m); 1160} 1161 1162template <class _Tp> 1163inline _LIBCPP_INLINE_VISIBILITY 1164typename enable_if 1165< 1166 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1167 _Tp 1168>::type 1169atomic_fetch_sub_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT 1170{ 1171 return __o->fetch_sub(__op, __m); 1172} 1173 1174template <class _Tp> 1175inline _LIBCPP_INLINE_VISIBILITY 1176_Tp* 1177atomic_fetch_sub_explicit(volatile atomic<_Tp*>* __o, ptrdiff_t __op, 1178 memory_order __m) _NOEXCEPT 1179{ 1180 return __o->fetch_sub(__op, __m); 1181} 1182 1183template <class _Tp> 1184inline _LIBCPP_INLINE_VISIBILITY 1185_Tp* 1186atomic_fetch_sub_explicit(atomic<_Tp*>* __o, ptrdiff_t __op, memory_order __m) _NOEXCEPT 1187{ 1188 return __o->fetch_sub(__op, __m); 1189} 1190 1191// atomic_fetch_and 1192 1193template <class _Tp> 1194inline _LIBCPP_INLINE_VISIBILITY 1195typename enable_if 1196< 1197 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1198 _Tp 1199>::type 1200atomic_fetch_and(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT 1201{ 1202 return __o->fetch_and(__op); 1203} 1204 1205template <class _Tp> 1206inline _LIBCPP_INLINE_VISIBILITY 1207typename enable_if 1208< 1209 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1210 _Tp 1211>::type 1212atomic_fetch_and(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT 1213{ 1214 return __o->fetch_and(__op); 1215} 1216 1217// atomic_fetch_and_explicit 1218 1219template <class _Tp> 1220inline _LIBCPP_INLINE_VISIBILITY 1221typename enable_if 1222< 1223 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1224 _Tp 1225>::type 1226atomic_fetch_and_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT 1227{ 1228 return __o->fetch_and(__op, __m); 1229} 1230 1231template <class _Tp> 1232inline _LIBCPP_INLINE_VISIBILITY 1233typename enable_if 1234< 1235 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1236 _Tp 1237>::type 1238atomic_fetch_and_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT 1239{ 1240 return __o->fetch_and(__op, __m); 1241} 1242 1243// atomic_fetch_or 1244 1245template <class _Tp> 1246inline _LIBCPP_INLINE_VISIBILITY 1247typename enable_if 1248< 1249 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1250 _Tp 1251>::type 1252atomic_fetch_or(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT 1253{ 1254 return __o->fetch_or(__op); 1255} 1256 1257template <class _Tp> 1258inline _LIBCPP_INLINE_VISIBILITY 1259typename enable_if 1260< 1261 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1262 _Tp 1263>::type 1264atomic_fetch_or(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT 1265{ 1266 return __o->fetch_or(__op); 1267} 1268 1269// atomic_fetch_or_explicit 1270 1271template <class _Tp> 1272inline _LIBCPP_INLINE_VISIBILITY 1273typename enable_if 1274< 1275 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1276 _Tp 1277>::type 1278atomic_fetch_or_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT 1279{ 1280 return __o->fetch_or(__op, __m); 1281} 1282 1283template <class _Tp> 1284inline _LIBCPP_INLINE_VISIBILITY 1285typename enable_if 1286< 1287 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1288 _Tp 1289>::type 1290atomic_fetch_or_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT 1291{ 1292 return __o->fetch_or(__op, __m); 1293} 1294 1295// atomic_fetch_xor 1296 1297template <class _Tp> 1298inline _LIBCPP_INLINE_VISIBILITY 1299typename enable_if 1300< 1301 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1302 _Tp 1303>::type 1304atomic_fetch_xor(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT 1305{ 1306 return __o->fetch_xor(__op); 1307} 1308 1309template <class _Tp> 1310inline _LIBCPP_INLINE_VISIBILITY 1311typename enable_if 1312< 1313 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1314 _Tp 1315>::type 1316atomic_fetch_xor(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT 1317{ 1318 return __o->fetch_xor(__op); 1319} 1320 1321// atomic_fetch_xor_explicit 1322 1323template <class _Tp> 1324inline _LIBCPP_INLINE_VISIBILITY 1325typename enable_if 1326< 1327 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1328 _Tp 1329>::type 1330atomic_fetch_xor_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT 1331{ 1332 return __o->fetch_xor(__op, __m); 1333} 1334 1335template <class _Tp> 1336inline _LIBCPP_INLINE_VISIBILITY 1337typename enable_if 1338< 1339 is_integral<_Tp>::value && !is_same<_Tp, bool>::value, 1340 _Tp 1341>::type 1342atomic_fetch_xor_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT 1343{ 1344 return __o->fetch_xor(__op, __m); 1345} 1346 1347// flag type and operations 1348 1349typedef struct atomic_flag 1350{ 1351 _Atomic(bool) __a_; 1352 1353 _LIBCPP_INLINE_VISIBILITY 1354 bool test_and_set(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT 1355 {return __c11_atomic_exchange(&__a_, true, __m);} 1356 _LIBCPP_INLINE_VISIBILITY 1357 bool test_and_set(memory_order __m = memory_order_seq_cst) _NOEXCEPT 1358 {return __c11_atomic_exchange(&__a_, true, __m);} 1359 _LIBCPP_INLINE_VISIBILITY 1360 void clear(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT 1361 {__c11_atomic_store(&__a_, false, __m);} 1362 _LIBCPP_INLINE_VISIBILITY 1363 void clear(memory_order __m = memory_order_seq_cst) _NOEXCEPT 1364 {__c11_atomic_store(&__a_, false, __m);} 1365 1366 _LIBCPP_INLINE_VISIBILITY 1367 atomic_flag() _NOEXCEPT {} // = default; 1368 _LIBCPP_INLINE_VISIBILITY 1369 atomic_flag(bool __b) _NOEXCEPT : __a_(__b) {} 1370 1371#ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS 1372 atomic_flag(const atomic_flag&) = delete; 1373 atomic_flag& operator=(const atomic_flag&) = delete; 1374 atomic_flag& operator=(const atomic_flag&) volatile = delete; 1375#else // _LIBCPP_HAS_NO_DELETED_FUNCTIONS 1376private: 1377 atomic_flag(const atomic_flag&); 1378 atomic_flag& operator=(const atomic_flag&); 1379 atomic_flag& operator=(const atomic_flag&) volatile; 1380#endif // _LIBCPP_HAS_NO_DELETED_FUNCTIONS 1381} atomic_flag; 1382 1383inline _LIBCPP_INLINE_VISIBILITY 1384bool 1385atomic_flag_test_and_set(volatile atomic_flag* __o) _NOEXCEPT 1386{ 1387 return __o->test_and_set(); 1388} 1389 1390inline _LIBCPP_INLINE_VISIBILITY 1391bool 1392atomic_flag_test_and_set(atomic_flag* __o) _NOEXCEPT 1393{ 1394 return __o->test_and_set(); 1395} 1396 1397inline _LIBCPP_INLINE_VISIBILITY 1398bool 1399atomic_flag_test_and_set_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT 1400{ 1401 return __o->test_and_set(__m); 1402} 1403 1404inline _LIBCPP_INLINE_VISIBILITY 1405bool 1406atomic_flag_test_and_set_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT 1407{ 1408 return __o->test_and_set(__m); 1409} 1410 1411inline _LIBCPP_INLINE_VISIBILITY 1412void 1413atomic_flag_clear(volatile atomic_flag* __o) _NOEXCEPT 1414{ 1415 __o->clear(); 1416} 1417 1418inline _LIBCPP_INLINE_VISIBILITY 1419void 1420atomic_flag_clear(atomic_flag* __o) _NOEXCEPT 1421{ 1422 __o->clear(); 1423} 1424 1425inline _LIBCPP_INLINE_VISIBILITY 1426void 1427atomic_flag_clear_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT 1428{ 1429 __o->clear(__m); 1430} 1431 1432inline _LIBCPP_INLINE_VISIBILITY 1433void 1434atomic_flag_clear_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT 1435{ 1436 __o->clear(__m); 1437} 1438 1439// fences 1440 1441inline _LIBCPP_INLINE_VISIBILITY 1442void 1443atomic_thread_fence(memory_order __m) _NOEXCEPT 1444{ 1445 __c11_atomic_thread_fence(__m); 1446} 1447 1448inline _LIBCPP_INLINE_VISIBILITY 1449void 1450atomic_signal_fence(memory_order __m) _NOEXCEPT 1451{ 1452 __c11_atomic_signal_fence(__m); 1453} 1454 1455// Atomics for standard typedef types 1456 1457typedef atomic<char> atomic_char; 1458typedef atomic<signed char> atomic_schar; 1459typedef atomic<unsigned char> atomic_uchar; 1460typedef atomic<short> atomic_short; 1461typedef atomic<unsigned short> atomic_ushort; 1462typedef atomic<int> atomic_int; 1463typedef atomic<unsigned int> atomic_uint; 1464typedef atomic<long> atomic_long; 1465typedef atomic<unsigned long> atomic_ulong; 1466typedef atomic<long long> atomic_llong; 1467typedef atomic<unsigned long long> atomic_ullong; 1468typedef atomic<char16_t> atomic_char16_t; 1469typedef atomic<char32_t> atomic_char32_t; 1470typedef atomic<wchar_t> atomic_wchar_t; 1471 1472typedef atomic<int_least8_t> atomic_int_least8_t; 1473typedef atomic<uint_least8_t> atomic_uint_least8_t; 1474typedef atomic<int_least16_t> atomic_int_least16_t; 1475typedef atomic<uint_least16_t> atomic_uint_least16_t; 1476typedef atomic<int_least32_t> atomic_int_least32_t; 1477typedef atomic<uint_least32_t> atomic_uint_least32_t; 1478typedef atomic<int_least64_t> atomic_int_least64_t; 1479typedef atomic<uint_least64_t> atomic_uint_least64_t; 1480 1481typedef atomic<int_fast8_t> atomic_int_fast8_t; 1482typedef atomic<uint_fast8_t> atomic_uint_fast8_t; 1483typedef atomic<int_fast16_t> atomic_int_fast16_t; 1484typedef atomic<uint_fast16_t> atomic_uint_fast16_t; 1485typedef atomic<int_fast32_t> atomic_int_fast32_t; 1486typedef atomic<uint_fast32_t> atomic_uint_fast32_t; 1487typedef atomic<int_fast64_t> atomic_int_fast64_t; 1488typedef atomic<uint_fast64_t> atomic_uint_fast64_t; 1489 1490typedef atomic<intptr_t> atomic_intptr_t; 1491typedef atomic<uintptr_t> atomic_uintptr_t; 1492typedef atomic<size_t> atomic_size_t; 1493typedef atomic<ptrdiff_t> atomic_ptrdiff_t; 1494typedef atomic<intmax_t> atomic_intmax_t; 1495typedef atomic<uintmax_t> atomic_uintmax_t; 1496 1497#define ATOMIC_FLAG_INIT {false} 1498#define ATOMIC_VAR_INIT(__v) {__v} 1499 1500// lock-free property 1501 1502#define ATOMIC_CHAR_LOCK_FREE 0 1503#define ATOMIC_CHAR16_T_LOCK_FREE 0 1504#define ATOMIC_CHAR32_T_LOCK_FREE 0 1505#define ATOMIC_WCHAR_T_LOCK_FREE 0 1506#define ATOMIC_SHORT_LOCK_FREE 0 1507#define ATOMIC_INT_LOCK_FREE 0 1508#define ATOMIC_LONG_LOCK_FREE 0 1509#define ATOMIC_LLONG_LOCK_FREE 0 1510 1511#endif // !__has_feature(cxx_atomic) 1512 1513_LIBCPP_END_NAMESPACE_STD 1514 1515#endif // _LIBCPP_ATOMIC 1516