BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bsls_atomicoperations_all_all_clangintrinsics.h
Go to the documentation of this file.
1/// @file bsls_atomicoperations_all_all_clangintrinsics.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bsls_atomicoperations_all_all_clangintrinsics.h -*-C++-*-
8#ifndef INCLUDED_BSLS_ATOMICOPERATIONS_ALL_ALL_CLANGINTRINSICS
9#define INCLUDED_BSLS_ATOMICOPERATIONS_ALL_ALL_CLANGINTRINSICS
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bsls_atomicoperations_all_all_clangintrinsics bsls_atomicoperations_all_all_clangintrinsics
15/// @brief Implement atomic operations using clang `__c11_atomic_*` intrinsics
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bsls
19/// @{
20/// @addtogroup bsls_atomicoperations_all_all_clangintrinsics
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bsls_atomicoperations_all_all_clangintrinsics-purpose"> Purpose</a>
25/// * <a href="#bsls_atomicoperations_all_all_clangintrinsics-classes"> Classes </a>
26/// * <a href="#bsls_atomicoperations_all_all_clangintrinsics-description"> Description </a>
27///
28/// # Purpose {#bsls_atomicoperations_all_all_clangintrinsics-purpose}
29/// Implement atomic operations using clang `__c11_atomic_*` intrinsics
30///
31/// # Classes {#bsls_atomicoperations_all_all_clangintrinsics-classes}
32///
33/// - bsls::AtomicOperations_ALL_ALL_ClangIntrinsics:
34/// - clang `__c11_atomic_*` intrinsics
35///
36/// # Description {#bsls_atomicoperations_all_all_clangintrinsics-description}
37/// This component provides classes necessary to implement atomics
38/// in 32bit/64bit mode using clang compiler intrinsics. The classes are for
39/// private use only. See @ref bsls_atomicoperations and @ref bsls_atomic for the
40/// public interface to atomics.
41/// @}
42/** @} */
43/** @} */
44
45/** @addtogroup bsl
46 * @{
47 */
48/** @addtogroup bsls
49 * @{
50 */
51/** @addtogroup bsls_atomicoperations_all_all_clangintrinsics
52 * @{
53 */
54
55#include <bsls_atomicoperations_default.h>
56#include <bsls_platform.h>
57#include <bsls_types.h>
58
59#if defined(BSLS_PLATFORM_CMP_CLANG)
60#if __has_extension(c_atomic) || __has_extension(cxx_atomic)
61
62
63
64namespace bsls {
65
66struct AtomicOperations_ALL_ALL_ClangIntrinsics;
67typedef AtomicOperations_ALL_ALL_ClangIntrinsics AtomicOperations_Imp;
68
69 // ==================================================================
70 // struct Atomic_TypeTraits<AtomicOperations_ALL_ALL_ClangIntrinsics>
71 // ==================================================================
72
73template <>
74struct Atomic_TypeTraits<AtomicOperations_ALL_ALL_ClangIntrinsics>
75{
76 struct __attribute__((__aligned__(sizeof(int)))) Int
77 {
78 _Atomic(int) d_value;
79 };
80
81 struct __attribute__((__aligned__(sizeof(Types::Int64)))) Int64
82 {
83 _Atomic(Types::Int64) d_value;
84 };
85
86 struct __attribute__((__aligned__(sizeof(unsigned int)))) Uint
87 {
88 _Atomic(unsigned int) d_value;
89 };
90
91 struct __attribute__((__aligned__(sizeof(Types::Uint64)))) Uint64
92 {
93 _Atomic(Types::Uint64) d_value;
94 };
95
96 struct __attribute__((__aligned__(sizeof(void *)))) Pointer
97 {
98 _Atomic(void *) d_value;
99 };
100};
101
102 // ===============================================
103 // struct AtomicOperations_ALL_ALL_ClangIntrinsics
104 // ===============================================
105
106struct AtomicOperations_ALL_ALL_ClangIntrinsics
107 #ifdef BSLS_PLATFORM_CPU_64_BIT
108 : AtomicOperations_Default64<AtomicOperations_ALL_ALL_ClangIntrinsics>
109 #else
110 : AtomicOperations_Default32<AtomicOperations_ALL_ALL_ClangIntrinsics>
111 #endif
112{
113 typedef Atomic_TypeTraits<AtomicOperations_ALL_ALL_ClangIntrinsics>
114 AtomicTypes;
115
116 /// compile-time assert
117 typedef char AtomicInt_SizeCheck[sizeof(int) == 4 ? 1 : -1];
118
119 // *** atomic functions for int ***
120
121 static void initInt(AtomicTypes::Int *atomicInt, int value);
122
123 static int getInt(const AtomicTypes::Int *atomicInt);
124
125 static int getIntAcquire(const AtomicTypes::Int *atomicInt);
126
127 static int getIntRelaxed(const AtomicTypes::Int *atomicInt);
128
129 static void setInt(AtomicTypes::Int *atomicInt, int value);
130
131 static void setIntRelease(AtomicTypes::Int *atomicInt, int value);
132
133 static void setIntRelaxed(AtomicTypes::Int *atomicInt, int value);
134
135 static int swapInt(AtomicTypes::Int *atomicInt, int swapValue);
136
137 static int swapIntAcqRel(AtomicTypes::Int *atomicInt, int swapValue);
138
139 static int testAndSwapInt(AtomicTypes::Int *atomicInt,
140 int compareValue,
141 int swapValue);
142
143 static int testAndSwapIntAcqRel(AtomicTypes::Int *atomicInt,
144 int compareValue,
145 int swapValue);
146
147 static int addIntNv(AtomicTypes::Int *atomicInt, int value);
148
149 static int addIntNvAcqRel(AtomicTypes::Int *atomicInt, int value);
150
151 static int addIntNvRelaxed(AtomicTypes::Int *atomicInt, int value);
152
153 // *** atomic functions for Int64 ***
154
155 static void initInt64(AtomicTypes::Int64 *atomicInt, Types::Int64 value);
156
157 static Types::Int64 getInt64(const AtomicTypes::Int64 *atomicInt);
158
159 static Types::Int64 getInt64Acquire(const AtomicTypes::Int64 *atomicInt);
160
161 static Types::Int64 getInt64Relaxed(const AtomicTypes::Int64 *atomicInt);
162
163 static void setInt64(AtomicTypes::Int64 *atomicInt, Types::Int64 value);
164
165 static void setInt64Release(AtomicTypes::Int64 *atomicInt,
166 Types::Int64 value);
167
168 static void setInt64Relaxed(AtomicTypes::Int64 *atomicInt,
169 Types::Int64 value);
170
171 static Types::Int64 swapInt64(AtomicTypes::Int64 *atomicInt,
172 Types::Int64 swapValue);
173
174 static Types::Int64 swapInt64AcqRel(AtomicTypes::Int64 *atomicInt,
175 Types::Int64 swapValue);
176
177 static Types::Int64 testAndSwapInt64(AtomicTypes::Int64 *atomicInt,
178 Types::Int64 compareValue,
179 Types::Int64 swapValue);
180
181 static Types::Int64 testAndSwapInt64AcqRel(
182 AtomicTypes::Int64 *atomicInt,
183 Types::Int64 compareValue,
184 Types::Int64 swapValue);
185
186 static Types::Int64 addInt64Nv(AtomicTypes::Int64 *atomicInt,
187 Types::Int64 value);
188
189 static Types::Int64 addInt64NvAcqRel(AtomicTypes::Int64 *atomicInt,
190 Types::Int64 value);
191
192 static Types::Int64 addInt64NvRelaxed(AtomicTypes::Int64 *atomicInt,
193 Types::Int64 value);
194};
195
196// ============================================================================
197// INLINE FUNCTION DEFINITIONS
198// ============================================================================
199
200 // -----------------------------------------------
201 // struct AtomicOperations_ALL_ALL_ClangIntrinsics
202 // -----------------------------------------------
203
204inline
205void AtomicOperations_ALL_ALL_ClangIntrinsics::
206 initInt(AtomicTypes::Int *atomicInt, int value)
207{
208 __c11_atomic_init(&atomicInt->d_value, value);
209}
210
211inline
212int AtomicOperations_ALL_ALL_ClangIntrinsics::
213 getInt(const AtomicTypes::Int *atomicInt)
214{
215 return __c11_atomic_load(
216 const_cast<_Atomic(int) *>(&atomicInt->d_value),
217 __ATOMIC_SEQ_CST);
218}
219
220inline
221int AtomicOperations_ALL_ALL_ClangIntrinsics::
222 getIntAcquire(const AtomicTypes::Int *atomicInt)
223{
224 return __c11_atomic_load(
225 const_cast<_Atomic(int) *>(&atomicInt->d_value),
226 __ATOMIC_ACQUIRE);
227}
228
229inline
230int AtomicOperations_ALL_ALL_ClangIntrinsics::
231 getIntRelaxed(const AtomicTypes::Int *atomicInt)
232{
233 return __c11_atomic_load(
234 const_cast<_Atomic(int) *>(&atomicInt->d_value),
235 __ATOMIC_RELAXED);
236}
237
238inline
239void AtomicOperations_ALL_ALL_ClangIntrinsics::
240 setInt(AtomicTypes::Int *atomicInt, int value)
241{
242 __c11_atomic_store(&atomicInt->d_value, value, __ATOMIC_SEQ_CST);
243}
244
245inline
246void AtomicOperations_ALL_ALL_ClangIntrinsics::
247 setIntRelease(AtomicTypes::Int *atomicInt, int value)
248{
249 __c11_atomic_store(&atomicInt->d_value, value, __ATOMIC_RELEASE);
250}
251
252inline
253void AtomicOperations_ALL_ALL_ClangIntrinsics::
254 setIntRelaxed(AtomicTypes::Int *atomicInt, int value)
255{
256 __c11_atomic_store(&atomicInt->d_value, value, __ATOMIC_RELAXED);
257}
258
259inline
260int AtomicOperations_ALL_ALL_ClangIntrinsics::
261 swapInt(AtomicTypes::Int *atomicInt, int swapValue)
262{
263 return
264 __c11_atomic_exchange(&atomicInt->d_value, swapValue, __ATOMIC_SEQ_CST);
265}
266
267inline
268int AtomicOperations_ALL_ALL_ClangIntrinsics::
269 swapIntAcqRel(AtomicTypes::Int *atomicInt, int swapValue)
270{
271 return
272 __c11_atomic_exchange(&atomicInt->d_value, swapValue, __ATOMIC_ACQ_REL);
273}
274
275inline
276int AtomicOperations_ALL_ALL_ClangIntrinsics::
277 testAndSwapInt(AtomicTypes::Int *atomicInt,
278 int compareValue,
279 int swapValue)
280{
281 __c11_atomic_compare_exchange_strong(&atomicInt->d_value,
282 &compareValue,
283 swapValue,
284 __ATOMIC_SEQ_CST,
285 __ATOMIC_SEQ_CST);
286 return compareValue;
287}
288
289inline
290int AtomicOperations_ALL_ALL_ClangIntrinsics::
291 testAndSwapIntAcqRel(AtomicTypes::Int *atomicInt,
292 int compareValue,
293 int swapValue)
294{
295 __c11_atomic_compare_exchange_strong(&atomicInt->d_value,
296 &compareValue,
297 swapValue,
298 __ATOMIC_ACQ_REL,
299 __ATOMIC_ACQUIRE);
300 return compareValue;
301}
302
303inline
304int AtomicOperations_ALL_ALL_ClangIntrinsics::
305 addIntNv(AtomicTypes::Int *atomicInt, int value)
306{
307 return static_cast<unsigned>(__c11_atomic_fetch_add(&atomicInt->d_value,
308 value,
309 __ATOMIC_SEQ_CST))
310 + value;
311}
312
313inline
314int AtomicOperations_ALL_ALL_ClangIntrinsics::
315 addIntNvAcqRel(AtomicTypes::Int *atomicInt, int value)
316{
317 return static_cast<unsigned>(__c11_atomic_fetch_add(&atomicInt->d_value,
318 value,
319 __ATOMIC_ACQ_REL))
320 + value;
321}
322
323inline
324int AtomicOperations_ALL_ALL_ClangIntrinsics::
325 addIntNvRelaxed(AtomicTypes::Int *atomicInt, int value)
326{
327 return static_cast<unsigned>(__c11_atomic_fetch_add(&atomicInt->d_value,
328 value,
329 __ATOMIC_RELAXED))
330 + value;
331}
332
333inline
334void AtomicOperations_ALL_ALL_ClangIntrinsics::
335 initInt64(AtomicTypes::Int64 *atomicInt, Types::Int64 value)
336{
337 __c11_atomic_init(&atomicInt->d_value, value);
338}
339
340inline
341Types::Int64 AtomicOperations_ALL_ALL_ClangIntrinsics::
342 getInt64(const AtomicTypes::Int64 *atomicInt)
343{
344 return __c11_atomic_load(
345 const_cast<_Atomic(Types::Int64) *>(&atomicInt->d_value),
346 __ATOMIC_SEQ_CST);
347}
348
349inline
350Types::Int64 AtomicOperations_ALL_ALL_ClangIntrinsics::
351 getInt64Acquire(const AtomicTypes::Int64 *atomicInt)
352{
353 return __c11_atomic_load(
354 const_cast<_Atomic(Types::Int64) *>(&atomicInt->d_value),
355 __ATOMIC_ACQUIRE);
356}
357
358inline
359Types::Int64 AtomicOperations_ALL_ALL_ClangIntrinsics::
360 getInt64Relaxed(const AtomicTypes::Int64 *atomicInt)
361{
362 return __c11_atomic_load(
363 const_cast<_Atomic(Types::Int64) *>(&atomicInt->d_value),
364 __ATOMIC_RELAXED);
365}
366
367inline
368void AtomicOperations_ALL_ALL_ClangIntrinsics::
369 setInt64(AtomicTypes::Int64 *atomicInt, Types::Int64 value)
370{
371 __c11_atomic_store(&atomicInt->d_value, value, __ATOMIC_SEQ_CST);
372}
373
374inline
375void AtomicOperations_ALL_ALL_ClangIntrinsics::
376 setInt64Release(AtomicTypes::Int64 *atomicInt, Types::Int64 value)
377{
378 __c11_atomic_store(&atomicInt->d_value, value, __ATOMIC_RELEASE);
379}
380
381inline
382void AtomicOperations_ALL_ALL_ClangIntrinsics::
383 setInt64Relaxed(AtomicTypes::Int64 *atomicInt, Types::Int64 value)
384{
385 __c11_atomic_store(&atomicInt->d_value, value, __ATOMIC_RELAXED);
386}
387
388inline
389Types::Int64 AtomicOperations_ALL_ALL_ClangIntrinsics::
390 swapInt64(AtomicTypes::Int64 *atomicInt, Types::Int64 swapValue)
391{
392 return
393 __c11_atomic_exchange(&atomicInt->d_value,
394 swapValue,
395 __ATOMIC_SEQ_CST);
396}
397
398inline
399Types::Int64 AtomicOperations_ALL_ALL_ClangIntrinsics::
400 swapInt64AcqRel(AtomicTypes::Int64 *atomicInt, Types::Int64 swapValue)
401{
402 return
403 __c11_atomic_exchange(&atomicInt->d_value,
404 swapValue,
405 __ATOMIC_ACQ_REL);
406}
407
408inline
409Types::Int64 AtomicOperations_ALL_ALL_ClangIntrinsics::
410 testAndSwapInt64(AtomicTypes::Int64 *atomicInt,
411 Types::Int64 compareValue,
412 Types::Int64 swapValue)
413{
414 __c11_atomic_compare_exchange_strong(&atomicInt->d_value,
415 &compareValue,
416 swapValue,
417 __ATOMIC_SEQ_CST,
418 __ATOMIC_SEQ_CST);
419 return compareValue;
420}
421
422inline
423Types::Int64 AtomicOperations_ALL_ALL_ClangIntrinsics::
424 testAndSwapInt64AcqRel(AtomicTypes::Int64 *atomicInt,
425 Types::Int64 compareValue,
426 Types::Int64 swapValue)
427{
428 __c11_atomic_compare_exchange_strong(&atomicInt->d_value,
429 &compareValue,
430 swapValue,
431 __ATOMIC_ACQ_REL,
432 __ATOMIC_ACQUIRE);
433 return compareValue;
434}
435
436inline
437Types::Int64 AtomicOperations_ALL_ALL_ClangIntrinsics::
438 addInt64Nv(AtomicTypes::Int64 *atomicInt, Types::Int64 value)
439{
440 return static_cast<Types::Uint64>(
441 __c11_atomic_fetch_add(&atomicInt->d_value,
442 value,
443 __ATOMIC_SEQ_CST))
444 + value;
445}
446
447inline
448Types::Int64 AtomicOperations_ALL_ALL_ClangIntrinsics::
449 addInt64NvAcqRel(AtomicTypes::Int64 *atomicInt, Types::Int64 value)
450{
451 return static_cast<Types::Uint64>(
452 __c11_atomic_fetch_add(&atomicInt->d_value,
453 value,
454 __ATOMIC_ACQ_REL))
455 + value;
456}
457
458inline
459Types::Int64 AtomicOperations_ALL_ALL_ClangIntrinsics::
460 addInt64NvRelaxed(AtomicTypes::Int64 *atomicInt, Types::Int64 value)
461{
462 return static_cast<Types::Uint64>(
463 __c11_atomic_fetch_add(&atomicInt->d_value,
464 value,
465 __ATOMIC_RELAXED))
466 + value;
467}
468
469} // close package namespace
470
471
472
473#endif // __has_extension(c_atomic) || __has_extension(cxx_atomic)
474
475#endif // BSLS_PLATFORM_CMP_CLANG
476
477#endif
478
479// ----------------------------------------------------------------------------
480// Copyright 2015 Bloomberg Finance L.P.
481//
482// Licensed under the Apache License, Version 2.0 (the "License");
483// you may not use this file except in compliance with the License.
484// You may obtain a copy of the License at
485//
486// http://www.apache.org/licenses/LICENSE-2.0
487//
488// Unless required by applicable law or agreed to in writing, software
489// distributed under the License is distributed on an "AS IS" BASIS,
490// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
491// See the License for the specific language governing permissions and
492// limitations under the License.
493// ----------------------------- END-OF-FILE ----------------------------------
494
495/** @} */
496/** @} */
497/** @} */
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
Definition bdlt_iso8601util.h:691
unsigned long long Uint64
Definition bsls_types.h:137
long long Int64
Definition bsls_types.h:132