BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bsls_atomicoperations_default.h
Go to the documentation of this file.
1/// @file bsls_atomicoperations_default.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bsls_atomicoperations_default.h -*-C++-*-
8#ifndef INCLUDED_BSLS_ATOMICOPERATIONS_DEFAULT
9#define INCLUDED_BSLS_ATOMICOPERATIONS_DEFAULT
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bsls_atomicoperations_default bsls_atomicoperations_default
15/// @brief Provide default implementation for atomic operations.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bsls
19/// @{
20/// @addtogroup bsls_atomicoperations_default
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bsls_atomicoperations_default-purpose"> Purpose</a>
25/// * <a href="#bsls_atomicoperations_default-classes"> Classes </a>
26/// * <a href="#bsls_atomicoperations_default-description"> Description </a>
27/// * <a href="#bsls_atomicoperations_default-design-of-components-providing-atomic-operations"> Design of Components Providing Atomic Operations </a>
28/// * <a href="#bsls_atomicoperations_default-component-and-class-hierarchy-for-atomic-operations"> Component and Class Hierarchy for Atomic Operations </a>
29/// * <a href="#bsls_atomicoperations_default-usage"> Usage </a>
30///
31/// # Purpose {#bsls_atomicoperations_default-purpose}
32/// Provide default implementation for atomic operations.
33///
34/// # Classes {#bsls_atomicoperations_default-classes}
35///
36/// - bsls::AtomicOperations_DefaultInt: defaults for atomic operations on int
37/// - bsls::AtomicOperations_DefaultInt64: defaults for Int64
38/// - bsls::AtomicOperations_DefaultPointer32: defaults for 32-bit pointer
39/// - bsls::AtomicOperations_DefaultPointer64: defaults for 64-bit pointer
40/// - bsls::AtomicOperations_Default32: all atomics for a generic 32-bit platform
41/// - bsls::AtomicOperations_Default64: all atomics for a generic 64-bit platform
42///
43/// # Description {#bsls_atomicoperations_default-description}
44/// [**PRIVATE**] This component provides classes having default
45/// implementations of atomic operations independent of a any specific platform.
46/// The purpose of these classes is for them to be combined with
47/// platform-specific implementations of atomic operations to form a full set of
48/// atomic operations.
49///
50/// [**WARNING**] This component should not be used directly by client code. It
51/// is subject to change without warning.
52///
53/// The implementation of atomic operations splits the set of operations into
54/// two groups: essential (core) operations and non-essential operations. The
55/// essential core operations, such as `getInt`, `setInt`, `swapInt`,
56/// `testAndSwapInt`, must be implemented on every target platform. The
57/// non-essential operations, such as `incrementInt`, `decrementInt`, have
58/// default implementations written in terms of the core operations (though the
59/// default implementation may be overridden for a target platform).
60///
61/// This component provides the default implementations for non-essential atomic
62/// operations. For the essential core operations, it provides only function
63/// prototypes without any concrete implementation. The concrete implementation
64/// for core operations on each platform are provided by a platform-specific
65/// implementation component.
66///
67/// ## Design of Components Providing Atomic Operations {#bsls_atomicoperations_default-design-of-components-providing-atomic-operations}
68///
69///
70/// There are about 70 different atomic operations we provide in this atomics
71/// library. Only a fraction of these operations (about 10-15) have
72/// implementations specific to a target platform. These are the core atomic
73/// operations. Other operations have implementations that are independent of
74/// the platform, and are defined in terms of those core operations.
75///
76/// A primary design objective for this implementation of atomic operations is
77/// to provide a single common implementation for the platform-independent,
78/// non-essential, atomic operations. This way, each platform-specific
79/// implementation of atomics needs to provide only the 10-15 core operations,
80/// and may obtain the remaining 60 atomic operations automatically from this
81/// default implementation component.
82///
83/// The implementation technique used to achieve this goal is called the
84/// Curiously Recurring Template Pattern, or CRTP.
85///
86/// In the CRTP a derived class inherits from the base class, but the base class
87/// is parameterized with the derived class template parameter. In the context
88/// of atomic operations, the CRTP allows the non-essential base class methods
89/// to be accessed through the platform specific derived class, while the
90/// template parameterization of the base class allows the implementations for
91/// platform-independent (non-essential) operations in the base class to be
92/// implemented in terms of the core operations implemented in the
93/// platform-specific derived class.
94///
95/// Let's illustrate this idea with an example. The base class, `AtomicsBase`,
96/// will provide an implementation for a single non-essential atomic operation,
97/// `getIntAcquire`, whose implementation delegates to the platform-specific
98/// implementation of another, (core) atomic operation, `getInt`:
99/// @code
100/// template <class IMP>
101/// struct AtomicsBase<IMP>
102/// {
103/// // static
104/// // int getInt(int volatile *);
105/// // Implemented in the derived class, 'IMP'.
106///
107/// static
108/// int getIntAcquire(int volatile *obj)
109/// // Platform-independent; implemented in terms of the derived
110/// // 'getInt'.
111/// {
112/// return IMP::getInt(obj);
113/// }
114/// };
115/// @endcode
116/// Now we define a platform-specific implementation of the atomics class for
117/// the x86 platform providing the core operation `getInt`:
118/// @code
119/// struct AtomicsX86 : AtomicsBase<AtomicsX86>
120/// {
121/// static
122/// int getInt(int volatile *obj)
123/// // Platform-specific implementation.
124/// {
125/// // ...whatever is necessary for this atomic operation on x86
126/// }
127/// };
128/// @endcode
129/// To get an idea what the effective interface and the implementation of the
130/// `AtomicsX86` class looks like, we can flatten the hierarchy of `AtomicsX86`
131/// and remove the `AtomicsBase` class from the picture, as if we implemented
132/// `AtomicsX86` without the help of `AtomicsBase`. The effective interface and
133/// the implementation of `AtomicsX86` is as follows:
134/// @code
135/// struct AtomicsX86Flattened
136/// {
137/// static
138/// int getInt(int volatile *obj)
139/// // Platform-specific implementation.
140/// {
141/// // ...whatever is necessary for this atomic operation on x86
142/// }
143///
144/// static
145/// int getIntAcquire(int volatile *obj)
146/// // Platform-independent; implemented in terms of 'getInt'.
147/// {
148/// return getInt(obj);
149/// }
150/// };
151/// @endcode
152/// The above code shows that the design goal is achieved: Platform-independent
153/// atomic operations are factored out into easily reusable `AtomicsBase` which,
154/// when combined with platform-specific atomic operations, produces the
155/// complete set of atomic operations for a given target-platform.
156///
157/// ## Component and Class Hierarchy for Atomic Operations {#bsls_atomicoperations_default-component-and-class-hierarchy-for-atomic-operations}
158///
159///
160/// This section describes the hierarchy of components and types that implement
161/// atomic operations. Below is the list of base classes providing default
162/// implementations of platform-independent, non-essential atomic operations.
163/// Atomic operations for different data types are factored into their own base
164/// classes:
165/// * bsls::AtomicOperations_DefaultInt - provides atomic operations for int
166/// * bsls::AtomicOperations_DefaultInt64 - for Int64
167/// * bsls::AtomicOperations_DefaultPointer32 - for 32-bit pointer
168/// * bsls::AtomicOperations_DefaultPointer64 - for 64-bit pointer
169///
170/// The platform-specific core atomic operations are left unimplemented in these
171/// default implementation classes. The implementations for those operations
172/// have to be provided by a platform-specific derived classes.
173///
174/// The above default implementation classes are combined (using inheritance)
175/// into more specialized base classes that provide nearly complete set of
176/// atomic operations for a generic platform:
177///
178/// * bsls::AtomicOperations_Default32 - a set of atomic operations for a
179/// generic 32-bit platform
180/// * bsls::AtomicOperations_Default64 - a set of atomic operations for a
181/// generic 64-bit platform
182///
183/// This is how the generic platform base classes are composed:
184/// * bsls::AtomicOperations_Default32 : AtomicOperations_DefaultInt,
185/// AtomicOperations_DefaultInt64, AtomicOperations_DefaultPointer32
186/// * bsls::AtomicOperations_Default64 : AtomicOperations_DefaultInt,
187/// AtomicOperations_DefaultInt64, AtomicOperations_DefaultPointer64
188///
189/// A typical derived class implementing platform-specific atomic operations
190/// needs to derive from either `bsls::AtomicOperations_Default32` (if the
191/// platform is 32-bit) or `bsls::AtomicOperations_Default64` (if the platform
192/// is 64-bit).
193///
194/// For example, let's take the X86_64 platform with GCC compiler. The derived
195/// class for this platform, `bsls::AtomicOperations_X64_ALL_GCC`, inherits from
196/// `bsls::AtomicOperations_Default64` and implements all platform-specific
197/// atomic operations:
198/// @code
199/// struct bsls::AtomicOperations_X64_ALL_GCC
200/// : bsls::AtomicOperations_Default64<bsls::AtomicOperations_X64_ALL_GCC>
201/// {
202/// typedef bsls::Atomic_TypeTraits<bsls::AtomicOperations_X64_ALL_GCC>
203/// AtomicTypes; // for explanation of atomic type traits see below
204///
205/// // *** atomic functions for int ***
206/// static int getInt(const AtomicTypes::Int *atomicInt);
207/// static void setInt(AtomicTypes::Int *atomicInt, int value);
208/// // ...
209///
210/// // *** atomic functions for Int64 ***
211/// static bsls::Types::Int64 getInt64(
212/// AtomicTypes::Int64 const *atomicInt);
213/// static void setInt64(
214/// AtomicTypes::Int64 *atomicInt, bsls::Types::Int64 value);
215/// // ...
216/// };
217/// @endcode
218/// A derived class can also override some default atomic implementations from a
219/// base class. For example, `bsls::AtomicOperations_X64_ALL_GCC` can provide a
220/// better implementation for `getIntAcquire` than the one provided by the
221/// `bsls::AtomicOperations_DefaultInt` base class. So
222/// `bsls::AtomicOperations_X64_ALL_GCC` implements its own `getIntAcquire` with
223/// the same signature as in the base class:
224/// @code
225/// struct bsls::AtomicOperations_X64_ALL_GCC
226/// : bsls::AtomicOperations_Default64<bsls::AtomicOperations_X64_ALL_GCC>
227/// {
228/// // *** atomic functions for int ***
229/// static int getIntAcquire(const AtomicTypes::Int *atomicInt);
230/// // ...
231/// };
232/// @endcode
233/// Technically speaking, this is not overriding, but hiding the respective
234/// methods of the base class, but for our purpose, it works as if the methods
235/// were overridden.
236///
237/// Platform-specific atomic operations for other platforms are implemented in a
238/// similar manner. Here is a conceptual diagram of relationships between
239/// classes that provide the default atomic operations and platform-specific
240/// atomic operations (the bsls::AtomicOperations_ prefix is omitted for
241/// brevity):
242/// @code
243/// DefaultPointer32 DefaultInt DefaultInt64 DefaultPointer64
244/// ^ ^ ^ ^
245/// | | | |
246/// +---------------+ +-------------------+ +--------------+
247/// | | | |
248/// Default32 Default64
249/// ^ ^
250/// | |
251/// X86_ALL_GCC --+ +-- X64_ALL_GCC
252/// | |
253/// X86_WIN_MSVC --+ +-- X64_WIN_MSVC
254/// | |
255/// POWERPC32_AIX_XLC --+ +-- POWERPC64_AIX_XLC
256/// | |
257/// SPARC32_SUN_CC --+ +-- SPARC64_SUN_CC
258/// |
259/// +-- IA64_HP_ACC
260/// @endcode
261///
262/// The last part of the implementation is the atomic type traits class. We
263/// need a special representation for atomic primitive types to ensure
264/// conformance to size and alignment requirements for each platform. For
265/// example, the atomic primitive type for `int` is usually a 4-byte aligned
266/// `volatile int`. Since the alignment is specified differently for different
267/// platforms and compilers, the atomic type traits class allows us to abstract
268/// the rest of the implementation of atomics from those differences.
269///
270/// This default implementation component provides only a declaration of a
271/// generic atomic type traits class:
272/// @code
273/// template <class IMP>
274/// struct bsls::Atomic_TypeTraits;
275/// @endcode
276/// Each platform-specific implementation has to provide its own specialization
277/// of the type traits class. For example, the specialization for the x86_64
278/// platform defined by the `bsls::AtomicOperations_X64_ALL_GCC` class might
279/// look like:
280/// @code
281/// template <>
282/// struct bsls::Atomic_TypeTraits<bsls::AtomicOperations_X64_ALL_GCC>
283/// {
284/// struct Int
285/// {
286/// volatile int d_value __attribute__((__aligned__(sizeof(int))));
287/// };
288///
289/// struct Int64
290/// {
291/// volatile bsls::Types::Int64 d_value
292/// __attribute__((__aligned__(sizeof(bsls::Types::Int64))));
293/// };
294///
295/// struct Pointer
296/// {
297/// void * volatile d_value
298/// __attribute__((__aligned__(sizeof(void *))));
299/// };
300/// };
301/// @endcode
302///
303/// ## Usage {#bsls_atomicoperations_default-usage}
304///
305///
306/// This component is a private implementation type of @ref bsls_atomicoperations ;
307/// see @ref bsls_atomicoperations for a usage example.
308/// @}
309/** @} */
310/** @} */
311
312/** @addtogroup bsl
313 * @{
314 */
315/** @addtogroup bsls
316 * @{
317 */
318/** @addtogroup bsls_atomicoperations_default
319 * @{
320 */
321
322#include <bsls_types.h>
323
324
325
326namespace bsls {
327
328 // ==================================
329 // struct AtomicOperations_DefaultInt
330 // ==================================
331
332template <class IMP>
334
335/// This class provides default implementations of non-essential atomic
336/// operations for the 32-bit integer type independent on any specific
337/// platform. It also provides prototypes for the atomic operations for the
338/// 32-bit integer type that have to be implemented separately for each
339/// specific platform. These platform-independent and platform-specific
340/// atomic operations together form a full set of atomic operations for the
341/// 32-bit integer type.
342template <class IMP>
344{
345 public:
346 // PUBLIC TYPES
348
349 private:
350 // The following are signatures for the core atomics interface, the
351 // implementation of which must be provided by a derived platform-specific
352 // 'IMP' class.
353
354 private:
355 // NOT IMPLEMENTED
356
357 /// Atomically add to the specified `atomicInt` the specified `value`
358 /// and return the resulting value, providing the sequential consistency
359 /// memory ordering guarantee.
360 static int addIntNv(typename AtomicTypes::Int *atomicInt, int value);
361
362 /// Atomically retrieve the value of the specified `atomicInt`,
363 /// providing the sequential consistency memory ordering guarantee.
364 static int getInt(typename AtomicTypes::Int const *atomicInt);
365
366 /// Atomically set the value of the specified `atomicInt` to the
367 /// specified `value`, providing the sequential consistency memory
368 /// ordering guarantee.
369 static void setInt(typename AtomicTypes::Int *atomicInt, int value);
370
371 /// Atomically set the value of the specified `atomicInt` to the
372 /// specified `swapValue`, and return its previous value, providing the
373 /// sequential consistency memory ordering guarantee.
374 static int swapInt(typename AtomicTypes::Int *atomicInt, int swapValue);
375
376 /// Conditionally set the value of the specified `atomicInt` to the
377 /// specified `swapValue` if and only if the value of `atomicInt` equals
378 /// the value of the specified `compareValue`, and return the initial
379 /// value of `atomicInt`, providing the sequential consistency memory
380 /// ordering guarantee. The whole operation is performed atomically.
381 static int testAndSwapInt(typename AtomicTypes::Int *atomicInt,
382 int compareValue,
383 int swapValue);
384
385 public:
386 // CLASS METHODS
387
388 /// Atomically retrieve the value of the specified `atomicInt`,
389 /// providing the acquire memory ordering guarantee.
390 static int getIntAcquire(typename AtomicTypes::Int const *atomicInt);
391
392 /// Atomically retrieve the value of the specified `atomicInt`, without
393 /// providing any memory ordering guarantees.
394 static int getIntRelaxed(typename AtomicTypes::Int const *atomicInt);
395
396 /// Initialize the specified `atomicInt` and set its value to the
397 /// optionally specified `initialValue`.
398 static void initInt(typename AtomicTypes::Int *atomicInt,
399 int initialValue = 0);
400
401 /// Atomically set the value of the specified `atomicInt` to the
402 /// specified `value`, without providing any memory ordering guarantees.
403 static void setIntRelaxed(typename AtomicTypes::Int *atomicInt, int value);
404
405 /// Atomically set the value of the specified `atomicInt` to the
406 /// specified `value`, providing the release memory ordering guarantee.
407 static void setIntRelease(typename AtomicTypes::Int *atomicInt, int value);
408
409 /// Atomically set the value of the specified `atomicInt` to the
410 /// specified `swapValue`, and return its previous value, providing the
411 /// acquire/release memory ordering guarantee.
412 static int swapIntAcqRel(typename AtomicTypes::Int *atomicInt,
413 int swapValue);
414
415 /// Conditionally set the value of the specified `atomicInt` to the
416 /// specified `swapValue` if and only if the value of `atomicInt` equals
417 /// the value of the specified `compareValue`, and return the initial
418 /// value of `atomicInt`, providing the acquire/release memory ordering
419 /// guarantee. The whole operation is performed atomically.
420 static int testAndSwapIntAcqRel(typename AtomicTypes::Int *atomicInt,
421 int compareValue,
422 int swapValue);
423
424 // Arithmetic
425
426 /// Atomically add to the specified `atomicInt` the specified `value`,
427 /// providing the sequential consistency memory ordering guarantee.
428 static void addInt(typename AtomicTypes::Int *atomicInt, int value);
429
430 /// Atomically add to the specified `atomicInt` the specified `value`,
431 /// providing the acquire/release memory ordering guarantee.
432 static void addIntAcqRel(typename AtomicTypes::Int *atomicInt, int value);
433
434 /// Atomically add to the specified `atomicInt` the specified `value`,
435 /// without providing any memory ordering guarantees.
436 static void addIntRelaxed(typename AtomicTypes::Int *atomicInt, int value);
437
438 /// Atomically add to the specified `atomicInt` the specified `value`
439 /// and return the resulting value, providing the acquire/release memory
440 /// ordering guarantee.
441 static int addIntNvAcqRel(typename AtomicTypes::Int *atomicInt, int value);
442
443 /// Atomically add to the specified `atomicInt` the specified `value`
444 /// and return the resulting value, without providing any memory
445 /// ordering guarantees.
446 static int addIntNvRelaxed(typename AtomicTypes::Int *atomicInt,
447 int value);
448
449 /// Atomically decrement the value of the specified `atomicInt` by 1,
450 /// providing the sequential consistency memory ordering guarantee.
451 static void decrementInt(typename AtomicTypes::Int *atomicInt);
452
453 /// Atomically decrement the value of the specified `atomicInt` by 1,
454 /// providing the acquire/release memory ordering guarantee.
455 static void decrementIntAcqRel(typename AtomicTypes::Int *atomicInt);
456
457 /// Atomically decrement the specified `atomicInt` by 1 and return the
458 /// resulting value, providing the sequential consistency memory
459 /// ordering guarantee.
460 static int decrementIntNv(typename AtomicTypes::Int *atomicInt);
461
462 /// Atomically decrement the specified `atomicInt` by 1 and return the
463 /// resulting value, providing the acquire/release memory ordering
464 /// guarantee.
465 static int decrementIntNvAcqRel(typename AtomicTypes::Int *atomicInt);
466
467 /// Atomically increment the value of the specified `atomicInt` by 1,
468 /// providing the sequential consistency memory ordering guarantee.
469 static void incrementInt(typename AtomicTypes::Int *atomicInt);
470
471 /// Atomically increment the value of the specified `atomicInt` by 1,
472 /// providing the acquire/release memory ordering guarantee.
473 static void incrementIntAcqRel(typename AtomicTypes::Int *atomicInt);
474
475 /// Atomically increment the specified `atomicInt` by 1 and return the
476 /// resulting value, providing the sequential consistency memory
477 /// ordering guarantee.
478 static int incrementIntNv(typename AtomicTypes::Int *atomicInt);
479
480 /// Atomically increment the specified `atomicInt` by 1 and return the
481 /// resulting value, providing the acquire/release memory ordering
482 /// guarantee.
483 static int incrementIntNvAcqRel(typename AtomicTypes::Int *atomicInt);
484
485 /// Atomically subtract from the specified `atomicInt` the specified
486 /// `value` and return the resulting value, providing the sequential
487 /// consistency memory ordering guarantee.
488 static int subtractIntNv(typename AtomicTypes::Int *atomicInt, int value);
489
490 /// Atomically subtract from the specified `atomicInt` the specified
491 /// `value` and return the resulting value, providing the
492 /// acquire/release memory ordering guarantee.
493 static int subtractIntNvAcqRel(typename AtomicTypes::Int *atomicInt,
494 int value);
495
496 /// Atomically subtract from the specified `atomicInt` the specified
497 /// `value` and return the resulting value, without providing any memory
498 /// ordering guarantees.
499 static int subtractIntNvRelaxed(typename AtomicTypes::Int *atomicInt,
500 int value);
501};
502
503 // ====================================
504 // struct AtomicOperations_DefaultInt64
505 // ====================================
506
507/// This class provides default implementations of non-essential atomic
508/// operations for the 64-bit integer type independent on any specific
509/// platform. It also provides prototypes for the atomic operations for the
510/// 64-bit integer type that have to be implemented separately for each
511/// specific platform. These platform-independent and platform-specific
512/// atomic operations together form a full set of atomic operations for the
513/// 64-bit integer type.
514template <class IMP>
516{
517 public:
518 // PUBLIC TYPES
520
521 private:
522 // The following are signatures for the core atomics interface, the
523 // implementation of which must be provided by a derived platform-specific
524 // 'IMP' class.
525
526 private:
527 // NOT IMPLEMENTED
528
529 /// Atomically add to the specified `atomicInt` the specified `value`
530 /// and return the resulting value, providing the sequential consistency
531 /// memory ordering guarantee.
532 static Types::Int64 addInt64Nv(typename AtomicTypes::Int64 *atomicInt,
533 Types::Int64 value);
534
535 /// Atomically retrieve the value of the specified `atomicInt`,
536 /// providing the sequential consistency memory ordering guarantee.
537 static Types::Int64 getInt64(typename AtomicTypes::Int64 const *atomicInt);
538
539 /// Atomically set the value of the specified `atomicInt` to the
540 /// specified `value`, providing the sequential consistency memory
541 /// ordering guarantee.
542 static void setInt64(typename AtomicTypes::Int64 *atomicInt,
543 Types::Int64 value);
544
545 /// Atomically set the value of the specified `atomicInt` to the
546 /// specified `swapValue` and return its previous value, providing the
547 /// sequential consistency memory ordering guarantee.
548 static Types::Int64 swapInt64(typename AtomicTypes::Int64 *atomicInt,
549 Types::Int64 swapValue);
550
551 /// Conditionally set the value of the specified `atomicInt` to the
552 /// specified `swapValue` if and only if the value of `atomicInt` equals
553 /// the value of the specified `compareValue`, and return the initial
554 /// value of `atomicInt`, providing the sequential consistency memory
555 /// ordering guarantee. The whole operation is performed atomically.
556 static Types::Int64 testAndSwapInt64(
557 typename AtomicTypes::Int64 *atomicInt,
558 Types::Int64 compareValue,
559 Types::Int64 swapValue);
560
561 public:
562 // CLASS METHODS
563
564 /// Atomically retrieve the value of the specified `atomicInt`,
565 /// providing the acquire memory ordering guarantee.
567 typename AtomicTypes::Int64 const *atomicInt);
568
569 /// Atomically retrieve the value of the specified `atomicInt`, without
570 /// providing any memory ordering guarantees.
572 typename AtomicTypes::Int64 const *atomicInt);
573
574 /// Initialize the specified `atomicInt` and set its value to the
575 /// optionally specified `initialValue`.
576 static void initInt64(typename AtomicTypes::Int64 *atomicInt,
577 Types::Int64 initialValue = 0);
578
579 /// Atomically set the value of the specified `atomicInt` to the
580 /// specified `value`, without providing any memory ordering guarantees.
581 static void setInt64Relaxed(typename AtomicTypes::Int64 *atomicInt,
582 Types::Int64 value);
583
584 /// Atomically set the value of the specified `atomicInt` to the
585 /// specified `value`, providing the release memory ordering guarantee.
586 static void setInt64Release(typename AtomicTypes::Int64 *atomicInt,
587 Types::Int64 value);
588
589 /// Atomically set the value of the specified `atomicInt` to the
590 /// specified `swapValue` and return its previous value, providing the
591 /// acquire/release memory ordering guarantee.
593 typename AtomicTypes::Int64 *atomicInt,
594 Types::Int64 swapValue);
595
596 /// Conditionally set the value of the specified `atomicInt` to the
597 /// specified `swapValue` if and only if the value of `atomicInt` equals
598 /// the value of the specified `compareValue`, and return the initial
599 /// value of `atomicInt`, providing the sequential consistency memory
600 /// ordering guarantee. The whole operation is performed atomically.
602 typename AtomicTypes::Int64 *atomicInt,
603 Types::Int64 compareValue,
604 Types::Int64 swapValue);
605
606 // Arithmetic
607
608 /// Atomically add to the specified `atomicInt` the specified `value`,
609 /// providing the sequential consistency memory ordering guarantee.
610 static void addInt64(typename AtomicTypes::Int64 *atomicInt,
611 Types::Int64 value);
612
613 /// Atomically add to the specified `atomicInt` the specified `value`,
614 /// providing the acquire/release memory ordering guarantee.
615 static void addInt64AcqRel(typename AtomicTypes::Int64 *atomicInt,
616 Types::Int64 value);
617
618 /// Atomically add to the specified `atomicInt` the specified `value`,
619 /// without providing any memory ordering guarantees.
620 static void addInt64Relaxed(typename AtomicTypes::Int64 *atomicInt,
621 Types::Int64 value);
622
623 /// Atomically add to the specified `atomicInt` the specified `value`
624 /// and return the resulting value, providing the acquire/release memory
625 /// ordering guarantee.
627 typename AtomicTypes::Int64 *atomicInt,
628 Types::Int64 value);
629
630 /// Atomically add to the specified `atomicInt` the specified `value`
631 /// and return the resulting value, without providing any memory
632 /// ordering guarantees.
634 typename AtomicTypes::Int64 *atomicInt,
635 Types::Int64 value);
636
637 /// Atomically decrement the specified `atomicInt` by 1, providing the
638 /// sequential consistency memory ordering guarantee.
639 static void decrementInt64(typename AtomicTypes::Int64 *atomicInt);
640
641 /// Atomically decrement the specified `atomicInt` by 1, providing the
642 /// acquire/release memory ordering guarantee.
643 static void decrementInt64AcqRel(typename AtomicTypes::Int64 *atomicInt);
644
645 /// Atomically decrement the specified `atomicInt` by 1 and return the
646 /// resulting value, providing the sequential consistency memory
647 /// ordering guarantee.
649 typename AtomicTypes::Int64 *atomicInt);
650
651 /// Atomically decrement the specified `atomicInt` by 1 and return the
652 /// resulting value, providing the acquire/release memory ordering
653 /// guarantee.
655 typename AtomicTypes::Int64 *atomicInt);
656
657 /// Atomically increment the value of the specified `atomicInt` by 1,
658 /// providing the sequential consistency memory ordering guarantee.
659 static void incrementInt64(typename AtomicTypes::Int64 *atomicInt);
660
661 /// Atomically increment the value of the specified `atomicInt` by 1,
662 /// providing the acquire/release memory ordering guarantee.
663 static void incrementInt64AcqRel(typename AtomicTypes::Int64 *atomicInt);
664
665 /// Atomically increment the specified `atomicInt` by 1 and return the
666 /// resulting value, providing the sequential consistency memory
667 /// ordering guarantee.
669 typename AtomicTypes::Int64 *atomicInt);
670
671 /// Atomically increment the specified `atomicInt` by 1 and return the
672 /// resulting value, providing the acquire/release memory ordering
673 /// guarantee.
675 typename AtomicTypes::Int64 *atomicInt);
676
677 /// Atomically subtract from the specified `atomicInt` the specified
678 /// `value` and return the resulting value, providing the sequential
679 /// consistency memory ordering guarantee.
680 static Types::Int64 subtractInt64Nv(typename AtomicTypes::Int64 *atomicInt,
681 Types::Int64 value);
682
683 /// Atomically subtract from the specified `atomicInt` the specified
684 /// `value` and return the resulting value, providing the
685 /// acquire/release memory ordering guarantee.
687 typename AtomicTypes::Int64 *atomicInt,
688 Types::Int64 value);
689
690 /// Atomically subtract from the specified `atomicInt` the specified
691 /// `value` and return the resulting value, without providing any memory
692 /// ordering guarantees.
694 typename AtomicTypes::Int64 *atomicInt,
695 Types::Int64 value);
696};
697
698 // ===================================
699 // struct AtomicOperations_DefaultUint
700 // ===================================
701
702template <class IMP>
703struct Atomic_TypeTraits;
704
705/// This class provides default implementations of non-essential atomic
706/// operations for the 32-bit unsigned integer type independent on any
707/// specific platform. It also provides prototypes for the atomic
708/// operations for the 32-bit unsigned integer type that have to be
709/// implemented separately for each specific platform. These
710/// platform-independent and platform-specific atomic operations together
711/// form a full set of atomic operations for the 32-bit unsigned integer
712/// type.
713///
714///
715/// \note Note that `AtomicOperations_DefaultUint` is implemented in terms of the
716/// following atomic operations on the integer type that must be provided by
717/// the `IMP` template parameter.
718/// @code
719/// static int getInt(typename AtomicTypes::Int const *atomicInt);
720/// static int getIntRelaxed(typename AtomicTypes::Int const *atomicInt);
721/// static int getIntAcquire(typename AtomicTypes::Int const *atomicInt);
722/// static void setInt(typename AtomicTypes::Int *atomicInt, int value);
723/// static void setIntRelaxed(typename AtomicTypes::Int *atomicInt,
724/// int value);
725/// static void setIntRelease(typename AtomicTypes::Int *atomicInt,
726/// int value);
727/// static int swapInt(typename AtomicTypes::Int *atomicInt,
728/// int swapValue);
729/// static int swapIntAcqRel(typename AtomicTypes::Int *atomicInt,
730/// int swapValue);
731/// static int testAndSwapInt(typename AtomicTypes::Int *atomicInt,
732/// int compareValue,
733/// int swapValue);
734/// static int testAndSwapIntAcqRel(typename AtomicTypes::Int *atomicInt,
735/// int compareValue,
736/// int swapValue);
737/// @endcode
738template <class IMP>
740{
741 public:
742 // PUBLIC TYPES
744
745 // CLASS METHODS
746
747 /// Atomically retrieve the value of the specified `atomicUint`,
748 /// providing the sequential consistency memory ordering guarantee.
749 static unsigned int getUint(typename AtomicTypes::Uint const *atomicUint);
750
751 /// Atomically retrieve the value of the specified `atomicUint`,
752 /// providing the acquire memory ordering guarantee.
753 static unsigned int getUintAcquire(
754 typename AtomicTypes::Uint const *atomicUint);
755
756 /// Atomically retrieve the value of the specified `atomicUint`, without
757 /// providing any memory ordering guarantees.
758 static unsigned int getUintRelaxed(
759 typename AtomicTypes::Uint const *atomicUint);
760
761 /// Initialize the specified `atomicUint` and set its value to the
762 /// optionally specified `initialValue`.
763 static void initUint(typename AtomicTypes::Uint *atomicUint,
764 unsigned int initialValue = 0);
765
766 /// Atomically set the value of the specified `atomicUint` to the
767 /// specified `value`, providing the sequential consistency memory
768 /// ordering guarantee.
769 static void setUint(typename AtomicTypes::Uint *atomicUint,
770 unsigned int value);
771
772 /// Atomically set the value of the specified `atomicUint` to the
773 /// specified `value`, without providing any memory ordering guarantees.
774 static void setUintRelaxed(typename AtomicTypes::Uint *atomicUint,
775 unsigned int value);
776
777 /// Atomically set the value of the specified `atomicUint` to the
778 /// specified `value`, providing the release memory ordering guarantee.
779 static void setUintRelease(typename AtomicTypes::Uint *atomicUint,
780 unsigned int value);
781
782 /// Atomically set the value of the specified `atomicUint` to the
783 /// specified `swapValue`, and return its previous value, providing the
784 /// sequential consistency memory ordering guarantee.
785 static unsigned int swapUint(typename AtomicTypes::Uint *atomicUint,
786 unsigned int swapValue);
787
788 /// Atomically set the value of the specified `atomicUint` to the
789 /// specified `swapValue`, and return its previous value, providing the
790 /// acquire/release memory ordering guarantee.
791 static unsigned int swapUintAcqRel(typename AtomicTypes::Uint *atomicUint,
792 unsigned int swapValue);
793
794 /// Conditionally set the value of the specified `atomicUint` to the
795 /// specified `swapValue` if and only if the value of `atomicUint`
796 /// equals the value of the specified `compareValue`, and return the
797 /// initial value of `atomicUint`, providing the sequential consistency
798 /// memory ordering guarantee. The whole operation is performed
799 /// atomically.
800 static unsigned int testAndSwapUint(
801 typename AtomicTypes::Uint *atomicUint,
802 unsigned int compareValue,
803 unsigned int swapValue);
804
805 /// Conditionally set the value of the specified `atomicUint` to the
806 /// specified `swapValue` if and only if the value of `atomicInt` equals
807 /// the value of the specified `compareValue`, and return the initial
808 /// value of `atomicUint`, providing the acquire/release memory ordering
809 /// guarantee. The whole operation is performed atomically.
810 static unsigned int testAndSwapUintAcqRel(
811 typename AtomicTypes::Uint *atomicUint,
812 unsigned int compareValue,
813 unsigned int swapValue);
814
815 // Arithmetic
816
817 /// Atomically add to the specified `atomicUint` the specified `value`,
818 /// providing the sequential consistency memory ordering guarantee.
819 static void addUint(typename AtomicTypes::Uint *atomicUint,
820 unsigned int value);
821
822 /// Atomically add to the specified `atomicUint` the specified `value`,
823 /// providing the acquire/release memory ordering guarantee.
824 static void addUintAcqRel(typename AtomicTypes::Uint *atomicUint,
825 unsigned int value);
826
827 /// Atomically add to the specified `atomicUint` the specified `value`,
828 /// without providing any memory ordering guarantees.
829 static void addUintRelaxed(typename AtomicTypes::Uint *atomicUint,
830 unsigned int value);
831
832 /// Atomically add to the specified `atomicUint` the specified `value`
833 /// and return the resulting value, providing the sequential consistency
834 /// memory ordering guarantee.
835 static unsigned int addUintNv(typename AtomicTypes::Uint *atomicUint,
836 unsigned int value);
837
838 /// Atomically add to the specified `atomicUint` the specified `value`
839 /// and return the resulting value, providing the acquire/release memory
840 /// ordering guarantee.
841 static unsigned int addUintNvAcqRel(typename AtomicTypes::Uint *atomicUint,
842 unsigned int value);
843
844 /// Atomically add to the specified `atomicUint` the specified `value`
845 /// and return the resulting value, without providing any memory
846 /// ordering guarantees.
847 static unsigned int addUintNvRelaxed(
848 typename AtomicTypes::Uint *atomicUint,
849 unsigned int value);
850
851 /// Atomically decrement the value of the specified `atomicUint` by 1,
852 /// providing the sequential consistency memory ordering guarantee.
853 static void decrementUint(typename AtomicTypes::Uint *atomicUint);
854
855 /// Atomically decrement the value of the specified `atomicUint` by 1,
856 /// providing the acquire/release memory ordering guarantee.
857 static void decrementUintAcqRel(typename AtomicTypes::Uint *atomicUint);
858
859 /// Atomically decrement the specified `atomicUint` by 1 and return the
860 /// resulting value, providing the sequential consistency memory
861 /// ordering guarantee.
862 static unsigned int decrementUintNv(
863 typename AtomicTypes::Uint *atomicUint);
864
865 /// Atomically decrement the specified `atomicUint` by 1 and return the
866 /// resulting value, providing the acquire/release memory ordering
867 /// guarantee.
868 static unsigned int decrementUintNvAcqRel(
869 typename AtomicTypes::Uint *atomicUint);
870
871 /// Atomically increment the value of the specified `atomicUint` by 1,
872 /// providing the sequential consistency memory ordering guarantee.
873 static void incrementUint(typename AtomicTypes::Uint *atomicUint);
874
875 /// Atomically increment the value of the specified `atomicUint` by 1,
876 /// providing the acquire/release memory ordering guarantee.
877 static void incrementUintAcqRel(typename AtomicTypes::Uint *atomicUint);
878
879 /// Atomically increment the specified `atomicUint` by 1 and return the
880 /// resulting value, providing the sequential consistency memory
881 /// ordering guarantee.
882 static unsigned int incrementUintNv(
883 typename AtomicTypes::Uint *atomicUint);
884
885 /// Atomically increment the specified `atomicUint` by 1 and return the
886 /// resulting value, providing the acquire/release memory ordering
887 /// guarantee.
888 static unsigned int incrementUintNvAcqRel(
889 typename AtomicTypes::Uint *atomicUint);
890
891 /// Atomically subtract from the specified `atomicUint` the specified
892 /// `value` and return the resulting value, providing the sequential
893 /// consistency memory ordering guarantee.
894 static unsigned int subtractUintNv(typename AtomicTypes::Uint *atomicUint,
895 unsigned int value);
896
897 /// Atomically subtract from the specified `atomicUint` the specified
898 /// `value` and return the resulting value, providing the
899 /// acquire/release memory ordering guarantee.
900 static unsigned int subtractUintNvAcqRel(
901 typename AtomicTypes::Uint *atomicUint,
902 unsigned int value);
903
904 /// Atomically subtract from the specified `atomicUint` the specified
905 /// `value` and return the resulting value, without providing any memory
906 /// ordering guarantees.
907 static unsigned int subtractUintNvRelaxed(
908 typename AtomicTypes::Uint *atomicUint,
909 unsigned int value);
910};
911
912 // =====================================
913 // struct AtomicOperations_DefaultUint64
914 // =====================================
915
916/// This class provides default implementations of non-essential atomic
917/// operations for the 64-bit unsigned integer type independent on any
918/// specific platform. It also provides prototypes for the atomic
919/// operations for the 64-bit unsigned integer type that have to be
920/// implemented separately for each specific platform. These
921/// platform-independent and platform-specific atomic operations together
922/// form a full set of atomic operations for the 64-bit unsigned integer
923/// type.
924///
925///
926/// \note Note that `AtomicOperations_DefaultUint64` is implemented in terms of
927/// the following atomic operations on the Int64 type that must be provided
928/// by the `IMP` template parameter.
929/// @code
930/// static Types::Int64 getInt64(
931/// typename AtomicTypes::Int64 const *atomicInt);
932/// static Types::Int64 getInt64Relaxed(
933/// typename AtomicTypes::Int64 const *atomicInt);
934/// static Types::Int64 getInt64Acquire(
935/// typename AtomicTypes::Int64 const *atomicInt);
936/// static void setInt64(typename AtomicTypes::Int64 *atomicInt,
937/// Types::Int64 value);
938/// static void setInt64Relaxed(typename AtomicTypes::Int64 *atomicInt,
939/// Types::Int64 value);
940/// static void setInt64Release(typename AtomicTypes::Int64 *atomicInt,
941/// Types::Int64 value);
942/// static Types::Int64 swapInt64(typename AtomicTypes::Int64 *atomicInt,
943/// Types::Int64 swapValue);
944/// static Types::Int64 swapInt64AcqRel(
945/// typename AtomicTypes::Int64 *atomicInt,
946/// Types::Int64 swapValue);
947/// static Types::Int64 testAndSwapInt64(
948/// typename AtomicTypes::Int64 *atomicInt,
949/// Types::Int64 compareValue,
950/// Types::Int64 swapValue);
951/// static Types::Int64 testAndSwapInt64AcqRel(
952/// typename AtomicTypes::Int64 *atomicInt,
953/// Types::Int64 compareValue,
954/// Types::Int64 swapValue);
955/// @endcode
956template <class IMP>
958{
959 public:
960 // PUBLIC TYPES
962
963 // CLASS METHODS
964
965 /// Atomically retrieve the value of the specified `atomicUint`,
966 /// providing the sequential consistency memory ordering guarantee.
968 typename AtomicTypes::Uint64 const *atomicUint);
969
970 /// Atomically retrieve the value of the specified `atomicUint`,
971 /// providing the acquire memory ordering guarantee.
973 typename AtomicTypes::Uint64 const *atomicUint);
974
975 /// Atomically retrieve the value of the specified `atomicUint`, without
976 /// providing any memory ordering guarantees.
978 typename AtomicTypes::Uint64 const *atomicUint);
979
980 /// Initialize the specified `atomicUint` and set its value to the
981 /// optionally specified `initialValue`.
982 static void initUint64(typename AtomicTypes::Uint64 *atomicUint,
983 Types::Uint64 initialValue = 0);
984
985 /// Atomically set the value of the specified `atomicUint` to the
986 /// specified `value`, providing the sequential consistency memory
987 /// ordering guarantee.
988 static void setUint64(typename AtomicTypes::Uint64 *atomicUint,
989 Types::Uint64 value);
990
991 /// Atomically set the value of the specified `atomicUint` to the
992 /// specified `value`, without providing any memory ordering guarantees.
993 static void setUint64Relaxed(typename AtomicTypes::Uint64 *atomicUint,
994 Types::Uint64 value);
995
996 /// Atomically set the value of the specified `atomicUint` to the
997 /// specified `value`, providing the release memory ordering guarantee.
998 static void setUint64Release(typename AtomicTypes::Uint64 *atomicUint,
999 Types::Uint64 value);
1000
1001 /// Atomically set the value of the specified `atomicUint` to the
1002 /// specified `swapValue` and return its previous value, providing the
1003 /// sequential consistency memory ordering guarantee.
1004 static Types::Uint64 swapUint64(typename AtomicTypes::Uint64 *atomicUint,
1005 Types::Uint64 swapValue);
1006
1007 /// Atomically set the value of the specified `atomicUint` to the
1008 /// specified `swapValue` and return its previous value, providing the
1009 /// acquire/release memory ordering guarantee.
1011 typename AtomicTypes::Uint64 *atomicUint,
1012 Types::Uint64 swapValue);
1013
1014 /// Conditionally set the value of the specified `atomicUint` to the
1015 /// specified `swapValue` if and only if the value of `atomicUint`
1016 /// equals the value of the specified `compareValue`, and return the
1017 /// initial value of `atomicUint`, providing the sequential consistency
1018 /// memory ordering guarantee. The whole operation is performed
1019 /// atomically.
1021 typename AtomicTypes::Uint64 *atomicUint,
1022 Types::Uint64 compareValue,
1023 Types::Uint64 swapValue);
1024
1025 /// Conditionally set the value of the specified `atomicUint` to the
1026 /// specified `swapValue` if and only if the value of `atomicUint`
1027 /// equals the value of the specified `compareValue`, and return the
1028 /// initial value of `atomicUint`, providing the acquire/release memory
1029 /// ordering guarantee. The whole operation is performed atomically.
1031 typename AtomicTypes::Uint64 *atomicUint,
1032 Types::Uint64 compareValue,
1033 Types::Uint64 swapValue);
1034
1035 // Arithmetic
1036
1037 /// Atomically add to the specified `atomicUint` the specified `value`,
1038 /// providing the sequential consistency memory ordering guarantee.
1039 static void addUint64(typename AtomicTypes::Uint64 *atomicUint,
1040 Types::Uint64 value);
1041
1042 /// Atomically add to the specified `atomicUint` the specified `value`,
1043 /// providing the acquire/release memory ordering guarantee.
1044 static void addUint64AcqRel(typename AtomicTypes::Uint64 *atomicUint,
1045 Types::Uint64 value);
1046
1047 /// Atomically add to the specified `atomicUint` the specified `value`,
1048 /// without providing any memory ordering guarantees.
1049 static void addUint64Relaxed(typename AtomicTypes::Uint64 *atomicUint,
1050 Types::Uint64 value);
1051
1052 /// Atomically add to the specified `atomicUint` the specified `value`
1053 /// and return the resulting value, providing the sequential consistency
1054 /// memory ordering guarantee.
1055 static Types::Uint64 addUint64Nv(typename AtomicTypes::Uint64 *atomicUint,
1056 Types::Uint64 value);
1057
1058 /// Atomically add to the specified `atomicUint` the specified `value`
1059 /// and return the resulting value, providing the acquire/release memory
1060 /// ordering guarantee.
1062 typename AtomicTypes::Uint64 *atomicUint,
1063 Types::Uint64 value);
1064
1065 /// Atomically add to the specified `atomicUint` the specified `value`
1066 /// and return the resulting value, without providing any memory
1067 /// ordering guarantees.
1069 typename AtomicTypes::Uint64 *atomicUint,
1070 Types::Uint64 value);
1071
1072 /// Atomically decrement the specified `atomicUint` by 1, providing the
1073 /// sequential consistency memory ordering guarantee.
1074 static void decrementUint64(typename AtomicTypes::Uint64 *atomicUint);
1075
1076 /// Atomically decrement the specified `atomicUint` by 1, providing the
1077 /// acquire/release memory ordering guarantee.
1078 static void decrementUint64AcqRel(
1079 typename AtomicTypes::Uint64 *atomicUint);
1080
1081 /// Atomically decrement the specified `atomicUint` by 1 and return the
1082 /// resulting value, providing the sequential consistency memory
1083 /// ordering guarantee.
1085 typename AtomicTypes::Uint64 *atomicUint);
1086
1087 /// Atomically decrement the specified `atomicUint` by 1 and return the
1088 /// resulting value, providing the acquire/release memory ordering
1089 /// guarantee.
1091 typename AtomicTypes::Uint64 *atomicUint);
1092
1093 /// Atomically increment the value of the specified `atomicUint` by 1,
1094 /// providing the sequential consistency memory ordering guarantee.
1095 static void incrementUint64(typename AtomicTypes::Uint64 *atomicUint);
1096
1097 /// Atomically increment the value of the specified `atomicUint` by 1,
1098 /// providing the acquire/release memory ordering guarantee.
1099 static void incrementUint64AcqRel(
1100 typename AtomicTypes::Uint64 *atomicUint);
1101
1102 /// Atomically increment the specified `atomicUint` by 1 and return the
1103 /// resulting value, providing the sequential consistency memory
1104 /// ordering guarantee.
1106 typename AtomicTypes::Uint64 *atomicUint);
1107
1108 /// Atomically increment the specified `atomicUint` by 1 and return the
1109 /// resulting value, providing the acquire/release memory ordering
1110 /// guarantee.
1112 typename AtomicTypes::Uint64 *atomicUint);
1113
1114 /// Atomically subtract from the specified `atomicUint` the specified
1115 /// `value` and return the resulting value, providing the sequential
1116 /// consistency memory ordering guarantee.
1118 typename AtomicTypes::Uint64 *atomicUint,
1119 Types::Uint64 value);
1120
1121 /// Atomically subtract from the specified `atomicUint` the specified
1122 /// `value` and return the resulting value, providing the
1123 /// acquire/release memory ordering guarantee.
1125 typename AtomicTypes::Uint64 *atomicUint,
1126 Types::Uint64 value);
1127
1128 /// Atomically subtract from the specified `atomicUint` the specified
1129 /// `value` and return the resulting value, without providing any memory
1130 /// ordering guarantees.
1132 typename AtomicTypes::Uint64 *atomicUint,
1133 Types::Uint64 value);
1134};
1135
1136 // ========================================
1137 // struct AtomicOperations_DefaultPointer32
1138 // ========================================
1139
1140/// This class provides default implementations of non-essential atomic
1141/// operations for the 32-bit pointer type independent on any specific
1142/// platform. It also provides prototypes for the atomic operations for the
1143/// pointer type that have to be implemented separately for each specific
1144/// platform. These platform-independent and platform-specific atomic
1145/// operations combined together form a full set of atomic operations for
1146/// the pointer type.
1147///
1148///
1149/// \note Note that `AtomicOperations_DefaultPointer32` is implemented in terms of
1150/// the following atomic operations on the integer type that must be
1151/// provided by the `IMP` template parameter.
1152/// @code
1153/// static int getInt(typename AtomicTypes::Int const *atomicInt);
1154/// static int getIntRelaxed(typename AtomicTypes::Int const *atomicInt);
1155/// static int getIntAcquire(typename AtomicTypes::Int const *atomicInt);
1156/// static void setInt(typename AtomicTypes::Int *atomicInt, int value);
1157/// static void setIntRelaxed(typename AtomicTypes::Int *atomicInt,
1158/// int value);
1159/// static void setIntRelease(typename AtomicTypes::Int *atomicInt,
1160/// int value);
1161/// static int swapInt(typename AtomicTypes::Int *atomicInt,
1162/// int swapValue);
1163/// static int swapIntAcqRel(typename AtomicTypes::Int *atomicInt,
1164/// int swapValue);
1165/// static int testAndSwapInt(typename AtomicTypes::Int *atomicInt,
1166/// int compareValue,
1167/// int swapValue);
1168/// static int testAndSwapIntAcqRel(typename AtomicTypes::Int *atomicInt,
1169/// int compareValue,
1170/// int swapValue);
1171/// @endcode
1172template <class IMP>
1174{
1175 // PUBLIC TYPES
1177
1178 // CLASS METHODS
1179
1180 /// Atomically retrieve the value of the specified `atomicPtr`,
1181 /// providing the sequential consistency memory ordering guarantee.
1182 static void *getPtr(typename AtomicTypes::Pointer const *atomicPtr);
1183
1184 /// Atomically retrieve the value of the specified `atomicPtr`,
1185 /// providing the acquire memory ordering guarantee.
1186 static void *getPtrAcquire(typename AtomicTypes::Pointer const *atomicPtr);
1187
1188 /// Atomically retrieve the value of the specified `atomicPtr`, without
1189 /// providing any memory ordering guarantees.
1190 static void *getPtrRelaxed(typename AtomicTypes::Pointer const *atomicPtr);
1191
1192 /// Initialize the specified `atomicPtr` and set its value to the
1193 /// optionally specified `initialValue`.
1194 static void initPointer(typename AtomicTypes::Pointer *atomicPtr,
1195 void *initialValue = 0);
1196
1197 /// Atomically set the value of the specified `atomicPtr` to the
1198 /// specified `value`, providing the sequential consistency memory
1199 /// ordering guarantee.
1200 static void setPtr(typename AtomicTypes::Pointer *atomicPtr,
1201 void *value);
1202
1203 /// Atomically set the value of the specified `atomicPtr` to the
1204 /// specified `value`, without providing any memory ordering guarantees.
1205 static void setPtrRelaxed(typename AtomicTypes::Pointer *atomicPtr,
1206 void *value);
1207
1208 /// Atomically set the value of the specified `atomicPtr` to the
1209 /// specified `value`, providing the release memory ordering guarantee.
1210 static void setPtrRelease(typename AtomicTypes::Pointer *atomicPtr,
1211 void *value);
1212
1213 /// Atomically set the value of the specified `atomicPtr` to the
1214 /// specified `swapValue`, and return its previous value, providing the
1215 /// sequential consistency memory ordering guarantee.
1216 static void *swapPtr(typename AtomicTypes::Pointer *atomicPtr,
1217 void *swapValue);
1218
1219 /// Atomically set the value of the specified `atomicPtr` to the
1220 /// specified `swapValue`, and return its previous value, providing the
1221 /// acquire/release memory ordering guarantee.
1222 static void *swapPtrAcqRel(typename AtomicTypes::Pointer *atomicPtr,
1223 void *swapValue);
1224
1225 /// Conditionally set the value of the specified `atomicPtr` to the
1226 /// specified `swapValue` if and only if the value of `atomicPtr` equals
1227 /// the value of the specified `compareValue`, and return the initial
1228 /// value of `atomicPtr`, providing the sequential consistency memory
1229 /// ordering guarantee. The whole operation is performed atomically.
1230 static void *testAndSwapPtr(typename AtomicTypes::Pointer *atomicPtr,
1231 void *compareValue,
1232 void *swapValue);
1233
1234 /// Conditionally set the value of the specified `atomicPtr` to the
1235 /// specified `swapValue` if and only if the value of `atomicPtr` equals
1236 /// the value of the specified `compareValue`, and return the initial
1237 /// value of `atomicPtr`, providing the acquire/release memory ordering
1238 /// guarantee. The whole operation is performed atomically.
1239 static void *testAndSwapPtrAcqRel(
1240 typename AtomicTypes::Pointer *atomicPtr,
1241 void *compareValue,
1242 void *swapValue);
1243};
1244
1245 // ========================================
1246 // struct AtomicOperations_DefaultPointer64
1247 // ========================================
1248
1249/// This class provides default implementations of non-essential atomic
1250/// operations for the 64-bit pointer type independent on any specific
1251/// platform. It also provides prototypes for the atomic operations for the
1252/// pointer type that have to be implemented separately for each specific
1253/// platform. These platform-independent and platform-specific atomic
1254/// operations combined together form a full set of atomic operations for
1255/// the pointer type.
1256///
1257///
1258/// \note Note that `AtomicOperations_DefaultPointer64` is implemented in terms of
1259/// the following atomic operations on the Int64 type that must be provided
1260/// by the `IMP` template parameter.
1261/// @code
1262/// static Types::Int64 getInt64(
1263/// typename AtomicTypes::Int64 const *atomicInt);
1264/// static Types::Int64 getInt64Relaxed(
1265/// typename AtomicTypes::Int64 const *atomicInt);
1266/// static Types::Int64 getInt64Acquire(
1267/// typename AtomicTypes::Int64 const *atomicInt);
1268/// static void setInt64(typename AtomicTypes::Int64 *atomicInt,
1269/// Types::Int64 value);
1270/// static void setInt64Relaxed(typename AtomicTypes::Int64 *atomicInt,
1271/// Types::Int64 value);
1272/// static void setInt64Release(typename AtomicTypes::Int64 *atomicInt,
1273/// Types::Int64 value);
1274/// static Types::Int64 swapInt64(typename AtomicTypes::Int64 *atomicInt,
1275/// Types::Int64 swapValue);
1276/// static Types::Int64 swapInt64AcqRel(
1277/// typename AtomicTypes::Int64 *atomicInt,
1278/// Types::Int64 swapValue);
1279/// static Types::Int64 testAndSwapInt64(
1280/// typename AtomicTypes::Int64 *atomicInt,
1281/// Types::Int64 compareValue,
1282/// Types::Int64 swapValue);
1283/// static Types::Int64 testAndSwapInt64AcqRel(
1284/// typename AtomicTypes::Int64 *atomicInt,
1285/// Types::Int64 compareValue,
1286/// Types::Int64 swapValue);
1287/// @endcode
1288template <class IMP>
1290{
1291 // PUBLIC TYPES
1293
1294 // CLASS METHODS
1295
1296 /// Atomically retrieve the value of the specified `atomicPtr`,
1297 /// providing the sequential consistency memory ordering guarantee.
1298 static void *getPtr(typename AtomicTypes::Pointer const *atomicPtr);
1299
1300 /// Atomically retrieve the value of the specified `atomicPtr`,
1301 /// providing the acquire memory ordering guarantee.
1302 static void *getPtrAcquire(typename AtomicTypes::Pointer const *atomicPtr);
1303
1304 /// Atomically retrieve the value of the specified `atomicPtr`, without
1305 /// providing any memory ordering guarantees.
1306 static void *getPtrRelaxed(typename AtomicTypes::Pointer const *atomicPtr);
1307
1308 /// Initialize the specified `atomicPtr` and set its value to the
1309 /// optionally specified `initialValue`.
1310 static void initPointer(typename AtomicTypes::Pointer *atomicPtr,
1311 void *initialValue = 0);
1312
1313 /// Atomically set the value of the specified `atomicPtr` to the
1314 /// specified `value`, providing the sequential consistency memory
1315 /// ordering guarantee.
1316 static void setPtr(typename AtomicTypes::Pointer *atomicPtr,
1317 void *value);
1318
1319 /// Atomically set the value of the specified `atomicPtr` to the
1320 /// specified `value`, without providing any memory ordering guarantees.
1321 static void setPtrRelaxed(typename AtomicTypes::Pointer *atomicPtr,
1322 void *value);
1323
1324 /// Atomically set the value of the specified `atomicPtr` to the
1325 /// specified `value`, providing the release memory ordering guarantee.
1326 static void setPtrRelease(typename AtomicTypes::Pointer *atomicPtr,
1327 void *value);
1328
1329 /// Atomically set the value of the specified `atomicPtr` to the
1330 /// specified `swapValue`, and return its previous value, providing the
1331 /// sequential consistency memory ordering guarantee.
1332 static void *swapPtr(typename AtomicTypes::Pointer *atomicPtr,
1333 void *swapValue);
1334
1335 /// Atomically set the value of the specified `atomicPtr` to the
1336 /// specified `swapValue`, and return its previous value, providing the
1337 /// acquire/release memory ordering guarantee.
1338 static void *swapPtrAcqRel(typename AtomicTypes::Pointer *atomicPtr,
1339 void *swapValue);
1340
1341 /// Conditionally set the value of the specified `atomicPtr` to the
1342 /// specified `swapValue` if and only if the value of `atomicPtr` equals
1343 /// the value of the specified `compareValue`, and return the initial
1344 /// value of `atomicPtr`, providing the sequential consistency memory
1345 /// ordering guarantee. The whole operation is performed atomically.
1346 static void *testAndSwapPtr(typename AtomicTypes::Pointer *atomicPtr,
1347 void *compareValue,
1348 void *swapValue);
1349
1350 /// Conditionally set the value of the specified `atomicPtr` to the
1351 /// specified `swapValue` if and only if the value of `atomicPtr` equals
1352 /// the value of the specified `compareValue`, and return the initial
1353 /// value of `atomicPtr`, providing the acquire/release memory ordering
1354 /// guarantee. The whole operation is performed atomically.
1355 static void *testAndSwapPtrAcqRel(
1356 typename AtomicTypes::Pointer *atomicPtr,
1357 void *compareValue,
1358 void *swapValue);
1359};
1360
1361 // =================================
1362 // struct AtomicOperations_Default32
1363 // =================================
1364
1365/// This class provides default implementations of non-essential atomic
1366/// operations for the 32-bit integer, 64-bit integer, the 32-bit unsigned
1367/// integer, 64-bit unsigned integer and 32-bit pointer type for a generic
1368/// 32-bit platform.
1369template <class IMP>
1378
1379 // =================================
1380 // struct AtomicOperations_Default64
1381 // =================================
1382
1383/// This class provides default implementations of non-essential atomic
1384/// operations for the 32-bit integer, 64-bit integer, the 32-bit unsigned
1385/// integer, 64-bit unsigned integer and 64-bit pointer type for a generic
1386/// 64-bit platform.
1387template <class IMP>
1396
1397// ============================================================================
1398// INLINE FUNCTION DEFINITIONS
1399// ============================================================================
1400
1401 // ----------------------------------
1402 // struct AtomicOperations_DefaultInt
1403 // ----------------------------------
1404
1405// CLASS METHODS
1406template <class IMP>
1407inline
1409 getIntAcquire(typename AtomicTypes::Int const *atomicInt)
1410{
1411 return IMP::getInt(atomicInt);
1412}
1413
1414template <class IMP>
1415inline
1417 getIntRelaxed(typename AtomicTypes::Int const *atomicInt)
1418{
1419 return atomicInt->d_value;
1420}
1421
1422template <class IMP>
1423inline
1425 initInt(typename AtomicTypes::Int *atomicInt, int initialValue)
1426{
1427 atomicInt->d_value = initialValue;
1428}
1429
1430template <class IMP>
1431inline
1433 setIntRelaxed(typename AtomicTypes::Int *atomicInt, int value)
1434{
1435 atomicInt->d_value = value;
1436}
1437
1438template <class IMP>
1439inline
1441 setIntRelease(typename AtomicTypes::Int *atomicInt, int value)
1442{
1443 IMP::setInt(atomicInt, value);
1444}
1445
1446template <class IMP>
1447inline
1449 swapIntAcqRel(typename AtomicTypes::Int *atomicInt, int swapValue)
1450{
1451 return IMP::swapInt(atomicInt, swapValue);
1452}
1453
1454template <class IMP>
1455inline
1457 typename AtomicTypes::Int *atomicInt,
1458 int compareValue,
1459 int swapValue)
1460{
1461 return IMP::testAndSwapInt(atomicInt, compareValue, swapValue);
1462}
1463
1464// Arithmetic
1465template <class IMP>
1466inline
1468 addInt(typename AtomicTypes::Int *atomicInt, int value)
1469{
1470 IMP::addIntNv(atomicInt, value);
1471}
1472
1473template <class IMP>
1474inline
1476 addIntAcqRel(typename AtomicTypes::Int *atomicInt, int value)
1477{
1478 IMP::addIntNvAcqRel(atomicInt, value);
1479}
1480
1481template <class IMP>
1482inline
1484 addIntRelaxed(typename AtomicTypes::Int *atomicInt, int value)
1485{
1486 IMP::addIntNvRelaxed(atomicInt, value);
1487}
1488
1489template <class IMP>
1490inline
1492 addIntNvAcqRel(typename AtomicTypes::Int *atomicInt, int value)
1493{
1494 return IMP::addIntNv(atomicInt, value);
1495}
1496
1497template <class IMP>
1498inline
1500 addIntNvRelaxed(typename AtomicTypes::Int *atomicInt, int value)
1501{
1502 return IMP::addIntNvAcqRel(atomicInt, value);
1503}
1504
1505template <class IMP>
1506inline
1508 decrementInt(typename AtomicTypes::Int *atomicInt)
1509{
1510 IMP::addInt(atomicInt, -1);
1511}
1512
1513template <class IMP>
1514inline
1516 decrementIntAcqRel(typename AtomicTypes::Int *atomicInt)
1517{
1518 IMP::addIntAcqRel(atomicInt, -1);
1519}
1520
1521template <class IMP>
1522inline
1524 decrementIntNv(typename AtomicTypes::Int *atomicInt)
1525{
1526 return IMP::addIntNv(atomicInt, -1);
1527}
1528
1529template <class IMP>
1530inline
1532 decrementIntNvAcqRel(typename AtomicTypes::Int *atomicInt)
1533{
1534 return IMP::addIntNvAcqRel(atomicInt, -1);
1535}
1536
1537template <class IMP>
1538inline
1540 incrementInt(typename AtomicTypes::Int *atomicInt)
1541{
1542 IMP::addInt(atomicInt, 1);
1543}
1544
1545template <class IMP>
1546inline
1548 incrementIntAcqRel(typename AtomicTypes::Int *atomicInt)
1549{
1550 IMP::addIntAcqRel(atomicInt, 1);
1551}
1552
1553template <class IMP>
1554inline
1556 incrementIntNv(typename AtomicTypes::Int *atomicInt)
1557{
1558 return IMP::addIntNv(atomicInt, 1);
1559}
1560
1561template <class IMP>
1562inline
1564 incrementIntNvAcqRel(typename AtomicTypes::Int *atomicInt)
1565{
1566 return IMP::addIntNvAcqRel(atomicInt, 1);
1567}
1568
1569template <class IMP>
1570inline
1572 subtractIntNv(typename AtomicTypes::Int *atomicInt, int value)
1573{
1574 return static_cast<int>(
1575 IMP::subtractUintNv(
1576 reinterpret_cast<typename AtomicTypes::Uint *>(atomicInt),
1577 static_cast<unsigned int>(value)));
1578}
1579
1580template <class IMP>
1581inline
1583 subtractIntNvAcqRel(typename AtomicTypes::Int *atomicInt, int value)
1584{
1585 return static_cast<int>(
1586 IMP::subtractUintNvAcqRel(
1587 reinterpret_cast<typename AtomicTypes::Uint *>(atomicInt),
1588 static_cast<unsigned int>(value)));
1589}
1590
1591template <class IMP>
1592inline
1594 subtractIntNvRelaxed(typename AtomicTypes::Int *atomicInt, int value)
1595{
1596 return static_cast<int>(
1597 IMP::subtractUintNvRelaxed(
1598 reinterpret_cast<typename AtomicTypes::Uint *>(atomicInt),
1599 static_cast<unsigned int>(value)));
1600}
1601
1602 // ------------------------------------
1603 // struct AtomicOperations_DefaultInt64
1604 // ------------------------------------
1605
1606// CLASS METHODS
1607template <class IMP>
1608inline
1610 getInt64Acquire(typename AtomicTypes::Int64 const *atomicInt)
1611{
1612 return IMP::getInt64(atomicInt);
1613}
1614
1615template <class IMP>
1616inline
1618 getInt64Relaxed(typename AtomicTypes::Int64 const *atomicInt)
1619{
1620 return atomicInt->d_value;
1621}
1622
1623template <class IMP>
1624inline
1626 typename AtomicTypes::Int64 *atomicInt,
1627 Types::Int64 initialValue)
1628{
1629 atomicInt->d_value = initialValue;
1630}
1631
1632template <class IMP>
1633inline
1635 typename AtomicTypes::Int64 *atomicInt,
1636 Types::Int64 value)
1637{
1638 atomicInt->d_value = value;
1639}
1640
1641template <class IMP>
1642inline
1644 typename AtomicTypes::Int64 *atomicInt,
1645 Types::Int64 value)
1646{
1647 IMP::setInt64(atomicInt, value);
1648}
1649
1650template <class IMP>
1651inline
1653 typename AtomicTypes::Int64 *atomicInt,
1654 Types::Int64 swapValue)
1655{
1656 return IMP::swapInt64(atomicInt, swapValue);
1657}
1658
1659template <class IMP>
1660inline
1662 typename AtomicTypes::Int64 *atomicInt,
1663 Types::Int64 compareValue,
1664 Types::Int64 swapValue)
1665{
1666 return IMP::testAndSwapInt64(atomicInt, compareValue, swapValue);
1667}
1668
1669// Arithmetic
1670template <class IMP>
1671inline
1673 typename AtomicTypes::Int64 *atomicInt,
1674 Types::Int64 value)
1675{
1676 IMP::addInt64Nv(atomicInt, value);
1677}
1678
1679template <class IMP>
1680inline
1682 typename AtomicTypes::Int64 *atomicInt,
1683 Types::Int64 value)
1684{
1685 IMP::addInt64NvAcqRel(atomicInt, value);
1686}
1687
1688template <class IMP>
1689inline
1691 typename AtomicTypes::Int64 *atomicInt,
1692 Types::Int64 value)
1693{
1694 IMP::addInt64NvRelaxed(atomicInt, value);
1695}
1696
1697template <class IMP>
1698inline
1700 typename AtomicTypes::Int64 *atomicInt,
1701 Types::Int64 value)
1702{
1703 return IMP::addInt64Nv(atomicInt, value);
1704}
1705
1706template <class IMP>
1707inline
1709 typename AtomicTypes::Int64 *atomicInt,
1710 Types::Int64 value)
1711{
1712 return IMP::addInt64NvAcqRel(atomicInt, value);
1713}
1714
1715template <class IMP>
1716inline
1718 decrementInt64(typename AtomicTypes::Int64 *atomicInt)
1719{
1720 IMP::addInt64(atomicInt, -1);
1721}
1722
1723template <class IMP>
1724inline
1726 decrementInt64AcqRel(typename AtomicTypes::Int64 *atomicInt)
1727{
1728 IMP::addInt64AcqRel(atomicInt, -1);
1729}
1730
1731template <class IMP>
1732inline
1734 decrementInt64Nv(typename AtomicTypes::Int64 *atomicInt)
1735{
1736 return IMP::addInt64Nv(atomicInt, -1);
1737}
1738
1739template <class IMP>
1740inline
1742 decrementInt64NvAcqRel(typename AtomicTypes::Int64 *atomicInt)
1743{
1744 return IMP::addInt64NvAcqRel(atomicInt, -1);
1745}
1746
1747template <class IMP>
1748inline
1750 incrementInt64(typename AtomicTypes::Int64 *atomicInt)
1751{
1752 IMP::addInt64(atomicInt, 1);
1753}
1754
1755template <class IMP>
1756inline
1758 incrementInt64AcqRel(typename AtomicTypes::Int64 *atomicInt)
1759{
1760 IMP::addInt64AcqRel(atomicInt, 1);
1761}
1762
1763template <class IMP>
1764inline
1766 incrementInt64Nv(typename AtomicTypes::Int64 *atomicInt)
1767{
1768 return IMP::addInt64Nv(atomicInt, 1);
1769}
1770
1771template <class IMP>
1772inline
1774 incrementInt64NvAcqRel(typename AtomicTypes::Int64 *atomicInt)
1775{
1776 return IMP::addInt64NvAcqRel(atomicInt, 1);
1777}
1778
1779template <class IMP>
1780inline
1782 typename AtomicTypes::Int64 *atomicInt,
1783 Types::Int64 value)
1784{
1785 return static_cast<Types::Int64>(
1786 IMP::subtractUint64Nv(
1787 reinterpret_cast<typename AtomicTypes::Uint64 *>(atomicInt),
1788 static_cast<Types::Uint64>(value)));
1789}
1790
1791template <class IMP>
1792inline
1794 typename AtomicTypes::Int64 *atomicInt,
1795 Types::Int64 value)
1796{
1797 return static_cast<Types::Int64>(
1798 IMP::subtractUint64NvAcqRel(
1799 reinterpret_cast<typename AtomicTypes::Uint64 *>(atomicInt),
1800 static_cast<Types::Uint64>(value)));
1801}
1802
1803template <class IMP>
1804inline
1806 typename AtomicTypes::Int64 *atomicInt,
1807 Types::Int64 value)
1808{
1809 return static_cast<Types::Int64>(
1810 IMP::subtractUint64NvRelaxed(
1811 reinterpret_cast<typename AtomicTypes::Uint64 *>(atomicInt),
1812 static_cast<Types::Uint64>(value)));
1813}
1814
1815 // ----------------------------------
1816 // struct AtomicOperations_DefaultUint
1817 // ----------------------------------
1818
1819// CLASS METHODS
1820template <class IMP>
1821inline
1823 getUint(typename AtomicTypes::Uint const *atomicUint)
1824{
1825 return static_cast<unsigned int>(
1826 IMP::getInt(
1827 reinterpret_cast<typename AtomicTypes::Int const *>(
1828 atomicUint)));
1829}
1830
1831template <class IMP>
1832inline
1834 getUintAcquire(typename AtomicTypes::Uint const *atomicUint)
1835{
1836 return static_cast<unsigned int>(
1837 IMP::getIntAcquire(
1838 reinterpret_cast<typename AtomicTypes::Int const *>(atomicUint)));
1839}
1840
1841template <class IMP>
1842inline
1844 getUintRelaxed(typename AtomicTypes::Uint const *atomicUint)
1845{
1846 return static_cast<unsigned int>(
1847 IMP::getIntRelaxed(
1848 reinterpret_cast<typename AtomicTypes::Int const *>(atomicUint)));
1849}
1850
1851template <class IMP>
1852inline
1854 initUint(typename AtomicTypes::Uint *atomicUint, unsigned int initialValue)
1855{
1856 atomicUint->d_value = initialValue;
1857}
1858
1859template <class IMP>
1860inline
1862 setUint(typename AtomicTypes::Uint *atomicUint, unsigned int value)
1863{
1864 IMP::setInt(reinterpret_cast<typename AtomicTypes::Int *>(atomicUint),
1865 static_cast<int>(value));
1866}
1867
1868template <class IMP>
1869inline
1871 setUintRelaxed(typename AtomicTypes::Uint *atomicUint, unsigned int value)
1872{
1873 IMP::setIntRelaxed(
1874 reinterpret_cast<typename AtomicTypes::Int *>(atomicUint),
1875 static_cast<int>(value));
1876}
1877
1878template <class IMP>
1879inline
1881 setUintRelease(typename AtomicTypes::Uint *atomicUint, unsigned int value)
1882{
1883 IMP::setIntRelease(
1884 reinterpret_cast<typename AtomicTypes::Int *>(atomicUint),
1885 static_cast<int>(value));
1886}
1887
1888template <class IMP>
1889inline
1891 swapUint(typename AtomicTypes::Uint *atomicUint, unsigned int swapValue)
1892{
1893 return static_cast<unsigned int>(
1894 IMP::swapInt(
1895 reinterpret_cast<typename AtomicTypes::Int *>(atomicUint),
1896 static_cast<int>(swapValue)));
1897}
1898
1899template <class IMP>
1900inline
1902 typename AtomicTypes::Uint *atomicUint,
1903 unsigned int swapValue)
1904{
1905 return static_cast<unsigned int>(
1906 IMP::swapIntAcqRel(
1907 reinterpret_cast<typename AtomicTypes::Int *>(atomicUint),
1908 static_cast<int>(swapValue)));
1909}
1910
1911template <class IMP>
1912inline
1914 typename AtomicTypes::Uint *atomicUint,
1915 unsigned int compareValue,
1916 unsigned int swapValue)
1917{
1918 return static_cast<unsigned int>(
1919 IMP::testAndSwapInt(
1920 reinterpret_cast<typename AtomicTypes::Int *>(atomicUint),
1921 static_cast<int>(compareValue),
1922 static_cast<int>(swapValue)));
1923}
1924
1925template <class IMP>
1926inline
1928 typename AtomicTypes::Uint *atomicUint,
1929 unsigned int compareValue,
1930 unsigned int swapValue)
1931{
1932 return static_cast<unsigned int>(
1933 IMP::testAndSwapIntAcqRel(
1934 reinterpret_cast<typename AtomicTypes::Int *>(atomicUint),
1935 static_cast<int>(compareValue),
1936 static_cast<int>(swapValue)));
1937}
1938
1939// Arithmetic
1940template <class IMP>
1941inline
1943 addUint(typename AtomicTypes::Uint *atomicUint, unsigned int value)
1944{
1945 IMP::addInt(reinterpret_cast<typename AtomicTypes::Int *>(atomicUint),
1946 static_cast<int>(value));
1947}
1948
1949template <class IMP>
1950inline
1952 addUintAcqRel(typename AtomicTypes::Uint *atomicUint, unsigned int value)
1953{
1954 IMP::addIntAcqRel(
1955 reinterpret_cast<typename AtomicTypes::Int *>(atomicUint),
1956 static_cast<int>(value));
1957}
1958
1959template <class IMP>
1960inline
1962 addUintRelaxed(typename AtomicTypes::Uint *atomicUint, unsigned int value)
1963{
1964 IMP::addIntRelaxed(
1965 reinterpret_cast<typename AtomicTypes::Int *>(atomicUint),
1966 static_cast<int>(value));
1967}
1968
1969template <class IMP>
1970inline
1972 addUintNv(typename AtomicTypes::Uint *atomicUint, unsigned int value)
1973{
1974 return static_cast<unsigned int>(
1975 IMP::addIntNv(
1976 reinterpret_cast<typename AtomicTypes::Int *>(atomicUint),
1977 static_cast<int>(value)));
1978}
1979
1980template <class IMP>
1981inline
1983 addUintNvAcqRel(typename AtomicTypes::Uint *atomicUint, unsigned int value)
1984{
1985 return static_cast<unsigned int>(
1986 IMP::addIntNvAcqRel(
1987 reinterpret_cast<typename AtomicTypes::Int *>(atomicUint),
1988 static_cast<int>(value)));
1989}
1990
1991template <class IMP>
1992inline
1994 typename AtomicTypes::Uint *atomicUint,
1995 unsigned int value)
1996{
1997 return static_cast<unsigned int>(
1998 IMP::addIntNvRelaxed(
1999 reinterpret_cast<typename AtomicTypes::Int *>(atomicUint),
2000 static_cast<int>(value)));
2001}
2002
2003template <class IMP>
2004inline
2006 decrementUint(typename AtomicTypes::Uint *atomicUint)
2007{
2008 IMP::addInt(reinterpret_cast<typename AtomicTypes::Int *>(atomicUint), -1);
2009}
2010
2011template <class IMP>
2012inline
2014 decrementUintAcqRel(typename AtomicTypes::Uint *atomicUint)
2015{
2016 IMP::addIntAcqRel(
2017 reinterpret_cast<typename AtomicTypes::Int *>(atomicUint), -1);
2018}
2019
2020template <class IMP>
2021inline
2023 decrementUintNv(typename AtomicTypes::Uint *atomicUint)
2024{
2025 return IMP::subtractUintNv(atomicUint, 1);
2026}
2027
2028template <class IMP>
2029inline
2031 decrementUintNvAcqRel(typename AtomicTypes::Uint *atomicUint)
2032{
2033 return static_cast<unsigned int>(
2034 IMP::addIntNvAcqRel(
2035 reinterpret_cast<typename AtomicTypes::Int *>(atomicUint), -1));
2036}
2037
2038template <class IMP>
2039inline
2041 incrementUint(typename AtomicTypes::Uint *atomicUint)
2042{
2043 IMP::addUint(atomicUint, 1);
2044}
2045
2046template <class IMP>
2047inline
2049 incrementUintAcqRel(typename AtomicTypes::Uint *atomicUint)
2050{
2051 IMP::addUintAcqRel(atomicUint, 1);
2052}
2053
2054template <class IMP>
2055inline
2057 incrementUintNv(typename AtomicTypes::Uint *atomicUint)
2058{
2059 return IMP::addUintNv(atomicUint, 1);
2060}
2061
2062template <class IMP>
2063inline
2065 incrementUintNvAcqRel(typename AtomicTypes::Uint *atomicUint)
2066{
2067 return IMP::addUintNvAcqRel(atomicUint, 1);
2068}
2069
2070template <class IMP>
2071inline
2073 subtractUintNv(typename AtomicTypes::Uint *atomicUint, unsigned int value)
2074{
2075 return static_cast<unsigned int>(
2076 IMP::addIntNv(
2077 reinterpret_cast<typename AtomicTypes::Int *>(atomicUint),
2078 static_cast<int>(1 + ~value)));
2079}
2080
2081template <class IMP>
2082inline
2084 typename AtomicTypes::Uint *atomicUint,
2085 unsigned int value)
2086{
2087 return static_cast<unsigned int>(
2088 IMP::addIntNvAcqRel(
2089 reinterpret_cast<typename AtomicTypes::Int *>(atomicUint),
2090 static_cast<int>(1 + ~value)));
2091}
2092
2093template <class IMP>
2094inline
2096 typename AtomicTypes::Uint *atomicUint,
2097 unsigned int value)
2098{
2099 return static_cast<unsigned int>(
2100 IMP::addIntNvRelaxed(
2101 reinterpret_cast<typename AtomicTypes::Int *>(atomicUint),
2102 static_cast<int>(1 + ~value)));
2103}
2104
2105 // ------------------------------------
2106 // struct AtomicOperations_DefaultUint64
2107 // ------------------------------------
2108
2109// CLASS METHODS
2110template <class IMP>
2111inline
2113 getUint64(typename AtomicTypes::Uint64 const *atomicUint)
2114{
2115 return static_cast<Types::Uint64>(
2116 IMP::getInt64(reinterpret_cast<typename AtomicTypes::Int64 const *>(
2117 atomicUint)));
2118}
2119
2120template <class IMP>
2121inline
2123 getUint64Acquire(typename AtomicTypes::Uint64 const *atomicUint)
2124{
2125 return static_cast<Types::Uint64>(IMP::getInt64Acquire(
2126 reinterpret_cast<typename AtomicTypes::Int64 const *>(atomicUint)));
2127}
2128
2129template <class IMP>
2130inline
2132 getUint64Relaxed(typename AtomicTypes::Uint64 const *atomicUint)
2133{
2134 return static_cast<Types::Uint64>(IMP::getInt64Relaxed(
2135 reinterpret_cast<typename AtomicTypes::Int64 const *>(atomicUint)));
2136}
2137
2138template <class IMP>
2139inline
2141 typename AtomicTypes::Uint64 *atomicUint,
2142 Types::Uint64 initialValue)
2143{
2144 atomicUint->d_value = initialValue;
2145}
2146
2147template <class IMP>
2148inline
2150 setUint64(typename AtomicTypes::Uint64 *atomicUint, Types::Uint64 value)
2151{
2152 IMP::setInt64(reinterpret_cast<typename AtomicTypes::Int64 *>(atomicUint),
2153 static_cast<Types::Int64>(value));
2154}
2155
2156template <class IMP>
2157inline
2159 typename AtomicTypes::Uint64 *atomicUint,
2160 Types::Uint64 value)
2161{
2162 IMP::setInt64Relaxed(
2163 reinterpret_cast<typename AtomicTypes::Int64 *>(atomicUint),
2164 static_cast<Types::Int64>(value));
2165}
2166
2167template <class IMP>
2168inline
2170 typename AtomicTypes::Uint64 *atomicUint,
2171 Types::Uint64 value)
2172{
2173 IMP::setInt64Release(
2174 reinterpret_cast<typename AtomicTypes::Int64 *>(atomicUint),
2175 static_cast<Types::Int64>(value));
2176}
2177
2178template <class IMP>
2179inline
2181 typename AtomicTypes::Uint64 *atomicUint,
2182 Types::Uint64 swapValue)
2183{
2184 return static_cast<Types::Uint64>(
2185 IMP::swapInt64(
2186 reinterpret_cast<typename AtomicTypes::Int64 *>(atomicUint),
2187 static_cast<Types::Int64>(swapValue)));
2188}
2189
2190template <class IMP>
2191inline
2193 typename AtomicTypes::Uint64 *atomicUint,
2194 Types::Uint64 swapValue)
2195{
2196 return static_cast<Types::Uint64>(
2197 IMP::swapInt64AcqRel(
2198 reinterpret_cast<typename AtomicTypes::Int64 *>(atomicUint),
2199 static_cast<Types::Int64>(swapValue)));
2200}
2201
2202template <class IMP>
2203inline
2205 typename AtomicTypes::Uint64 *atomicUint,
2206 Types::Uint64 compareValue,
2207 Types::Uint64 swapValue)
2208{
2209 return static_cast<Types::Uint64>(
2210 IMP::testAndSwapInt64(
2211 reinterpret_cast<typename AtomicTypes::Int64 *>(atomicUint),
2212 static_cast<Types::Int64>(compareValue),
2213 static_cast<Types::Int64>(swapValue)));
2214}
2215
2216template <class IMP>
2217inline
2219 typename AtomicTypes::Uint64 *atomicUint,
2220 Types::Uint64 compareValue,
2221 Types::Uint64 swapValue)
2222{
2223 return static_cast<Types::Uint64>(
2224 IMP::testAndSwapInt64AcqRel(
2225 reinterpret_cast<typename AtomicTypes::Int64 *>(atomicUint),
2226 static_cast<Types::Int64>(compareValue),
2227 static_cast<Types::Int64>(swapValue)));
2228}
2229
2230// Arithmetic
2231template <class IMP>
2232inline
2234 typename AtomicTypes::Uint64 *atomicUint,Types::Uint64 value)
2235{
2236 IMP::addInt64(reinterpret_cast<typename AtomicTypes::Int64 *>(atomicUint),
2237 static_cast<Types::Int64>(value));
2238}
2239
2240template <class IMP>
2241inline
2243 typename AtomicTypes::Uint64 *atomicUint,Types::Uint64 value)
2244{
2245 IMP::addInt64AcqRel(
2246 reinterpret_cast<typename AtomicTypes::Int64 *>(atomicUint),
2247 static_cast<Types::Int64>(value));
2248}
2249
2250template <class IMP>
2251inline
2253 typename AtomicTypes::Uint64 *atomicUint,Types::Uint64 value)
2254{
2255 IMP::addInt64Relaxed(
2256 reinterpret_cast<typename AtomicTypes::Int64 *>(atomicUint),
2257 static_cast<Types::Int64>(value));
2258}
2259
2260template <class IMP>
2261inline
2263 typename AtomicTypes::Uint64 *atomicUint,Types::Uint64 value)
2264{
2265 return static_cast<Types::Uint64>(
2266 IMP::addInt64Nv(
2267 reinterpret_cast<typename AtomicTypes::Int64 *>(atomicUint),
2268 static_cast<Types::Int64>(value)));
2269}
2270
2271template <class IMP>
2272inline
2274 typename AtomicTypes::Uint64 *atomicUint,Types::Uint64 value)
2275{
2276 return static_cast<Types::Uint64>(
2277 IMP::addInt64NvAcqRel(
2278 reinterpret_cast<typename AtomicTypes::Int64 *>(atomicUint),
2279 static_cast<Types::Int64>(value)));
2280}
2281
2282template <class IMP>
2283inline
2285 typename AtomicTypes::Uint64 *atomicUint,Types::Uint64 value)
2286{
2287 return static_cast<Types::Uint64>(
2288 IMP::addInt64NvRelaxed(
2289 reinterpret_cast<typename AtomicTypes::Int64 *>(atomicUint),
2290 static_cast<Types::Int64>(value)));
2291}
2292
2293template <class IMP>
2294inline
2296 decrementUint64(typename AtomicTypes::Uint64 *atomicUint)
2297{
2298 IMP::addInt64(reinterpret_cast<typename AtomicTypes::Int64 *>(atomicUint),
2299 -1);
2300}
2301
2302template <class IMP>
2303inline
2305 decrementUint64AcqRel(typename AtomicTypes::Uint64 *atomicUint)
2306{
2307 IMP::addInt64AcqRel(
2308 reinterpret_cast<typename AtomicTypes::Int64 *>(atomicUint), -1);
2309}
2310
2311template <class IMP>
2312inline
2314 decrementUint64Nv(typename AtomicTypes::Uint64 *atomicUint)
2315{
2316 return IMP::subtractUint64Nv(atomicUint, 1);
2317}
2318
2319template <class IMP>
2320inline
2322 decrementUint64NvAcqRel(typename AtomicTypes::Uint64 *atomicUint)
2323{
2324 return static_cast<Types::Uint64>(
2325 IMP::addInt64NvAcqRel(
2326 reinterpret_cast<typename AtomicTypes::Int64 *>(atomicUint), -1));
2327}
2328
2329template <class IMP>
2330inline
2332 incrementUint64(typename AtomicTypes::Uint64 *atomicUint)
2333{
2334 IMP::addUint64(atomicUint, 1);
2335}
2336
2337template <class IMP>
2338inline
2340 incrementUint64AcqRel(typename AtomicTypes::Uint64 *atomicUint)
2341{
2342 IMP::addUint64AcqRel(atomicUint, 1);
2343}
2344
2345template <class IMP>
2346inline
2348 incrementUint64Nv(typename AtomicTypes::Uint64 *atomicUint)
2349{
2350 return IMP::addUint64Nv(atomicUint, 1);
2351}
2352
2353template <class IMP>
2354inline
2356 incrementUint64NvAcqRel(typename AtomicTypes::Uint64 *atomicUint)
2357{
2358 return IMP::addUint64NvAcqRel(atomicUint, 1);
2359}
2360
2361template <class IMP>
2362inline
2364 typename AtomicTypes::Uint64 *atomicUint, Types::Uint64 value)
2365{
2366 return static_cast<Types::Uint64>(
2367 IMP::addInt64Nv(
2368 reinterpret_cast<typename AtomicTypes::Int64 *>(atomicUint),
2369 static_cast<Types::Int64>(1 + ~value)));
2370}
2371
2372template <class IMP>
2373inline
2375 typename AtomicTypes::Uint64 *atomicUint,Types::Uint64 value)
2376{
2377 return static_cast<Types::Uint64>(
2378 IMP::addInt64NvAcqRel(
2379 reinterpret_cast<typename AtomicTypes::Int64 *>(atomicUint),
2380 static_cast<Types::Int64>(1 + ~value)));
2381}
2382
2383template <class IMP>
2384inline
2386 typename AtomicTypes::Uint64 *atomicUint,Types::Uint64 value)
2387{
2388 return static_cast<Types::Uint64>(
2389 IMP::addInt64NvRelaxed(
2390 reinterpret_cast<typename AtomicTypes::Int64 *>(atomicUint),
2391 static_cast<Types::Int64>(1 + ~value)));
2392}
2393
2394 // ----------------------------------------
2395 // struct AtomicOperations_DefaultPointer32
2396 // ----------------------------------------
2397
2398// CLASS METHODS
2399template <class IMP>
2400inline
2402 getPtr(typename AtomicTypes::Pointer const *atomicPtr)
2403{
2404 return reinterpret_cast<void *>(
2405 IMP::getInt(
2406 reinterpret_cast<typename AtomicTypes::Int const *>(
2407 atomicPtr)));
2408}
2409
2410template <class IMP>
2411inline
2413 getPtrAcquire(typename AtomicTypes::Pointer const *atomicPtr)
2414{
2415 return reinterpret_cast<void *>(
2416 IMP::getIntAcquire(
2417 reinterpret_cast<typename AtomicTypes::Int const *>(
2418 atomicPtr)));
2419}
2420
2421template <class IMP>
2422inline
2424 getPtrRelaxed(typename AtomicTypes::Pointer const *atomicPtr)
2425{
2426 return reinterpret_cast<void *>(
2427 IMP::getIntRelaxed(
2428 reinterpret_cast<typename AtomicTypes::Int const *>(
2429 atomicPtr)));
2430}
2431
2432template <class IMP>
2433inline
2435 typename AtomicTypes::Pointer *atomicPtr, void *initialValue)
2436{
2437 atomicPtr->d_value = initialValue;
2438}
2439
2440template <class IMP>
2441inline
2443 typename AtomicTypes::Pointer *atomicPtr, void *value)
2444{
2445 IMP::setInt(
2446 reinterpret_cast<typename AtomicTypes::Int *>(atomicPtr),
2447 reinterpret_cast<Types::IntPtr>(value));
2448}
2449
2450template <class IMP>
2451inline
2453 typename AtomicTypes::Pointer *atomicPtr, void *value)
2454{
2455 IMP::setIntRelaxed(
2456 reinterpret_cast<typename AtomicTypes::Int *>(atomicPtr),
2457 reinterpret_cast<Types::IntPtr>(value));
2458}
2459
2460template <class IMP>
2461inline
2463 typename AtomicTypes::Pointer *atomicPtr, void *value)
2464{
2465 IMP::setIntRelease(
2466 reinterpret_cast<typename AtomicTypes::Int *>(atomicPtr),
2467 reinterpret_cast<Types::IntPtr>(value));
2468}
2469
2470template <class IMP>
2471inline
2473 typename AtomicTypes::Pointer *atomicPtr, void *swapValue)
2474{
2475 return reinterpret_cast<void *>(
2476 IMP::swapInt(
2477 reinterpret_cast<typename AtomicTypes::Int *>(atomicPtr),
2478 reinterpret_cast<Types::IntPtr>(swapValue)));
2479}
2480
2481template <class IMP>
2482inline
2484 typename AtomicTypes::Pointer *atomicPtr, void *swapValue)
2485{
2486 return reinterpret_cast<void *>(
2487 IMP::swapIntAcqRel(
2488 reinterpret_cast<typename AtomicTypes::Int *>(atomicPtr),
2489 reinterpret_cast<Types::IntPtr>(swapValue)));
2490}
2491
2492template <class IMP>
2493inline
2495 typename AtomicTypes::Pointer *atomicPtr,
2496 void *compareValue,
2497 void *swapValue)
2498{
2499 return reinterpret_cast<void *>(
2500 IMP::testAndSwapInt(
2501 reinterpret_cast<typename AtomicTypes::Int *>(atomicPtr),
2502 reinterpret_cast<Types::IntPtr>(compareValue),
2503 reinterpret_cast<Types::IntPtr>(swapValue)));
2504}
2505
2506template <class IMP>
2507inline
2509 typename AtomicTypes::Pointer *atomicPtr,
2510 void *compareValue,
2511 void *swapValue)
2512{
2513 return reinterpret_cast<void *>(
2514 IMP::testAndSwapIntAcqRel(
2515 reinterpret_cast<typename AtomicTypes::Int *>(atomicPtr),
2516 reinterpret_cast<Types::IntPtr>(compareValue),
2517 reinterpret_cast<Types::IntPtr>(swapValue)));
2518}
2519
2520 // ----------------------------------------
2521 // struct AtomicOperations_DefaultPointer64
2522 // ----------------------------------------
2523
2524// CLASS METHODS
2525template <class IMP>
2526inline
2528 getPtr(typename AtomicTypes::Pointer const *atomicPtr)
2529{
2530 return reinterpret_cast<void *>(
2531 IMP::getInt64(
2532 reinterpret_cast<typename AtomicTypes::Int64 const *>(
2533 atomicPtr)));
2534}
2535
2536template <class IMP>
2537inline
2539 getPtrAcquire(typename AtomicTypes::Pointer const *atomicPtr)
2540{
2541 return reinterpret_cast<void *>(
2542 IMP::getInt64Acquire(
2543 reinterpret_cast<typename AtomicTypes::Int64 const *>(
2544 atomicPtr)));
2545}
2546
2547template <class IMP>
2548inline
2550 getPtrRelaxed(typename AtomicTypes::Pointer const *atomicPtr)
2551{
2552 return reinterpret_cast<void *>(
2553 IMP::getInt64Relaxed(
2554 reinterpret_cast<typename AtomicTypes::Int64 const *>(
2555 atomicPtr)));
2556}
2557
2558template <class IMP>
2559inline
2561 typename AtomicTypes::Pointer *atomicPtr, void *initialValue)
2562{
2563 atomicPtr->d_value = initialValue;
2564}
2565
2566template <class IMP>
2567inline
2569 typename AtomicTypes::Pointer *atomicPtr, void *value)
2570{
2571 IMP::setInt64(
2572 reinterpret_cast<typename AtomicTypes::Int64 *>(atomicPtr),
2573 reinterpret_cast<Types::IntPtr>(value));
2574}
2575
2576template <class IMP>
2577inline
2579 typename AtomicTypes::Pointer *atomicPtr, void *value)
2580{
2581 IMP::setInt64Relaxed(
2582 reinterpret_cast<typename AtomicTypes::Int64 *>(atomicPtr),
2583 reinterpret_cast<Types::IntPtr>(value));
2584}
2585
2586template <class IMP>
2587inline
2589 typename AtomicTypes::Pointer *atomicPtr, void *value)
2590{
2591 IMP::setInt64Release(
2592 reinterpret_cast<typename AtomicTypes::Int64 *>(atomicPtr),
2593 reinterpret_cast<Types::IntPtr>(value));
2594}
2595
2596template <class IMP>
2597inline
2599 typename AtomicTypes::Pointer *atomicPtr, void *swapValue)
2600{
2601 return reinterpret_cast<void *>(
2602 IMP::swapInt64(
2603 reinterpret_cast<typename AtomicTypes::Int64 *>(atomicPtr),
2604 reinterpret_cast<Types::IntPtr>(swapValue)));
2605}
2606
2607template <class IMP>
2608inline
2610 typename AtomicTypes::Pointer *atomicPtr, void *swapValue)
2611{
2612 return reinterpret_cast<void *>(
2613 IMP::swapInt64AcqRel(
2614 reinterpret_cast<typename AtomicTypes::Int64 *>(atomicPtr),
2615 reinterpret_cast<Types::IntPtr>(swapValue)));
2616}
2617
2618template <class IMP>
2619inline
2621 typename AtomicTypes::Pointer *atomicPtr,
2622 void *compareValue,
2623 void *swapValue)
2624{
2625 return reinterpret_cast<void *>(
2626 IMP::testAndSwapInt64(
2627 reinterpret_cast<typename AtomicTypes::Int64 *>(atomicPtr),
2628 reinterpret_cast<Types::IntPtr>(compareValue),
2629 reinterpret_cast<Types::IntPtr>(swapValue)));
2630}
2631
2632template <class IMP>
2633inline
2635 typename AtomicTypes::Pointer *atomicPtr,
2636 void *compareValue,
2637 void *swapValue)
2638{
2639 return reinterpret_cast<void *>(
2640 IMP::testAndSwapInt64AcqRel(
2641 reinterpret_cast<typename AtomicTypes::Int64 *>(atomicPtr),
2642 reinterpret_cast<Types::IntPtr>(compareValue),
2643 reinterpret_cast<Types::IntPtr>(swapValue)));
2644}
2645
2646} // close package namespace
2647
2648
2649
2650#endif
2651
2652// ----------------------------------------------------------------------------
2653// Copyright 2013 Bloomberg Finance L.P.
2654//
2655// Licensed under the Apache License, Version 2.0 (the "License");
2656// you may not use this file except in compliance with the License.
2657// You may obtain a copy of the License at
2658//
2659// http://www.apache.org/licenses/LICENSE-2.0
2660//
2661// Unless required by applicable law or agreed to in writing, software
2662// distributed under the License is distributed on an "AS IS" BASIS,
2663// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2664// See the License for the specific language governing permissions and
2665// limitations under the License.
2666// ----------------------------- END-OF-FILE ----------------------------------
2667
2668/** @} */
2669/** @} */
2670/** @} */
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
Definition bdlt_iso8601util.h:707
Definition bsls_atomicoperations_default.h:1376
Definition bsls_atomicoperations_default.h:1394
Definition bsls_atomicoperations_default.h:516
static void setInt64Release(typename AtomicTypes::Int64 *atomicInt, Types::Int64 value)
Definition bsls_atomicoperations_default.h:1643
static Types::Int64 incrementInt64NvAcqRel(typename AtomicTypes::Int64 *atomicInt)
Definition bsls_atomicoperations_default.h:1774
static Types::Int64 addInt64NvAcqRel(typename AtomicTypes::Int64 *atomicInt, Types::Int64 value)
Definition bsls_atomicoperations_default.h:1699
static void initInt64(typename AtomicTypes::Int64 *atomicInt, Types::Int64 initialValue=0)
Definition bsls_atomicoperations_default.h:1625
Atomic_TypeTraits< IMP > AtomicTypes
Definition bsls_atomicoperations_default.h:519
static void decrementInt64(typename AtomicTypes::Int64 *atomicInt)
Definition bsls_atomicoperations_default.h:1718
static void incrementInt64(typename AtomicTypes::Int64 *atomicInt)
Definition bsls_atomicoperations_default.h:1750
static void addInt64Relaxed(typename AtomicTypes::Int64 *atomicInt, Types::Int64 value)
Definition bsls_atomicoperations_default.h:1690
static Types::Int64 subtractInt64NvAcqRel(typename AtomicTypes::Int64 *atomicInt, Types::Int64 value)
Definition bsls_atomicoperations_default.h:1793
static Types::Int64 incrementInt64Nv(typename AtomicTypes::Int64 *atomicInt)
Definition bsls_atomicoperations_default.h:1766
static Types::Int64 testAndSwapInt64AcqRel(typename AtomicTypes::Int64 *atomicInt, Types::Int64 compareValue, Types::Int64 swapValue)
Definition bsls_atomicoperations_default.h:1661
static Types::Int64 subtractInt64Nv(typename AtomicTypes::Int64 *atomicInt, Types::Int64 value)
Definition bsls_atomicoperations_default.h:1781
static Types::Int64 getInt64Relaxed(typename AtomicTypes::Int64 const *atomicInt)
Definition bsls_atomicoperations_default.h:1618
static void addInt64AcqRel(typename AtomicTypes::Int64 *atomicInt, Types::Int64 value)
Definition bsls_atomicoperations_default.h:1681
static Types::Int64 decrementInt64Nv(typename AtomicTypes::Int64 *atomicInt)
Definition bsls_atomicoperations_default.h:1734
static void setInt64Relaxed(typename AtomicTypes::Int64 *atomicInt, Types::Int64 value)
Definition bsls_atomicoperations_default.h:1634
static void incrementInt64AcqRel(typename AtomicTypes::Int64 *atomicInt)
Definition bsls_atomicoperations_default.h:1758
static void decrementInt64AcqRel(typename AtomicTypes::Int64 *atomicInt)
Definition bsls_atomicoperations_default.h:1726
static Types::Int64 getInt64Acquire(typename AtomicTypes::Int64 const *atomicInt)
Definition bsls_atomicoperations_default.h:1610
static Types::Int64 decrementInt64NvAcqRel(typename AtomicTypes::Int64 *atomicInt)
Definition bsls_atomicoperations_default.h:1742
static Types::Int64 subtractInt64NvRelaxed(typename AtomicTypes::Int64 *atomicInt, Types::Int64 value)
Definition bsls_atomicoperations_default.h:1805
static Types::Int64 swapInt64AcqRel(typename AtomicTypes::Int64 *atomicInt, Types::Int64 swapValue)
Definition bsls_atomicoperations_default.h:1652
static void addInt64(typename AtomicTypes::Int64 *atomicInt, Types::Int64 value)
Definition bsls_atomicoperations_default.h:1672
static Types::Int64 addInt64NvRelaxed(typename AtomicTypes::Int64 *atomicInt, Types::Int64 value)
Definition bsls_atomicoperations_default.h:1708
Definition bsls_atomicoperations_default.h:344
static void setIntRelease(typename AtomicTypes::Int *atomicInt, int value)
Definition bsls_atomicoperations_default.h:1441
static int testAndSwapIntAcqRel(typename AtomicTypes::Int *atomicInt, int compareValue, int swapValue)
Definition bsls_atomicoperations_default.h:1456
static void addIntRelaxed(typename AtomicTypes::Int *atomicInt, int value)
Definition bsls_atomicoperations_default.h:1484
static void incrementIntAcqRel(typename AtomicTypes::Int *atomicInt)
Definition bsls_atomicoperations_default.h:1548
static void addInt(typename AtomicTypes::Int *atomicInt, int value)
Definition bsls_atomicoperations_default.h:1468
static int decrementIntNvAcqRel(typename AtomicTypes::Int *atomicInt)
Definition bsls_atomicoperations_default.h:1532
static void incrementInt(typename AtomicTypes::Int *atomicInt)
Definition bsls_atomicoperations_default.h:1540
static int addIntNvRelaxed(typename AtomicTypes::Int *atomicInt, int value)
Definition bsls_atomicoperations_default.h:1500
static int swapIntAcqRel(typename AtomicTypes::Int *atomicInt, int swapValue)
Definition bsls_atomicoperations_default.h:1449
Atomic_TypeTraits< IMP > AtomicTypes
Definition bsls_atomicoperations_default.h:347
static void addIntAcqRel(typename AtomicTypes::Int *atomicInt, int value)
Definition bsls_atomicoperations_default.h:1476
static void initInt(typename AtomicTypes::Int *atomicInt, int initialValue=0)
Definition bsls_atomicoperations_default.h:1425
static int incrementIntNvAcqRel(typename AtomicTypes::Int *atomicInt)
Definition bsls_atomicoperations_default.h:1564
static int getIntRelaxed(typename AtomicTypes::Int const *atomicInt)
Definition bsls_atomicoperations_default.h:1417
static void setIntRelaxed(typename AtomicTypes::Int *atomicInt, int value)
Definition bsls_atomicoperations_default.h:1433
static int getIntAcquire(typename AtomicTypes::Int const *atomicInt)
Definition bsls_atomicoperations_default.h:1409
static int addIntNvAcqRel(typename AtomicTypes::Int *atomicInt, int value)
Definition bsls_atomicoperations_default.h:1492
static int incrementIntNv(typename AtomicTypes::Int *atomicInt)
Definition bsls_atomicoperations_default.h:1556
static void decrementInt(typename AtomicTypes::Int *atomicInt)
Definition bsls_atomicoperations_default.h:1508
static int decrementIntNv(typename AtomicTypes::Int *atomicInt)
Definition bsls_atomicoperations_default.h:1524
static void decrementIntAcqRel(typename AtomicTypes::Int *atomicInt)
Definition bsls_atomicoperations_default.h:1516
static int subtractIntNvAcqRel(typename AtomicTypes::Int *atomicInt, int value)
Definition bsls_atomicoperations_default.h:1583
static int subtractIntNv(typename AtomicTypes::Int *atomicInt, int value)
Definition bsls_atomicoperations_default.h:1572
static int subtractIntNvRelaxed(typename AtomicTypes::Int *atomicInt, int value)
Definition bsls_atomicoperations_default.h:1594
Definition bsls_atomicoperations_default.h:1174
static void initPointer(typename AtomicTypes::Pointer *atomicPtr, void *initialValue=0)
Definition bsls_atomicoperations_default.h:2434
static void setPtrRelease(typename AtomicTypes::Pointer *atomicPtr, void *value)
Definition bsls_atomicoperations_default.h:2462
static void * getPtrAcquire(typename AtomicTypes::Pointer const *atomicPtr)
Definition bsls_atomicoperations_default.h:2413
Atomic_TypeTraits< IMP > AtomicTypes
Definition bsls_atomicoperations_default.h:1176
static void * getPtr(typename AtomicTypes::Pointer const *atomicPtr)
Definition bsls_atomicoperations_default.h:2402
static void setPtrRelaxed(typename AtomicTypes::Pointer *atomicPtr, void *value)
Definition bsls_atomicoperations_default.h:2452
static void * swapPtr(typename AtomicTypes::Pointer *atomicPtr, void *swapValue)
Definition bsls_atomicoperations_default.h:2472
static void * testAndSwapPtrAcqRel(typename AtomicTypes::Pointer *atomicPtr, void *compareValue, void *swapValue)
Definition bsls_atomicoperations_default.h:2508
static void * swapPtrAcqRel(typename AtomicTypes::Pointer *atomicPtr, void *swapValue)
Definition bsls_atomicoperations_default.h:2483
static void setPtr(typename AtomicTypes::Pointer *atomicPtr, void *value)
Definition bsls_atomicoperations_default.h:2442
static void * testAndSwapPtr(typename AtomicTypes::Pointer *atomicPtr, void *compareValue, void *swapValue)
Definition bsls_atomicoperations_default.h:2494
static void * getPtrRelaxed(typename AtomicTypes::Pointer const *atomicPtr)
Definition bsls_atomicoperations_default.h:2424
Definition bsls_atomicoperations_default.h:1290
static void * swapPtrAcqRel(typename AtomicTypes::Pointer *atomicPtr, void *swapValue)
Definition bsls_atomicoperations_default.h:2609
static void * swapPtr(typename AtomicTypes::Pointer *atomicPtr, void *swapValue)
Definition bsls_atomicoperations_default.h:2598
static void * testAndSwapPtrAcqRel(typename AtomicTypes::Pointer *atomicPtr, void *compareValue, void *swapValue)
Definition bsls_atomicoperations_default.h:2634
static void initPointer(typename AtomicTypes::Pointer *atomicPtr, void *initialValue=0)
Definition bsls_atomicoperations_default.h:2560
Atomic_TypeTraits< IMP > AtomicTypes
Definition bsls_atomicoperations_default.h:1292
static void * getPtrAcquire(typename AtomicTypes::Pointer const *atomicPtr)
Definition bsls_atomicoperations_default.h:2539
static void * getPtrRelaxed(typename AtomicTypes::Pointer const *atomicPtr)
Definition bsls_atomicoperations_default.h:2550
static void setPtrRelaxed(typename AtomicTypes::Pointer *atomicPtr, void *value)
Definition bsls_atomicoperations_default.h:2578
static void * getPtr(typename AtomicTypes::Pointer const *atomicPtr)
Definition bsls_atomicoperations_default.h:2528
static void setPtrRelease(typename AtomicTypes::Pointer *atomicPtr, void *value)
Definition bsls_atomicoperations_default.h:2588
static void * testAndSwapPtr(typename AtomicTypes::Pointer *atomicPtr, void *compareValue, void *swapValue)
Definition bsls_atomicoperations_default.h:2620
static void setPtr(typename AtomicTypes::Pointer *atomicPtr, void *value)
Definition bsls_atomicoperations_default.h:2568
Definition bsls_atomicoperations_default.h:958
static Types::Uint64 swapUint64(typename AtomicTypes::Uint64 *atomicUint, Types::Uint64 swapValue)
Definition bsls_atomicoperations_default.h:2180
static Types::Uint64 decrementUint64Nv(typename AtomicTypes::Uint64 *atomicUint)
Definition bsls_atomicoperations_default.h:2314
static void initUint64(typename AtomicTypes::Uint64 *atomicUint, Types::Uint64 initialValue=0)
Definition bsls_atomicoperations_default.h:2140
static Types::Uint64 incrementUint64Nv(typename AtomicTypes::Uint64 *atomicUint)
Definition bsls_atomicoperations_default.h:2348
static void addUint64(typename AtomicTypes::Uint64 *atomicUint, Types::Uint64 value)
Definition bsls_atomicoperations_default.h:2233
static void setUint64Relaxed(typename AtomicTypes::Uint64 *atomicUint, Types::Uint64 value)
Definition bsls_atomicoperations_default.h:2158
static Types::Uint64 subtractUint64Nv(typename AtomicTypes::Uint64 *atomicUint, Types::Uint64 value)
Definition bsls_atomicoperations_default.h:2363
static Types::Uint64 subtractUint64NvAcqRel(typename AtomicTypes::Uint64 *atomicUint, Types::Uint64 value)
Definition bsls_atomicoperations_default.h:2374
static void setUint64Release(typename AtomicTypes::Uint64 *atomicUint, Types::Uint64 value)
Definition bsls_atomicoperations_default.h:2169
static void incrementUint64AcqRel(typename AtomicTypes::Uint64 *atomicUint)
Definition bsls_atomicoperations_default.h:2340
static void decrementUint64(typename AtomicTypes::Uint64 *atomicUint)
Definition bsls_atomicoperations_default.h:2296
static Types::Uint64 getUint64(typename AtomicTypes::Uint64 const *atomicUint)
Definition bsls_atomicoperations_default.h:2113
static Types::Uint64 addUint64NvRelaxed(typename AtomicTypes::Uint64 *atomicUint, Types::Uint64 value)
Definition bsls_atomicoperations_default.h:2284
static void incrementUint64(typename AtomicTypes::Uint64 *atomicUint)
Definition bsls_atomicoperations_default.h:2332
static Types::Uint64 getUint64Relaxed(typename AtomicTypes::Uint64 const *atomicUint)
Definition bsls_atomicoperations_default.h:2132
static Types::Uint64 decrementUint64NvAcqRel(typename AtomicTypes::Uint64 *atomicUint)
Definition bsls_atomicoperations_default.h:2322
Atomic_TypeTraits< IMP > AtomicTypes
Definition bsls_atomicoperations_default.h:961
static void setUint64(typename AtomicTypes::Uint64 *atomicUint, Types::Uint64 value)
Definition bsls_atomicoperations_default.h:2150
static void addUint64Relaxed(typename AtomicTypes::Uint64 *atomicUint, Types::Uint64 value)
Definition bsls_atomicoperations_default.h:2252
static Types::Uint64 addUint64NvAcqRel(typename AtomicTypes::Uint64 *atomicUint, Types::Uint64 value)
Definition bsls_atomicoperations_default.h:2273
static void addUint64AcqRel(typename AtomicTypes::Uint64 *atomicUint, Types::Uint64 value)
Definition bsls_atomicoperations_default.h:2242
static Types::Uint64 testAndSwapUint64(typename AtomicTypes::Uint64 *atomicUint, Types::Uint64 compareValue, Types::Uint64 swapValue)
Definition bsls_atomicoperations_default.h:2204
static Types::Uint64 incrementUint64NvAcqRel(typename AtomicTypes::Uint64 *atomicUint)
Definition bsls_atomicoperations_default.h:2356
static Types::Uint64 subtractUint64NvRelaxed(typename AtomicTypes::Uint64 *atomicUint, Types::Uint64 value)
Definition bsls_atomicoperations_default.h:2385
static Types::Uint64 getUint64Acquire(typename AtomicTypes::Uint64 const *atomicUint)
Definition bsls_atomicoperations_default.h:2123
static Types::Uint64 testAndSwapUint64AcqRel(typename AtomicTypes::Uint64 *atomicUint, Types::Uint64 compareValue, Types::Uint64 swapValue)
Definition bsls_atomicoperations_default.h:2218
static void decrementUint64AcqRel(typename AtomicTypes::Uint64 *atomicUint)
Definition bsls_atomicoperations_default.h:2305
static Types::Uint64 swapUint64AcqRel(typename AtomicTypes::Uint64 *atomicUint, Types::Uint64 swapValue)
Definition bsls_atomicoperations_default.h:2192
static Types::Uint64 addUint64Nv(typename AtomicTypes::Uint64 *atomicUint, Types::Uint64 value)
Definition bsls_atomicoperations_default.h:2262
Definition bsls_atomicoperations_default.h:740
static unsigned int subtractUintNvRelaxed(typename AtomicTypes::Uint *atomicUint, unsigned int value)
Definition bsls_atomicoperations_default.h:2095
static unsigned int swapUint(typename AtomicTypes::Uint *atomicUint, unsigned int swapValue)
Definition bsls_atomicoperations_default.h:1891
static void addUintRelaxed(typename AtomicTypes::Uint *atomicUint, unsigned int value)
Definition bsls_atomicoperations_default.h:1962
static unsigned int incrementUintNv(typename AtomicTypes::Uint *atomicUint)
Definition bsls_atomicoperations_default.h:2057
static unsigned int decrementUintNv(typename AtomicTypes::Uint *atomicUint)
Definition bsls_atomicoperations_default.h:2023
static void addUintAcqRel(typename AtomicTypes::Uint *atomicUint, unsigned int value)
Definition bsls_atomicoperations_default.h:1952
static unsigned int addUintNv(typename AtomicTypes::Uint *atomicUint, unsigned int value)
Definition bsls_atomicoperations_default.h:1972
static void setUintRelaxed(typename AtomicTypes::Uint *atomicUint, unsigned int value)
Definition bsls_atomicoperations_default.h:1871
static unsigned int addUintNvRelaxed(typename AtomicTypes::Uint *atomicUint, unsigned int value)
Definition bsls_atomicoperations_default.h:1993
static void setUintRelease(typename AtomicTypes::Uint *atomicUint, unsigned int value)
Definition bsls_atomicoperations_default.h:1881
static unsigned int decrementUintNvAcqRel(typename AtomicTypes::Uint *atomicUint)
Definition bsls_atomicoperations_default.h:2031
static unsigned int incrementUintNvAcqRel(typename AtomicTypes::Uint *atomicUint)
Definition bsls_atomicoperations_default.h:2065
static unsigned int getUintAcquire(typename AtomicTypes::Uint const *atomicUint)
Definition bsls_atomicoperations_default.h:1834
static void incrementUintAcqRel(typename AtomicTypes::Uint *atomicUint)
Definition bsls_atomicoperations_default.h:2049
static void decrementUint(typename AtomicTypes::Uint *atomicUint)
Definition bsls_atomicoperations_default.h:2006
static unsigned int swapUintAcqRel(typename AtomicTypes::Uint *atomicUint, unsigned int swapValue)
Definition bsls_atomicoperations_default.h:1901
static void addUint(typename AtomicTypes::Uint *atomicUint, unsigned int value)
Definition bsls_atomicoperations_default.h:1943
static unsigned int subtractUintNvAcqRel(typename AtomicTypes::Uint *atomicUint, unsigned int value)
Definition bsls_atomicoperations_default.h:2083
static void initUint(typename AtomicTypes::Uint *atomicUint, unsigned int initialValue=0)
Definition bsls_atomicoperations_default.h:1854
static unsigned int addUintNvAcqRel(typename AtomicTypes::Uint *atomicUint, unsigned int value)
Definition bsls_atomicoperations_default.h:1983
static unsigned int testAndSwapUint(typename AtomicTypes::Uint *atomicUint, unsigned int compareValue, unsigned int swapValue)
Definition bsls_atomicoperations_default.h:1913
static void setUint(typename AtomicTypes::Uint *atomicUint, unsigned int value)
Definition bsls_atomicoperations_default.h:1862
static void incrementUint(typename AtomicTypes::Uint *atomicUint)
Definition bsls_atomicoperations_default.h:2041
static void decrementUintAcqRel(typename AtomicTypes::Uint *atomicUint)
Definition bsls_atomicoperations_default.h:2014
Atomic_TypeTraits< IMP > AtomicTypes
Definition bsls_atomicoperations_default.h:743
static unsigned int subtractUintNv(typename AtomicTypes::Uint *atomicUint, unsigned int value)
Definition bsls_atomicoperations_default.h:2073
static unsigned int testAndSwapUintAcqRel(typename AtomicTypes::Uint *atomicUint, unsigned int compareValue, unsigned int swapValue)
Definition bsls_atomicoperations_default.h:1927
static unsigned int getUint(typename AtomicTypes::Uint const *atomicUint)
Definition bsls_atomicoperations_default.h:1823
static unsigned int getUintRelaxed(typename AtomicTypes::Uint const *atomicUint)
Definition bsls_atomicoperations_default.h:1844
Definition bsls_atomicoperations_default.h:333
unsigned long long Uint64
Definition bsls_types.h:139
std::ptrdiff_t IntPtr
Definition bsls_types.h:132
long long Int64
Definition bsls_types.h:134