xref: /aosp_15_r20/external/libcxx/src/include/atomic_support.h (revision 58b9f456b02922dfdb1fad8a988d5fd8765ecb80)
1*58b9f456SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===////
2*58b9f456SAndroid Build Coastguard Worker //
3*58b9f456SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*58b9f456SAndroid Build Coastguard Worker //
5*58b9f456SAndroid Build Coastguard Worker // This file is dual licensed under the MIT and the University of Illinois Open
6*58b9f456SAndroid Build Coastguard Worker // Source Licenses. See LICENSE.TXT for details.
7*58b9f456SAndroid Build Coastguard Worker //
8*58b9f456SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===////
9*58b9f456SAndroid Build Coastguard Worker 
10*58b9f456SAndroid Build Coastguard Worker #ifndef ATOMIC_SUPPORT_H
11*58b9f456SAndroid Build Coastguard Worker #define ATOMIC_SUPPORT_H
12*58b9f456SAndroid Build Coastguard Worker 
13*58b9f456SAndroid Build Coastguard Worker #include "__config"
14*58b9f456SAndroid Build Coastguard Worker #include "memory" // for __libcpp_relaxed_load
15*58b9f456SAndroid Build Coastguard Worker 
16*58b9f456SAndroid Build Coastguard Worker #if defined(__clang__) && __has_builtin(__atomic_load_n)             \
17*58b9f456SAndroid Build Coastguard Worker                        && __has_builtin(__atomic_store_n)            \
18*58b9f456SAndroid Build Coastguard Worker                        && __has_builtin(__atomic_add_fetch)          \
19*58b9f456SAndroid Build Coastguard Worker                        && __has_builtin(__atomic_exchange_n)         \
20*58b9f456SAndroid Build Coastguard Worker                        && __has_builtin(__atomic_compare_exchange_n) \
21*58b9f456SAndroid Build Coastguard Worker                        && defined(__ATOMIC_RELAXED)                  \
22*58b9f456SAndroid Build Coastguard Worker                        && defined(__ATOMIC_CONSUME)                  \
23*58b9f456SAndroid Build Coastguard Worker                        && defined(__ATOMIC_ACQUIRE)                  \
24*58b9f456SAndroid Build Coastguard Worker                        && defined(__ATOMIC_RELEASE)                  \
25*58b9f456SAndroid Build Coastguard Worker                        && defined(__ATOMIC_ACQ_REL)                  \
26*58b9f456SAndroid Build Coastguard Worker                        && defined(__ATOMIC_SEQ_CST)
27*58b9f456SAndroid Build Coastguard Worker #   define _LIBCPP_HAS_ATOMIC_BUILTINS
28*58b9f456SAndroid Build Coastguard Worker #elif !defined(__clang__) && defined(_GNUC_VER) && _GNUC_VER >= 407
29*58b9f456SAndroid Build Coastguard Worker #   define _LIBCPP_HAS_ATOMIC_BUILTINS
30*58b9f456SAndroid Build Coastguard Worker #endif
31*58b9f456SAndroid Build Coastguard Worker 
32*58b9f456SAndroid Build Coastguard Worker #if !defined(_LIBCPP_HAS_ATOMIC_BUILTINS) && !defined(_LIBCPP_HAS_NO_THREADS)
33*58b9f456SAndroid Build Coastguard Worker # if defined(_LIBCPP_WARNING)
34*58b9f456SAndroid Build Coastguard Worker     _LIBCPP_WARNING("Building libc++ without __atomic builtins is unsupported")
35*58b9f456SAndroid Build Coastguard Worker # else
36*58b9f456SAndroid Build Coastguard Worker #   warning Building libc++ without __atomic builtins is unsupported
37*58b9f456SAndroid Build Coastguard Worker # endif
38*58b9f456SAndroid Build Coastguard Worker #endif
39*58b9f456SAndroid Build Coastguard Worker 
40*58b9f456SAndroid Build Coastguard Worker _LIBCPP_BEGIN_NAMESPACE_STD
41*58b9f456SAndroid Build Coastguard Worker 
42*58b9f456SAndroid Build Coastguard Worker namespace {
43*58b9f456SAndroid Build Coastguard Worker 
44*58b9f456SAndroid Build Coastguard Worker #if defined(_LIBCPP_HAS_ATOMIC_BUILTINS) && !defined(_LIBCPP_HAS_NO_THREADS)
45*58b9f456SAndroid Build Coastguard Worker 
46*58b9f456SAndroid Build Coastguard Worker enum __libcpp_atomic_order {
47*58b9f456SAndroid Build Coastguard Worker     _AO_Relaxed = __ATOMIC_RELAXED,
48*58b9f456SAndroid Build Coastguard Worker     _AO_Consume = __ATOMIC_CONSUME,
49*58b9f456SAndroid Build Coastguard Worker     _AO_Acquire = __ATOMIC_ACQUIRE,
50*58b9f456SAndroid Build Coastguard Worker     _AO_Release = __ATOMIC_RELEASE,
51*58b9f456SAndroid Build Coastguard Worker     _AO_Acq_Rel = __ATOMIC_ACQ_REL,
52*58b9f456SAndroid Build Coastguard Worker     _AO_Seq     = __ATOMIC_SEQ_CST
53*58b9f456SAndroid Build Coastguard Worker };
54*58b9f456SAndroid Build Coastguard Worker 
55*58b9f456SAndroid Build Coastguard Worker template <class _ValueType, class _FromType>
56*58b9f456SAndroid Build Coastguard Worker inline _LIBCPP_INLINE_VISIBILITY
57*58b9f456SAndroid Build Coastguard Worker void __libcpp_atomic_store(_ValueType* __dest, _FromType __val,
58*58b9f456SAndroid Build Coastguard Worker                            int __order = _AO_Seq)
59*58b9f456SAndroid Build Coastguard Worker {
60*58b9f456SAndroid Build Coastguard Worker     __atomic_store_n(__dest, __val, __order);
61*58b9f456SAndroid Build Coastguard Worker }
62*58b9f456SAndroid Build Coastguard Worker 
63*58b9f456SAndroid Build Coastguard Worker template <class _ValueType, class _FromType>
64*58b9f456SAndroid Build Coastguard Worker inline _LIBCPP_INLINE_VISIBILITY
__libcpp_relaxed_store(_ValueType * __dest,_FromType __val)65*58b9f456SAndroid Build Coastguard Worker void __libcpp_relaxed_store(_ValueType* __dest, _FromType __val)
66*58b9f456SAndroid Build Coastguard Worker {
67*58b9f456SAndroid Build Coastguard Worker     __atomic_store_n(__dest, __val, _AO_Relaxed);
68*58b9f456SAndroid Build Coastguard Worker }
69*58b9f456SAndroid Build Coastguard Worker 
70*58b9f456SAndroid Build Coastguard Worker template <class _ValueType>
71*58b9f456SAndroid Build Coastguard Worker inline _LIBCPP_INLINE_VISIBILITY
72*58b9f456SAndroid Build Coastguard Worker _ValueType __libcpp_atomic_load(_ValueType const* __val,
73*58b9f456SAndroid Build Coastguard Worker                                 int __order = _AO_Seq)
74*58b9f456SAndroid Build Coastguard Worker {
75*58b9f456SAndroid Build Coastguard Worker     return __atomic_load_n(__val, __order);
76*58b9f456SAndroid Build Coastguard Worker }
77*58b9f456SAndroid Build Coastguard Worker 
78*58b9f456SAndroid Build Coastguard Worker template <class _ValueType, class _AddType>
79*58b9f456SAndroid Build Coastguard Worker inline _LIBCPP_INLINE_VISIBILITY
80*58b9f456SAndroid Build Coastguard Worker _ValueType __libcpp_atomic_add(_ValueType* __val, _AddType __a,
81*58b9f456SAndroid Build Coastguard Worker                                int __order = _AO_Seq)
82*58b9f456SAndroid Build Coastguard Worker {
83*58b9f456SAndroid Build Coastguard Worker     return __atomic_add_fetch(__val, __a, __order);
84*58b9f456SAndroid Build Coastguard Worker }
85*58b9f456SAndroid Build Coastguard Worker 
86*58b9f456SAndroid Build Coastguard Worker template <class _ValueType>
87*58b9f456SAndroid Build Coastguard Worker inline _LIBCPP_INLINE_VISIBILITY
88*58b9f456SAndroid Build Coastguard Worker _ValueType __libcpp_atomic_exchange(_ValueType* __target,
89*58b9f456SAndroid Build Coastguard Worker                                     _ValueType __value, int __order = _AO_Seq)
90*58b9f456SAndroid Build Coastguard Worker {
91*58b9f456SAndroid Build Coastguard Worker     return __atomic_exchange_n(__target, __value, __order);
92*58b9f456SAndroid Build Coastguard Worker }
93*58b9f456SAndroid Build Coastguard Worker 
94*58b9f456SAndroid Build Coastguard Worker template <class _ValueType>
95*58b9f456SAndroid Build Coastguard Worker inline _LIBCPP_INLINE_VISIBILITY
96*58b9f456SAndroid Build Coastguard Worker bool __libcpp_atomic_compare_exchange(_ValueType* __val,
97*58b9f456SAndroid Build Coastguard Worker     _ValueType* __expected, _ValueType __after,
98*58b9f456SAndroid Build Coastguard Worker     int __success_order = _AO_Seq,
99*58b9f456SAndroid Build Coastguard Worker     int __fail_order = _AO_Seq)
100*58b9f456SAndroid Build Coastguard Worker {
101*58b9f456SAndroid Build Coastguard Worker     return __atomic_compare_exchange_n(__val, __expected, __after, true,
102*58b9f456SAndroid Build Coastguard Worker                                        __success_order, __fail_order);
103*58b9f456SAndroid Build Coastguard Worker }
104*58b9f456SAndroid Build Coastguard Worker 
105*58b9f456SAndroid Build Coastguard Worker #else // _LIBCPP_HAS_NO_THREADS
106*58b9f456SAndroid Build Coastguard Worker 
107*58b9f456SAndroid Build Coastguard Worker enum __libcpp_atomic_order {
108*58b9f456SAndroid Build Coastguard Worker     _AO_Relaxed,
109*58b9f456SAndroid Build Coastguard Worker     _AO_Consume,
110*58b9f456SAndroid Build Coastguard Worker     _AO_Acquire,
111*58b9f456SAndroid Build Coastguard Worker     _AO_Release,
112*58b9f456SAndroid Build Coastguard Worker     _AO_Acq_Rel,
113*58b9f456SAndroid Build Coastguard Worker     _AO_Seq
114*58b9f456SAndroid Build Coastguard Worker };
115*58b9f456SAndroid Build Coastguard Worker 
116*58b9f456SAndroid Build Coastguard Worker template <class _ValueType, class _FromType>
117*58b9f456SAndroid Build Coastguard Worker inline _LIBCPP_INLINE_VISIBILITY
118*58b9f456SAndroid Build Coastguard Worker void __libcpp_atomic_store(_ValueType* __dest, _FromType __val,
119*58b9f456SAndroid Build Coastguard Worker                            int = 0)
120*58b9f456SAndroid Build Coastguard Worker {
121*58b9f456SAndroid Build Coastguard Worker     *__dest = __val;
122*58b9f456SAndroid Build Coastguard Worker }
123*58b9f456SAndroid Build Coastguard Worker 
124*58b9f456SAndroid Build Coastguard Worker template <class _ValueType, class _FromType>
125*58b9f456SAndroid Build Coastguard Worker inline _LIBCPP_INLINE_VISIBILITY
126*58b9f456SAndroid Build Coastguard Worker void __libcpp_relaxed_store(_ValueType* __dest, _FromType __val)
127*58b9f456SAndroid Build Coastguard Worker {
128*58b9f456SAndroid Build Coastguard Worker     *__dest = __val;
129*58b9f456SAndroid Build Coastguard Worker }
130*58b9f456SAndroid Build Coastguard Worker 
131*58b9f456SAndroid Build Coastguard Worker template <class _ValueType>
132*58b9f456SAndroid Build Coastguard Worker inline _LIBCPP_INLINE_VISIBILITY
133*58b9f456SAndroid Build Coastguard Worker _ValueType __libcpp_atomic_load(_ValueType const* __val,
134*58b9f456SAndroid Build Coastguard Worker                                 int = 0)
135*58b9f456SAndroid Build Coastguard Worker {
136*58b9f456SAndroid Build Coastguard Worker     return *__val;
137*58b9f456SAndroid Build Coastguard Worker }
138*58b9f456SAndroid Build Coastguard Worker 
139*58b9f456SAndroid Build Coastguard Worker template <class _ValueType, class _AddType>
140*58b9f456SAndroid Build Coastguard Worker inline _LIBCPP_INLINE_VISIBILITY
141*58b9f456SAndroid Build Coastguard Worker _ValueType __libcpp_atomic_add(_ValueType* __val, _AddType __a,
142*58b9f456SAndroid Build Coastguard Worker                                int = 0)
143*58b9f456SAndroid Build Coastguard Worker {
144*58b9f456SAndroid Build Coastguard Worker     return *__val += __a;
145*58b9f456SAndroid Build Coastguard Worker }
146*58b9f456SAndroid Build Coastguard Worker 
147*58b9f456SAndroid Build Coastguard Worker template <class _ValueType>
148*58b9f456SAndroid Build Coastguard Worker inline _LIBCPP_INLINE_VISIBILITY
149*58b9f456SAndroid Build Coastguard Worker _ValueType __libcpp_atomic_exchange(_ValueType* __target,
150*58b9f456SAndroid Build Coastguard Worker                                     _ValueType __value, int __order = _AO_Seq)
151*58b9f456SAndroid Build Coastguard Worker {
152*58b9f456SAndroid Build Coastguard Worker     _ValueType old = *__target;
153*58b9f456SAndroid Build Coastguard Worker     *__target = __value;
154*58b9f456SAndroid Build Coastguard Worker     return old;
155*58b9f456SAndroid Build Coastguard Worker }
156*58b9f456SAndroid Build Coastguard Worker 
157*58b9f456SAndroid Build Coastguard Worker template <class _ValueType>
158*58b9f456SAndroid Build Coastguard Worker inline _LIBCPP_INLINE_VISIBILITY
159*58b9f456SAndroid Build Coastguard Worker bool __libcpp_atomic_compare_exchange(_ValueType* __val,
160*58b9f456SAndroid Build Coastguard Worker     _ValueType* __expected, _ValueType __after,
161*58b9f456SAndroid Build Coastguard Worker     int = 0, int = 0)
162*58b9f456SAndroid Build Coastguard Worker {
163*58b9f456SAndroid Build Coastguard Worker     if (*__val == *__expected) {
164*58b9f456SAndroid Build Coastguard Worker         *__val = __after;
165*58b9f456SAndroid Build Coastguard Worker         return true;
166*58b9f456SAndroid Build Coastguard Worker     }
167*58b9f456SAndroid Build Coastguard Worker     *__expected = *__val;
168*58b9f456SAndroid Build Coastguard Worker     return false;
169*58b9f456SAndroid Build Coastguard Worker }
170*58b9f456SAndroid Build Coastguard Worker 
171*58b9f456SAndroid Build Coastguard Worker #endif // _LIBCPP_HAS_NO_THREADS
172*58b9f456SAndroid Build Coastguard Worker 
173*58b9f456SAndroid Build Coastguard Worker } // end namespace
174*58b9f456SAndroid Build Coastguard Worker 
175*58b9f456SAndroid Build Coastguard Worker _LIBCPP_END_NAMESPACE_STD
176*58b9f456SAndroid Build Coastguard Worker 
177*58b9f456SAndroid Build Coastguard Worker #endif // ATOMIC_SUPPORT_H
178