brintos

brintos / llvm-project-archived public Read only

0
0
Text · 10.9 KiB · d79ef7d Raw
218 lines · c
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef _LIBCPP___CXX03___ATOMIC_ATOMIC_BASE_H10#define _LIBCPP___CXX03___ATOMIC_ATOMIC_BASE_H11 12#include <__cxx03/__atomic/atomic_sync.h>13#include <__cxx03/__atomic/check_memory_order.h>14#include <__cxx03/__atomic/cxx_atomic_impl.h>15#include <__cxx03/__atomic/is_always_lock_free.h>16#include <__cxx03/__atomic/memory_order.h>17#include <__cxx03/__config>18#include <__cxx03/__memory/addressof.h>19#include <__cxx03/__type_traits/is_integral.h>20#include <__cxx03/__type_traits/is_nothrow_constructible.h>21#include <__cxx03/__type_traits/is_same.h>22#include <__cxx03/version>23 24#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)25#  pragma GCC system_header26#endif27 28_LIBCPP_BEGIN_NAMESPACE_STD29 30template <class _Tp, bool = is_integral<_Tp>::value && !is_same<_Tp, bool>::value>31struct __atomic_base // false32{33  mutable __cxx_atomic_impl<_Tp> __a_;34 35  using value_type = _Tp;36 37  _LIBCPP_HIDE_FROM_ABI bool is_lock_free() const volatile _NOEXCEPT {38    return __cxx_atomic_is_lock_free(sizeof(__cxx_atomic_impl<_Tp>));39  }40  _LIBCPP_HIDE_FROM_ABI bool is_lock_free() const _NOEXCEPT {41    return static_cast<__atomic_base const volatile*>(this)->is_lock_free();42  }43  _LIBCPP_HIDE_FROM_ABI void store(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT44      _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) {45    std::__cxx_atomic_store(std::addressof(__a_), __d, __m);46  }47  _LIBCPP_HIDE_FROM_ABI void store(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT48      _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) {49    std::__cxx_atomic_store(std::addressof(__a_), __d, __m);50  }51  _LIBCPP_HIDE_FROM_ABI _Tp load(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT52      _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) {53    return std::__cxx_atomic_load(std::addressof(__a_), __m);54  }55  _LIBCPP_HIDE_FROM_ABI _Tp load(memory_order __m = memory_order_seq_cst) const _NOEXCEPT56      _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) {57    return std::__cxx_atomic_load(std::addressof(__a_), __m);58  }59  _LIBCPP_HIDE_FROM_ABI operator _Tp() const volatile _NOEXCEPT { return load(); }60  _LIBCPP_HIDE_FROM_ABI operator _Tp() const _NOEXCEPT { return load(); }61  _LIBCPP_HIDE_FROM_ABI _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {62    return std::__cxx_atomic_exchange(std::addressof(__a_), __d, __m);63  }64  _LIBCPP_HIDE_FROM_ABI _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT {65    return std::__cxx_atomic_exchange(std::addressof(__a_), __d, __m);66  }67  _LIBCPP_HIDE_FROM_ABI bool68  compare_exchange_weak(_Tp& __e, _Tp __d, memory_order __s, memory_order __f) volatile _NOEXCEPT69      _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) {70    return std::__cxx_atomic_compare_exchange_weak(std::addressof(__a_), std::addressof(__e), __d, __s, __f);71  }72  _LIBCPP_HIDE_FROM_ABI bool compare_exchange_weak(_Tp& __e, _Tp __d, memory_order __s, memory_order __f) _NOEXCEPT73      _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) {74    return std::__cxx_atomic_compare_exchange_weak(std::addressof(__a_), std::addressof(__e), __d, __s, __f);75  }76  _LIBCPP_HIDE_FROM_ABI bool77  compare_exchange_strong(_Tp& __e, _Tp __d, memory_order __s, memory_order __f) volatile _NOEXCEPT78      _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) {79    return std::__cxx_atomic_compare_exchange_strong(std::addressof(__a_), std::addressof(__e), __d, __s, __f);80  }81  _LIBCPP_HIDE_FROM_ABI bool compare_exchange_strong(_Tp& __e, _Tp __d, memory_order __s, memory_order __f) _NOEXCEPT82      _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) {83    return std::__cxx_atomic_compare_exchange_strong(std::addressof(__a_), std::addressof(__e), __d, __s, __f);84  }85  _LIBCPP_HIDE_FROM_ABI bool86  compare_exchange_weak(_Tp& __e, _Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {87    return std::__cxx_atomic_compare_exchange_weak(std::addressof(__a_), std::addressof(__e), __d, __m, __m);88  }89  _LIBCPP_HIDE_FROM_ABI bool90  compare_exchange_weak(_Tp& __e, _Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT {91    return std::__cxx_atomic_compare_exchange_weak(std::addressof(__a_), std::addressof(__e), __d, __m, __m);92  }93  _LIBCPP_HIDE_FROM_ABI bool94  compare_exchange_strong(_Tp& __e, _Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {95    return std::__cxx_atomic_compare_exchange_strong(std::addressof(__a_), std::addressof(__e), __d, __m, __m);96  }97  _LIBCPP_HIDE_FROM_ABI bool98  compare_exchange_strong(_Tp& __e, _Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT {99    return std::__cxx_atomic_compare_exchange_strong(std::addressof(__a_), std::addressof(__e), __d, __m, __m);100  }101 102  _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void wait(_Tp __v, memory_order __m = memory_order_seq_cst) const103      volatile _NOEXCEPT {104    std::__atomic_wait(*this, __v, __m);105  }106  _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void107  wait(_Tp __v, memory_order __m = memory_order_seq_cst) const _NOEXCEPT {108    std::__atomic_wait(*this, __v, __m);109  }110  _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_one() volatile _NOEXCEPT {111    std::__atomic_notify_one(*this);112  }113  _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_one() _NOEXCEPT { std::__atomic_notify_one(*this); }114  _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_all() volatile _NOEXCEPT {115    std::__atomic_notify_all(*this);116  }117  _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void notify_all() _NOEXCEPT { std::__atomic_notify_all(*this); }118 119  _LIBCPP_HIDE_FROM_ABI __atomic_base() _NOEXCEPT = default;120 121  _LIBCPP_HIDE_FROM_ABI __atomic_base(_Tp __d) _NOEXCEPT : __a_(__d) {}122 123  __atomic_base(const __atomic_base&) = delete;124};125 126// atomic<Integral>127 128template <class _Tp>129struct __atomic_base<_Tp, true> : public __atomic_base<_Tp, false> {130  using __base = __atomic_base<_Tp, false>;131 132  using difference_type = typename __base::value_type;133 134  _LIBCPP_HIDE_FROM_ABI __atomic_base() _NOEXCEPT = default;135 136  _LIBCPP_HIDE_FROM_ABI __atomic_base(_Tp __d) _NOEXCEPT : __base(__d) {}137 138  _LIBCPP_HIDE_FROM_ABI _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {139    return std::__cxx_atomic_fetch_add(std::addressof(this->__a_), __op, __m);140  }141  _LIBCPP_HIDE_FROM_ABI _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT {142    return std::__cxx_atomic_fetch_add(std::addressof(this->__a_), __op, __m);143  }144  _LIBCPP_HIDE_FROM_ABI _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {145    return std::__cxx_atomic_fetch_sub(std::addressof(this->__a_), __op, __m);146  }147  _LIBCPP_HIDE_FROM_ABI _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT {148    return std::__cxx_atomic_fetch_sub(std::addressof(this->__a_), __op, __m);149  }150  _LIBCPP_HIDE_FROM_ABI _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {151    return std::__cxx_atomic_fetch_and(std::addressof(this->__a_), __op, __m);152  }153  _LIBCPP_HIDE_FROM_ABI _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT {154    return std::__cxx_atomic_fetch_and(std::addressof(this->__a_), __op, __m);155  }156  _LIBCPP_HIDE_FROM_ABI _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {157    return std::__cxx_atomic_fetch_or(std::addressof(this->__a_), __op, __m);158  }159  _LIBCPP_HIDE_FROM_ABI _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT {160    return std::__cxx_atomic_fetch_or(std::addressof(this->__a_), __op, __m);161  }162  _LIBCPP_HIDE_FROM_ABI _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {163    return std::__cxx_atomic_fetch_xor(std::addressof(this->__a_), __op, __m);164  }165  _LIBCPP_HIDE_FROM_ABI _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT {166    return std::__cxx_atomic_fetch_xor(std::addressof(this->__a_), __op, __m);167  }168 169  _LIBCPP_HIDE_FROM_ABI _Tp operator++(int) volatile _NOEXCEPT { return fetch_add(_Tp(1)); }170  _LIBCPP_HIDE_FROM_ABI _Tp operator++(int) _NOEXCEPT { return fetch_add(_Tp(1)); }171  _LIBCPP_HIDE_FROM_ABI _Tp operator--(int) volatile _NOEXCEPT { return fetch_sub(_Tp(1)); }172  _LIBCPP_HIDE_FROM_ABI _Tp operator--(int) _NOEXCEPT { return fetch_sub(_Tp(1)); }173  _LIBCPP_HIDE_FROM_ABI _Tp operator++() volatile _NOEXCEPT { return fetch_add(_Tp(1)) + _Tp(1); }174  _LIBCPP_HIDE_FROM_ABI _Tp operator++() _NOEXCEPT { return fetch_add(_Tp(1)) + _Tp(1); }175  _LIBCPP_HIDE_FROM_ABI _Tp operator--() volatile _NOEXCEPT { return fetch_sub(_Tp(1)) - _Tp(1); }176  _LIBCPP_HIDE_FROM_ABI _Tp operator--() _NOEXCEPT { return fetch_sub(_Tp(1)) - _Tp(1); }177  _LIBCPP_HIDE_FROM_ABI _Tp operator+=(_Tp __op) volatile _NOEXCEPT { return fetch_add(__op) + __op; }178  _LIBCPP_HIDE_FROM_ABI _Tp operator+=(_Tp __op) _NOEXCEPT { return fetch_add(__op) + __op; }179  _LIBCPP_HIDE_FROM_ABI _Tp operator-=(_Tp __op) volatile _NOEXCEPT { return fetch_sub(__op) - __op; }180  _LIBCPP_HIDE_FROM_ABI _Tp operator-=(_Tp __op) _NOEXCEPT { return fetch_sub(__op) - __op; }181  _LIBCPP_HIDE_FROM_ABI _Tp operator&=(_Tp __op) volatile _NOEXCEPT { return fetch_and(__op) & __op; }182  _LIBCPP_HIDE_FROM_ABI _Tp operator&=(_Tp __op) _NOEXCEPT { return fetch_and(__op) & __op; }183  _LIBCPP_HIDE_FROM_ABI _Tp operator|=(_Tp __op) volatile _NOEXCEPT { return fetch_or(__op) | __op; }184  _LIBCPP_HIDE_FROM_ABI _Tp operator|=(_Tp __op) _NOEXCEPT { return fetch_or(__op) | __op; }185  _LIBCPP_HIDE_FROM_ABI _Tp operator^=(_Tp __op) volatile _NOEXCEPT { return fetch_xor(__op) ^ __op; }186  _LIBCPP_HIDE_FROM_ABI _Tp operator^=(_Tp __op) _NOEXCEPT { return fetch_xor(__op) ^ __op; }187};188 189// Here we need _IsIntegral because the default template argument is not enough190// e.g  __atomic_base<int> is __atomic_base<int, true>, which inherits from191// __atomic_base<int, false> and the caller of the wait function is192// __atomic_base<int, false>. So specializing __atomic_base<_Tp> does not work193template <class _Tp, bool _IsIntegral>194struct __atomic_waitable_traits<__atomic_base<_Tp, _IsIntegral> > {195  static _LIBCPP_HIDE_FROM_ABI _Tp __atomic_load(const __atomic_base<_Tp, _IsIntegral>& __a, memory_order __order) {196    return __a.load(__order);197  }198 199  static _LIBCPP_HIDE_FROM_ABI _Tp200  __atomic_load(const volatile __atomic_base<_Tp, _IsIntegral>& __this, memory_order __order) {201    return __this.load(__order);202  }203 204  static _LIBCPP_HIDE_FROM_ABI const __cxx_atomic_impl<_Tp>*205  __atomic_contention_address(const __atomic_base<_Tp, _IsIntegral>& __a) {206    return std::addressof(__a.__a_);207  }208 209  static _LIBCPP_HIDE_FROM_ABI const volatile __cxx_atomic_impl<_Tp>*210  __atomic_contention_address(const volatile __atomic_base<_Tp, _IsIntegral>& __this) {211    return std::addressof(__this.__a_);212  }213};214 215_LIBCPP_END_NAMESPACE_STD216 217#endif // _LIBCPP___CXX03___ATOMIC_ATOMIC_BASE_H218