Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/libcxx/include/__atomic/support/c11.h
213799 views
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-exception
6
//
7
//===----------------------------------------------------------------------===//
8
9
#ifndef _LIBCPP___ATOMIC_SUPPORT_C11_H
10
#define _LIBCPP___ATOMIC_SUPPORT_C11_H
11
12
#include <__atomic/memory_order.h>
13
#include <__config>
14
#include <__cstddef/ptrdiff_t.h>
15
#include <__memory/addressof.h>
16
#include <__type_traits/remove_const.h>
17
18
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
19
# pragma GCC system_header
20
#endif
21
22
//
23
// This file implements support for C11-style atomics
24
//
25
26
_LIBCPP_BEGIN_NAMESPACE_STD
27
28
template <typename _Tp>
29
struct __cxx_atomic_base_impl {
30
_LIBCPP_HIDE_FROM_ABI
31
#ifndef _LIBCPP_CXX03_LANG
32
__cxx_atomic_base_impl() _NOEXCEPT = default;
33
#else
34
__cxx_atomic_base_impl() _NOEXCEPT : __a_value() {
35
}
36
#endif // _LIBCPP_CXX03_LANG
37
_LIBCPP_CONSTEXPR explicit __cxx_atomic_base_impl(_Tp __value) _NOEXCEPT : __a_value(__value) {}
38
_Atomic(_Tp) __a_value;
39
};
40
41
#define __cxx_atomic_is_lock_free(__s) __c11_atomic_is_lock_free(__s)
42
43
_LIBCPP_HIDE_FROM_ABI inline void __cxx_atomic_thread_fence(memory_order __order) _NOEXCEPT {
44
__c11_atomic_thread_fence(static_cast<__memory_order_underlying_t>(__order));
45
}
46
47
_LIBCPP_HIDE_FROM_ABI inline void __cxx_atomic_signal_fence(memory_order __order) _NOEXCEPT {
48
__c11_atomic_signal_fence(static_cast<__memory_order_underlying_t>(__order));
49
}
50
51
template <class _Tp>
52
_LIBCPP_HIDE_FROM_ABI void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __val) _NOEXCEPT {
53
__c11_atomic_init(std::addressof(__a->__a_value), __val);
54
}
55
template <class _Tp>
56
_LIBCPP_HIDE_FROM_ABI void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp>* __a, _Tp __val) _NOEXCEPT {
57
__c11_atomic_init(std::addressof(__a->__a_value), __val);
58
}
59
60
template <class _Tp>
61
_LIBCPP_HIDE_FROM_ABI void
62
__cxx_atomic_store(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __val, memory_order __order) _NOEXCEPT {
63
__c11_atomic_store(std::addressof(__a->__a_value), __val, static_cast<__memory_order_underlying_t>(__order));
64
}
65
template <class _Tp>
66
_LIBCPP_HIDE_FROM_ABI void
67
__cxx_atomic_store(__cxx_atomic_base_impl<_Tp>* __a, _Tp __val, memory_order __order) _NOEXCEPT {
68
__c11_atomic_store(std::addressof(__a->__a_value), __val, static_cast<__memory_order_underlying_t>(__order));
69
}
70
71
template <class _Tp>
72
_LIBCPP_HIDE_FROM_ABI _Tp
73
__cxx_atomic_load(__cxx_atomic_base_impl<_Tp> const volatile* __a, memory_order __order) _NOEXCEPT {
74
using __ptr_type = __remove_const_t<decltype(__a->__a_value)>*;
75
return __c11_atomic_load(
76
const_cast<__ptr_type>(std::addressof(__a->__a_value)), static_cast<__memory_order_underlying_t>(__order));
77
}
78
template <class _Tp>
79
_LIBCPP_HIDE_FROM_ABI _Tp __cxx_atomic_load(__cxx_atomic_base_impl<_Tp> const* __a, memory_order __order) _NOEXCEPT {
80
using __ptr_type = __remove_const_t<decltype(__a->__a_value)>*;
81
return __c11_atomic_load(
82
const_cast<__ptr_type>(std::addressof(__a->__a_value)), static_cast<__memory_order_underlying_t>(__order));
83
}
84
85
template <class _Tp>
86
_LIBCPP_HIDE_FROM_ABI void
87
__cxx_atomic_load_inplace(__cxx_atomic_base_impl<_Tp> const volatile* __a, _Tp* __dst, memory_order __order) _NOEXCEPT {
88
using __ptr_type = __remove_const_t<decltype(__a->__a_value)>*;
89
*__dst = __c11_atomic_load(
90
const_cast<__ptr_type>(std::addressof(__a->__a_value)), static_cast<__memory_order_underlying_t>(__order));
91
}
92
template <class _Tp>
93
_LIBCPP_HIDE_FROM_ABI void
94
__cxx_atomic_load_inplace(__cxx_atomic_base_impl<_Tp> const* __a, _Tp* __dst, memory_order __order) _NOEXCEPT {
95
using __ptr_type = __remove_const_t<decltype(__a->__a_value)>*;
96
*__dst = __c11_atomic_load(
97
const_cast<__ptr_type>(std::addressof(__a->__a_value)), static_cast<__memory_order_underlying_t>(__order));
98
}
99
100
template <class _Tp>
101
_LIBCPP_HIDE_FROM_ABI _Tp
102
__cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __value, memory_order __order) _NOEXCEPT {
103
return __c11_atomic_exchange(
104
std::addressof(__a->__a_value), __value, static_cast<__memory_order_underlying_t>(__order));
105
}
106
template <class _Tp>
107
_LIBCPP_HIDE_FROM_ABI _Tp
108
__cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp>* __a, _Tp __value, memory_order __order) _NOEXCEPT {
109
return __c11_atomic_exchange(
110
std::addressof(__a->__a_value), __value, static_cast<__memory_order_underlying_t>(__order));
111
}
112
113
_LIBCPP_HIDE_FROM_ABI inline _LIBCPP_CONSTEXPR memory_order __to_failure_order(memory_order __order) {
114
// Avoid switch statement to make this a constexpr.
115
return __order == memory_order_release
116
? memory_order_relaxed
117
: (__order == memory_order_acq_rel ? memory_order_acquire : __order);
118
}
119
120
template <class _Tp>
121
_LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_compare_exchange_strong(
122
__cxx_atomic_base_impl<_Tp> volatile* __a,
123
_Tp* __expected,
124
_Tp __value,
125
memory_order __success,
126
memory_order __failure) _NOEXCEPT {
127
return __c11_atomic_compare_exchange_strong(
128
std::addressof(__a->__a_value),
129
__expected,
130
__value,
131
static_cast<__memory_order_underlying_t>(__success),
132
static_cast<__memory_order_underlying_t>(__to_failure_order(__failure)));
133
}
134
template <class _Tp>
135
_LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_compare_exchange_strong(
136
__cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure)
137
_NOEXCEPT {
138
return __c11_atomic_compare_exchange_strong(
139
std::addressof(__a->__a_value),
140
__expected,
141
__value,
142
static_cast<__memory_order_underlying_t>(__success),
143
static_cast<__memory_order_underlying_t>(__to_failure_order(__failure)));
144
}
145
146
template <class _Tp>
147
_LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_compare_exchange_weak(
148
__cxx_atomic_base_impl<_Tp> volatile* __a,
149
_Tp* __expected,
150
_Tp __value,
151
memory_order __success,
152
memory_order __failure) _NOEXCEPT {
153
return __c11_atomic_compare_exchange_weak(
154
std::addressof(__a->__a_value),
155
__expected,
156
__value,
157
static_cast<__memory_order_underlying_t>(__success),
158
static_cast<__memory_order_underlying_t>(__to_failure_order(__failure)));
159
}
160
template <class _Tp>
161
_LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_compare_exchange_weak(
162
__cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure)
163
_NOEXCEPT {
164
return __c11_atomic_compare_exchange_weak(
165
std::addressof(__a->__a_value),
166
__expected,
167
__value,
168
static_cast<__memory_order_underlying_t>(__success),
169
static_cast<__memory_order_underlying_t>(__to_failure_order(__failure)));
170
}
171
172
template <class _Tp>
173
_LIBCPP_HIDE_FROM_ABI _Tp
174
__cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __delta, memory_order __order) _NOEXCEPT {
175
return __c11_atomic_fetch_add(
176
std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order));
177
}
178
template <class _Tp>
179
_LIBCPP_HIDE_FROM_ABI _Tp
180
__cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp>* __a, _Tp __delta, memory_order __order) _NOEXCEPT {
181
return __c11_atomic_fetch_add(
182
std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order));
183
}
184
185
template <class _Tp>
186
_LIBCPP_HIDE_FROM_ABI _Tp*
187
__cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp*> volatile* __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT {
188
return __c11_atomic_fetch_add(
189
std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order));
190
}
191
template <class _Tp>
192
_LIBCPP_HIDE_FROM_ABI _Tp*
193
__cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp*>* __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT {
194
return __c11_atomic_fetch_add(
195
std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order));
196
}
197
198
template <class _Tp>
199
_LIBCPP_HIDE_FROM_ABI _Tp
200
__cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __delta, memory_order __order) _NOEXCEPT {
201
return __c11_atomic_fetch_sub(
202
std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order));
203
}
204
template <class _Tp>
205
_LIBCPP_HIDE_FROM_ABI _Tp
206
__cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp>* __a, _Tp __delta, memory_order __order) _NOEXCEPT {
207
return __c11_atomic_fetch_sub(
208
std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order));
209
}
210
template <class _Tp>
211
_LIBCPP_HIDE_FROM_ABI _Tp*
212
__cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp*> volatile* __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT {
213
return __c11_atomic_fetch_sub(
214
std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order));
215
}
216
template <class _Tp>
217
_LIBCPP_HIDE_FROM_ABI _Tp*
218
__cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp*>* __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT {
219
return __c11_atomic_fetch_sub(
220
std::addressof(__a->__a_value), __delta, static_cast<__memory_order_underlying_t>(__order));
221
}
222
223
template <class _Tp>
224
_LIBCPP_HIDE_FROM_ABI _Tp
225
__cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
226
return __c11_atomic_fetch_and(
227
std::addressof(__a->__a_value), __pattern, static_cast<__memory_order_underlying_t>(__order));
228
}
229
template <class _Tp>
230
_LIBCPP_HIDE_FROM_ABI _Tp
231
__cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
232
return __c11_atomic_fetch_and(
233
std::addressof(__a->__a_value), __pattern, static_cast<__memory_order_underlying_t>(__order));
234
}
235
236
template <class _Tp>
237
_LIBCPP_HIDE_FROM_ABI _Tp
238
__cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
239
return __c11_atomic_fetch_or(
240
std::addressof(__a->__a_value), __pattern, static_cast<__memory_order_underlying_t>(__order));
241
}
242
template <class _Tp>
243
_LIBCPP_HIDE_FROM_ABI _Tp
244
__cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
245
return __c11_atomic_fetch_or(
246
std::addressof(__a->__a_value), __pattern, static_cast<__memory_order_underlying_t>(__order));
247
}
248
249
template <class _Tp>
250
_LIBCPP_HIDE_FROM_ABI _Tp
251
__cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
252
return __c11_atomic_fetch_xor(
253
std::addressof(__a->__a_value), __pattern, static_cast<__memory_order_underlying_t>(__order));
254
}
255
template <class _Tp>
256
_LIBCPP_HIDE_FROM_ABI _Tp
257
__cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
258
return __c11_atomic_fetch_xor(
259
std::addressof(__a->__a_value), __pattern, static_cast<__memory_order_underlying_t>(__order));
260
}
261
262
_LIBCPP_END_NAMESPACE_STD
263
264
#endif // _LIBCPP___ATOMIC_SUPPORT_C11_H
265
266