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