xref: /llvm-project/libcxx/include/__atomic/support.h (revision 0e34f3f4968d8d32a64e26777541f939deb2274c)
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