1*0e34f3f4SLouis Dionne //===----------------------------------------------------------------------===// 2*0e34f3f4SLouis Dionne // 3*0e34f3f4SLouis Dionne // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0e34f3f4SLouis Dionne // See https://llvm.org/LICENSE.txt for license information. 5*0e34f3f4SLouis Dionne // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0e34f3f4SLouis Dionne // 7*0e34f3f4SLouis Dionne //===----------------------------------------------------------------------===// 8*0e34f3f4SLouis Dionne 9*0e34f3f4SLouis Dionne #ifndef _LIBCPP___ATOMIC_SUPPORT_H 10*0e34f3f4SLouis Dionne #define _LIBCPP___ATOMIC_SUPPORT_H 11*0e34f3f4SLouis Dionne 12*0e34f3f4SLouis Dionne #include <__config> 13*0e34f3f4SLouis Dionne #include <__type_traits/is_trivially_copyable.h> 14*0e34f3f4SLouis Dionne 15*0e34f3f4SLouis Dionne #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 16*0e34f3f4SLouis Dionne # pragma GCC system_header 17*0e34f3f4SLouis Dionne #endif 18*0e34f3f4SLouis Dionne 19*0e34f3f4SLouis Dionne // 20*0e34f3f4SLouis Dionne // This file implements base support for atomics on the platform. 21*0e34f3f4SLouis Dionne // 22*0e34f3f4SLouis Dionne // The following operations and types must be implemented (where _Atmc 23*0e34f3f4SLouis Dionne // is __cxx_atomic_base_impl for readability): 24*0e34f3f4SLouis Dionne // 25*0e34f3f4SLouis Dionne // clang-format off 26*0e34f3f4SLouis Dionne // 27*0e34f3f4SLouis Dionne // template <class _Tp> 28*0e34f3f4SLouis Dionne // struct __cxx_atomic_base_impl; 29*0e34f3f4SLouis Dionne // 30*0e34f3f4SLouis Dionne // #define __cxx_atomic_is_lock_free(__size) 31*0e34f3f4SLouis Dionne // 32*0e34f3f4SLouis Dionne // void __cxx_atomic_thread_fence(memory_order __order) noexcept; 33*0e34f3f4SLouis Dionne // void __cxx_atomic_signal_fence(memory_order __order) noexcept; 34*0e34f3f4SLouis Dionne // 35*0e34f3f4SLouis Dionne // template <class _Tp> 36*0e34f3f4SLouis Dionne // void __cxx_atomic_init(_Atmc<_Tp> volatile* __a, _Tp __val) noexcept; 37*0e34f3f4SLouis Dionne // template <class _Tp> 38*0e34f3f4SLouis Dionne // void __cxx_atomic_init(_Atmc<_Tp>* __a, _Tp __val) noexcept; 39*0e34f3f4SLouis Dionne // 40*0e34f3f4SLouis Dionne // template <class _Tp> 41*0e34f3f4SLouis Dionne // void __cxx_atomic_store(_Atmc<_Tp> volatile* __a, _Tp __val, memory_order __order) noexcept; 42*0e34f3f4SLouis Dionne // template <class _Tp> 43*0e34f3f4SLouis Dionne // void __cxx_atomic_store(_Atmc<_Tp>* __a, _Tp __val, memory_order __order) noexcept; 44*0e34f3f4SLouis Dionne // 45*0e34f3f4SLouis Dionne // template <class _Tp> 46*0e34f3f4SLouis Dionne // _Tp __cxx_atomic_load(_Atmc<_Tp> const volatile* __a, memory_order __order) noexcept; 47*0e34f3f4SLouis Dionne // template <class _Tp> 48*0e34f3f4SLouis Dionne // _Tp __cxx_atomic_load(_Atmc<_Tp> const* __a, memory_order __order) noexcept; 49*0e34f3f4SLouis Dionne // 50*0e34f3f4SLouis Dionne // template <class _Tp> 51*0e34f3f4SLouis Dionne // void __cxx_atomic_load_inplace(_Atmc<_Tp> const volatile* __a, _Tp* __dst, memory_order __order) noexcept; 52*0e34f3f4SLouis Dionne // template <class _Tp> 53*0e34f3f4SLouis Dionne // void __cxx_atomic_load_inplace(_Atmc<_Tp> const* __a, _Tp* __dst, memory_order __order) noexcept; 54*0e34f3f4SLouis Dionne // 55*0e34f3f4SLouis Dionne // template <class _Tp> 56*0e34f3f4SLouis Dionne // _Tp __cxx_atomic_exchange(_Atmc<_Tp> volatile* __a, _Tp __value, memory_order __order) noexcept; 57*0e34f3f4SLouis Dionne // template <class _Tp> 58*0e34f3f4SLouis Dionne // _Tp __cxx_atomic_exchange(_Atmc<_Tp>* __a, _Tp __value, memory_order __order) noexcept; 59*0e34f3f4SLouis Dionne // 60*0e34f3f4SLouis Dionne // template <class _Tp> 61*0e34f3f4SLouis Dionne // bool __cxx_atomic_compare_exchange_strong(_Atmc<_Tp> volatile* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) noexcept; 62*0e34f3f4SLouis Dionne // template <class _Tp> 63*0e34f3f4SLouis Dionne // bool __cxx_atomic_compare_exchange_strong(_Atmc<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) noexcept; 64*0e34f3f4SLouis Dionne // 65*0e34f3f4SLouis Dionne // template <class _Tp> 66*0e34f3f4SLouis Dionne // bool __cxx_atomic_compare_exchange_weak(_Atmc<_Tp> volatile* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) noexcept; 67*0e34f3f4SLouis Dionne // template <class _Tp> 68*0e34f3f4SLouis Dionne // bool __cxx_atomic_compare_exchange_weak(_Atmc<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) noexcept; 69*0e34f3f4SLouis Dionne // 70*0e34f3f4SLouis Dionne // template <class _Tp> 71*0e34f3f4SLouis Dionne // _Tp __cxx_atomic_fetch_add(_Atmc<_Tp> volatile* __a, _Tp __delta, memory_order __order) noexcept; 72*0e34f3f4SLouis Dionne // template <class _Tp> 73*0e34f3f4SLouis Dionne // _Tp __cxx_atomic_fetch_add(_Atmc<_Tp>* __a, _Tp __delta, memory_order __order) noexcept; 74*0e34f3f4SLouis Dionne // 75*0e34f3f4SLouis Dionne // template <class _Tp> 76*0e34f3f4SLouis Dionne // _Tp* __cxx_atomic_fetch_add(_Atmc<_Tp*> volatile* __a, ptrdiff_t __delta, memory_order __order) noexcept; 77*0e34f3f4SLouis Dionne // template <class _Tp> 78*0e34f3f4SLouis Dionne // _Tp* __cxx_atomic_fetch_add(_Atmc<_Tp*>* __a, ptrdiff_t __delta, memory_order __order) noexcept; 79*0e34f3f4SLouis Dionne // 80*0e34f3f4SLouis Dionne // template <class _Tp> 81*0e34f3f4SLouis Dionne // _Tp __cxx_atomic_fetch_sub(_Atmc<_Tp> volatile* __a, _Tp __delta, memory_order __order) noexcept; 82*0e34f3f4SLouis Dionne // template <class _Tp> 83*0e34f3f4SLouis Dionne // _Tp __cxx_atomic_fetch_sub(_Atmc<_Tp>* __a, _Tp __delta, memory_order __order) noexcept; 84*0e34f3f4SLouis Dionne // template <class _Tp> 85*0e34f3f4SLouis Dionne // _Tp* __cxx_atomic_fetch_sub(_Atmc<_Tp*> volatile* __a, ptrdiff_t __delta, memory_order __order) noexcept; 86*0e34f3f4SLouis Dionne // template <class _Tp> 87*0e34f3f4SLouis Dionne // _Tp* __cxx_atomic_fetch_sub(_Atmc<_Tp*>* __a, ptrdiff_t __delta, memory_order __order) noexcept; 88*0e34f3f4SLouis Dionne // 89*0e34f3f4SLouis Dionne // template <class _Tp> 90*0e34f3f4SLouis Dionne // _Tp __cxx_atomic_fetch_and(_Atmc<_Tp> volatile* __a, _Tp __pattern, memory_order __order) noexcept; 91*0e34f3f4SLouis Dionne // template <class _Tp> 92*0e34f3f4SLouis Dionne // _Tp __cxx_atomic_fetch_and(_Atmc<_Tp>* __a, _Tp __pattern, memory_order __order) noexcept; 93*0e34f3f4SLouis Dionne // 94*0e34f3f4SLouis Dionne // template <class _Tp> 95*0e34f3f4SLouis Dionne // _Tp __cxx_atomic_fetch_or(_Atmc<_Tp> volatile* __a, _Tp __pattern, memory_order __order) noexcept; 96*0e34f3f4SLouis Dionne // template <class _Tp> 97*0e34f3f4SLouis Dionne // _Tp __cxx_atomic_fetch_or(_Atmc<_Tp>* __a, _Tp __pattern, memory_order __order) noexcept; 98*0e34f3f4SLouis Dionne // template <class _Tp> 99*0e34f3f4SLouis Dionne // _Tp __cxx_atomic_fetch_xor(_Atmc<_Tp> volatile* __a, _Tp __pattern, memory_order __order) noexcept; 100*0e34f3f4SLouis Dionne // template <class _Tp> 101*0e34f3f4SLouis Dionne // _Tp __cxx_atomic_fetch_xor(_Atmc<_Tp>* __a, _Tp __pattern, memory_order __order) noexcept; 102*0e34f3f4SLouis Dionne // 103*0e34f3f4SLouis Dionne // clang-format on 104*0e34f3f4SLouis Dionne // 105*0e34f3f4SLouis Dionne 106*0e34f3f4SLouis Dionne #if _LIBCPP_HAS_GCC_ATOMIC_IMP 107*0e34f3f4SLouis Dionne # include <__atomic/support/gcc.h> 108*0e34f3f4SLouis Dionne #elif _LIBCPP_HAS_C_ATOMIC_IMP 109*0e34f3f4SLouis Dionne # include <__atomic/support/c11.h> 110*0e34f3f4SLouis Dionne #endif 111*0e34f3f4SLouis Dionne 112*0e34f3f4SLouis Dionne _LIBCPP_BEGIN_NAMESPACE_STD 113*0e34f3f4SLouis Dionne 114*0e34f3f4SLouis Dionne template <typename _Tp, typename _Base = __cxx_atomic_base_impl<_Tp> > 115*0e34f3f4SLouis Dionne struct __cxx_atomic_impl : public _Base { 116*0e34f3f4SLouis Dionne static_assert(is_trivially_copyable<_Tp>::value, "std::atomic<T> requires that 'T' be a trivially copyable type"); 117*0e34f3f4SLouis Dionne 118*0e34f3f4SLouis Dionne _LIBCPP_HIDE_FROM_ABI __cxx_atomic_impl() _NOEXCEPT = default; 119*0e34f3f4SLouis Dionne _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR explicit __cxx_atomic_impl(_Tp __value) _NOEXCEPT : _Base(__value) {} 120*0e34f3f4SLouis Dionne }; 121*0e34f3f4SLouis Dionne 122*0e34f3f4SLouis Dionne _LIBCPP_END_NAMESPACE_STD 123*0e34f3f4SLouis Dionne 124*0e34f3f4SLouis Dionne #endif // _LIBCPP___ATOMIC_SUPPORT_H 125