BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bsls_atomicoperations.h
Go to the documentation of this file.
1/// @file bsls_atomicoperations.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bsls_atomicoperations.h -*-C++-*-
8#ifndef INCLUDED_BSLS_ATOMICOPERATIONS
9#define INCLUDED_BSLS_ATOMICOPERATIONS
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bsls_atomicoperations bsls_atomicoperations
15/// @brief Provide platform-independent atomic operations.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bsls
19/// @{
20/// @addtogroup bsls_atomicoperations
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bsls_atomicoperations-purpose"> Purpose</a>
25/// * <a href="#bsls_atomicoperations-classes"> Classes </a>
26/// * <a href="#bsls_atomicoperations-description"> Description </a>
27/// * <a href="#bsls_atomicoperations-memory-order-and-consistency-guarantees-of-atomic-operations"> Memory Order and Consistency Guarantees of Atomic Operations </a>
28/// * <a href="#bsls_atomicoperations-acquire-and-release-memory-consistency-guarantees"> Acquire and Release Memory Consistency Guarantees </a>
29/// * <a href="#bsls_atomicoperations-sequential-consistency-memory-consistency-guarantee"> Sequential Consistency Memory Consistency Guarantee </a>
30/// * <a href="#bsls_atomicoperations-atomic-integer-operations"> Atomic Integer Operations </a>
31/// * <a href="#bsls_atomicoperations-atomic-pointer-operations"> Atomic Pointer Operations </a>
32/// * <a href="#bsls_atomicoperations-usage"> Usage </a>
33/// * <a href="#bsls_atomicoperations-example-1-usage-statistics-on-a-thread-pool"> Example 1: Usage Statistics on a Thread Pool </a>
34/// * <a href="#bsls_atomicoperations-example-2-thread-safe-counted-handle"> Example 2: Thread-Safe Counted Handle </a>
35/// * <a href="#bsls_atomicoperations-class-my_countedhandlerep"> Class my_CountedHandleRep </a>
36/// * <a href="#bsls_atomicoperations-class-my_countedhandle"> Class my_CountedHandle </a>
37/// * <a href="#bsls_atomicoperations-function-definitions-for-my_countedhandlerep"> Function Definitions for my_CountedHandleRep </a>
38/// * <a href="#bsls_atomicoperations-function-definitions-for-my_countedhandle"> Function Definitions for my_CountedHandle </a>
39/// * <a href="#bsls_atomicoperations-example-3-thread-safe-lock-free-singly-linked-list"> Example 3: Thread-Safe Lock-Free Singly-Linked List </a>
40///
41/// # Purpose {#bsls_atomicoperations-purpose}
42/// Provide platform-independent atomic operations.
43///
44/// # Classes {#bsls_atomicoperations-classes}
45///
46/// - bsls::AtomicOperations: namespace for atomic operations
47///
48/// # Description {#bsls_atomicoperations-description}
49/// This utility, `bsls::AtomicOperations`, provides a set of
50/// platform-independent atomic operations for fundamental data types, such as
51/// 32-bit integer, 64-bit integer, 32-bit unsigned integer, 64-bit unsigned
52/// integer, pointer, and bool. The examples of provided atomic operations
53/// include loading, storing, exchanging, incrementing and decrementing the
54/// data of fundamental types. Atomic operations are useful for manipulating
55/// certain types of shared data without the need for high level synchronization
56/// mechanisms (e.g., "mutexes" or "critical sections").
57///
58/// Integer atomic operations allow for thread-safe manipulation of a single 32
59/// or 64-bit integer value, without the use of other synchronization
60/// mechanisms. Even the most basic operations on data that is shared among
61/// multiple threads must use some form of synchronization to ensure proper
62/// results.
63///
64/// Consider the prefix increment from the following snippet of C code:
65/// @code
66/// static int x;
67/// ++x;
68/// @endcode
69/// Although the increment statement looks very simple, it may result in several
70/// machine instructions. Depending on the architecture and compiler
71/// optimization options, the statement might result in the following pseudo
72/// machine instructions:
73/// @code
74/// LOAD 'x' to register
75/// ADD 1 to register
76/// STORE register to 'x'
77/// @endcode
78/// Consider the situation when the above statements were executed
79/// simultaneously by two threads. Thread A could load `x` to a register, and
80/// then be interrupted by the operating system. Thread B could then begin to
81/// execute, and complete all three instructions, loading, incrementing, and
82/// storing the variable `x`. When thread A resumes, it would increment the
83/// value that it loaded, and store the result.
84///
85/// Thus, it is possible that both threads load the same value of x to the
86/// register, add one, and store their individual but equal results, incorrectly
87/// incrementing `x` by only 1 instead of the correct value 2. One could
88/// correct this problem by using a high level synchronization mechanisms (e.g.,
89/// "mutex"), but these mechanisms are generally very expensive for such a small
90/// fragment of code, and could result in a large number of unnecessary context
91/// switches, for instance, if the increment statement occurs within a loop.
92///
93/// Instead, an atomic operation (in this case,
94/// `bsls::AtomicOperations::incrementInt`) can be used to manipulate the value;
95/// use of this operation will ensure that, when executed simultaneously by
96/// multiple threads, the threads will increment the value serially, without
97/// interrupting one another.
98///
99/// Special data types are provided to represent these values. Atomic data
100/// types are generally the same as their corresponding primitive data types,
101/// and therefore typically do not incur any additional memory overhead.
102/// However, on some platforms, it may be necessary to use larger, more complex
103/// types to represent these values; therefore they must always be accessed or
104/// manipulated using their accessors or manipulators, respectively. Not doing
105/// so may result in incorrect results and/or non-portable code.
106///
107/// Atomic operations should not be used in situations where behavior is
108/// inherently thread-safe and no synchronization is required; although they are
109/// typically much faster than using high-level synchronization mechanisms to
110/// accomplish the same results, atomic operations are typically more expensive
111/// (in both speed and code size) than their non-atomic equivalents.
112///
113/// ## Memory Order and Consistency Guarantees of Atomic Operations {#bsls_atomicoperations-memory-order-and-consistency-guarantees-of-atomic-operations}
114///
115///
116/// Atomic operations provided by this component ensure various memory ordering
117/// consistency guarantees. Memory ordering guarantees of atomic operations are
118/// designed to ensure visibility and synchronization order of memory reads and
119/// writes between threads that perform atomic operations. The operations on
120/// objects of the provided classes ensure the most strict consistency
121/// guarantee, sequential consistency (described below), unless explicitly
122/// qualified with a less strict consistency guarantee (i.e., Acquire, Release,
123/// Acquire/Release or Relaxed).
124///
125/// This component implements memory order and consistency guarantees as defined
126/// in the C++ 2011 Standard (sections: [intro.multithreaded], [atomics.order]).
127///
128/// The following memory ordering guarantees are supported:
129///
130/// * relaxed - the operation does not provide any memory consistency guarantee
131/// * release - the operation performs a release operation on the affected
132/// memory location, thus making preceding regular memory writes of the
133/// calling thread visible to other threads through the atomic variable to
134/// which it is applied (generally available for operations that write to a
135/// memory location).
136/// * acquire - the operation performs an acquire operation on the affected
137/// memory location, thus making regular memory writes in other threads
138/// released through the atomic variable to which it is applied visible to
139/// the current thread (generally available for operations that read from a
140/// memory location).
141/// * acquire/release - the operation has both acquire and release semantics
142/// (generally available for operations that both read and write a memory
143/// location).
144/// * sequential consistency - the operation has both acquire and release
145/// guarantees, and further guarantees that all sequentially consistent
146/// operations performed by the process will be observed to occur in a single
147/// global total order (regardless of the thread from which they are
148/// observed).
149///
150/// ### Acquire and Release Memory Consistency Guarantees {#bsls_atomicoperations-acquire-and-release-memory-consistency-guarantees}
151///
152///
153/// Operations providing acquire and release guarantees are essential to
154/// synchronizing the memory state between multiple threads. For example,
155/// consider two threads, A and B, that perform store and load operations to
156/// shared memory locations. Without any synchronization, store operations in
157/// thread A can be freely reordered with load operations in thread B, i.e,
158/// thread A can perform two store operations to two memory locations in a
159/// certain order and thread B can see those operations done in a different
160/// order due to such effects as: compiler or processor optimizations of store
161/// and load operations, and cache synchronization between processors and cores.
162///
163/// However, stores in thread A can be ordered with loads in thread B using a
164/// combination of store-release and load-acquire operations. A store-release
165/// operation in thread A followed by a load-acquire operation in thread B to
166/// the *same* *memory* *location* guarantees that thread B sees all other
167/// stores done in thread A prior to the store-release operation. The
168/// store-release in thread A effectively synchronizes the memory state with the
169/// load-acquire in thread B.
170///
171/// An acquire-release operation is a load-modify-store operation that, if
172/// performed in both threads A and B on the same memory location, synchronizes
173/// stores and loads between threads A and B in both directions.
174///
175/// ### Sequential Consistency Memory Consistency Guarantee {#bsls_atomicoperations-sequential-consistency-memory-consistency-guarantee}
176///
177///
178/// Finally, load and store operations with sequential consistency are
179/// guaranteed to performed in a global total order among all threads in the
180/// process. To illustrate the total order, let's consider the so-called
181/// "independent reads of independent writes" example:
182/// @code
183/// bsls::AtomicInt x(0);
184/// bsls::AtomicInt y(0);
185/// int r1, r2, r3, r4;
186///
187/// void thread1() {
188/// x = 1; // sequential consistency store
189/// }
190///
191/// void thread2() {
192/// y = 1; // sequential consistency store
193/// }
194///
195/// void thread3() {
196/// r1 = x; // sequential consistency load
197/// r2 = y; // sequential consistency load
198/// }
199///
200/// void thread4() {
201/// r3 = y; // sequential consistency load
202/// r4 = x; // sequential consistency load
203/// }
204/// @endcode
205/// Where `threadN` functions are executed concurrently by different threads
206/// (note that values `x` and `y` are written by independent threads).
207/// Sequential consistency guarantees that if `thread3` observes values `x` and
208/// `y` as `r1 == 1 && r2 == 0`, then `thread4` can't observe values `x` and `y`
209/// in a different order, i.e., `r3 == 1 && r4 == 0`.
210///
211/// ## Atomic Integer Operations {#bsls_atomicoperations-atomic-integer-operations}
212///
213///
214/// The atomic integer operations provide thread-safe access for 32- or 64-bit
215/// signed integer numbers without the use of higher level synchronization
216/// mechanisms. Atomic integers are most commonly used to manipulate shared
217/// counters and indices. Five types of operations are provided; get/set,
218/// increment/decrement, add, swap, and test and swap. Two sub-types of
219/// manipulators are provided for increment/decrement and addition operations.
220///
221/// `bsls::AtomicOperations` functions whose names end in "Nv" (stands for "new
222/// value"; e.g., `addIntNv`, `incrementInt64Nv`) return the resulting value of
223/// the operations; those without the suffix do not return a value. If an
224/// application does not require the resulting value of an operation, it should
225/// not use the "Nv" manipulator. On some platforms, it may be less efficient
226/// to determine the resulting value of an operation than to simply perform the
227/// operation.
228///
229/// ## Atomic Pointer Operations {#bsls_atomicoperations-atomic-pointer-operations}
230///
231///
232/// The atomic pointer operations provide thread-safe access to pointer values
233/// without the use of higher level synchronization mechanisms. They are
234/// commonly used to create fast thread-safe singly-linked lists.
235///
236/// ## Usage {#bsls_atomicoperations-usage}
237///
238///
239/// This section illustrates intended use of this component.
240///
241/// ### Example 1: Usage Statistics on a Thread Pool {#bsls_atomicoperations-example-1-usage-statistics-on-a-thread-pool}
242///
243///
244/// This example demonstrates a common use of atomic integer types for
245/// statistics counters. The program creates a series of threads to process
246/// transactions. As each thread completes a transaction, it atomically
247/// increments the transaction counters.
248///
249/// For this example, we assume the existence of the functions
250/// `processNextTransaction`, `createWorkerThread`, and `waitAllThreads`. The
251/// function `createWorkerThread` spawns a new thread, which executes the
252/// `workerThread` function. `waitAllThreads` blocks until all the worker
253/// thread complete.
254///
255/// First, we declare the shared counters:
256/// @code
257/// static bsls::AtomicOperations::AtomicTypes::Int64 transactionCount;
258/// static bsls::AtomicOperations::AtomicTypes::Int64 successCount;
259/// static bsls::AtomicOperations::AtomicTypes::Int64 failureCount;
260/// @endcode
261/// Next, for each transaction processed, we atomically increment either the
262/// success or the failure counter as well as the total transaction count:
263/// @code
264/// static void workerThread(int *stop)
265/// {
266/// while (!(*stop)) {
267/// if (processNextTransaction()) {
268/// bsls::AtomicOperations::incrementInt64(&failureCount);
269/// }
270/// else {
271/// bsls::AtomicOperations::incrementInt64(&successCount);
272/// }
273/// bsls::AtomicOperations::incrementInt64(&transactionCount);
274/// }
275/// }
276/// @endcode
277/// Finally, we write function, `serverMain`, that provides the overall control
278/// logic for the server. This function spawns the threads and then waits for
279/// all work to be completed; when all of the threads have finished, this
280/// function returns normally:
281/// @code
282/// void serverMain()
283/// {
284/// const int numThreads = 10;
285/// @endcode
286/// Before any of the counters is used, they must be initialized. `initInt64`
287/// is called to initialize each value to 0:
288/// @code
289/// bsls::AtomicOperations::initInt64(&transactionCount, 0);
290/// bsls::AtomicOperations::initInt64(&successCount, 0);
291/// bsls::AtomicOperations::initInt64(&failureCount, 0);
292/// @endcode
293/// Spawn the threads to process the transactions concurrently:
294/// @code
295/// for (int i = 0; i < numThreads; ++i) {
296/// createWorkerThread();
297/// }
298/// @endcode
299/// Wait for all the threads to complete:
300/// @code
301/// waitAllThreads();
302/// }
303/// @endcode
304/// Note that functions `createWorkerThread` and `waitAllThreads` can be
305/// implemented using any thread-support package.
306///
307/// ### Example 2: Thread-Safe Counted Handle {#bsls_atomicoperations-example-2-thread-safe-counted-handle}
308///
309///
310/// The following example demonstrates the use of atomic integer operations to
311/// implement a thread-safe ref-counted handle similar to a shared pointer.
312/// Each handle (of type `my_CountedHandle`) maintains a pointer to a
313/// representation object, `my_CountedHandleRep`, which in turn, stores both a
314/// pointer to the managed object and a reference counter.
315///
316/// Both the handle class and the representation class are template classes with
317/// two template parameters. The template parameter, `INSTANCE`, represents the
318/// type of the "instance", or managed object.
319///
320/// A representation object can be shared by several handle objects. When a
321/// handle object is assigned to a second handle object, the address of the
322/// representation is copied to the second handle, and the reference count on
323/// the representation is atomically incremented. When a handle releases its
324/// reference to the representation, it atomically decrements the reference
325/// count. If the resulting reference count becomes 0 (and there are no more
326/// references to the object), the handle deletes the representation object and
327/// the representation object, in turn, deletes the managed object (`INSTANCE`).
328///
329/// ### Class my_CountedHandleRep {#bsls_atomicoperations-class-my_countedhandlerep}
330///
331///
332/// First, we define class `my_CountedHandleRep`. This class manages a single
333/// `INSTANCE` object on behalf of multiple "handle" objects; since different
334/// "handle" objects may be active in different threads, class
335/// `my_CountedHandleRep` must be (fully) thread-safe. Specifically, methods
336/// `increment` and `decrement` must work atomically.
337///
338/// Note that, this rep class is intended to be used only by class
339/// `my_CountedHandle`, and thus all methods of class `my_CountedHandleRep` are
340/// declared private, and `friend` status is granted to class
341/// `my_CountedHandle`:
342/// @code
343/// // =========================
344/// // class my_CountedHandleRep
345/// // =========================
346///
347/// template <class INSTANCE>
348/// class my_CountedHandle;
349///
350/// template <class INSTANCE>
351/// class my_CountedHandleRep {
352///
353/// // DATA
354/// bsls::AtomicOperations::AtomicTypes::Int
355/// d_count; // number of active references
356/// INSTANCE *d_instance_p; // address of managed instance
357///
358/// // FRIENDS
359/// friend class my_CountedHandle<INSTANCE>;
360///
361/// private: // not implemented
362/// my_CountedHandleRep(const my_CountedHandleRep&);
363/// my_CountedHandleRep& operator=(const my_CountedHandleRep&);
364///
365/// public:
366/// // CLASS METHODS
367/// static void
368/// deleteObject(my_CountedHandleRep<INSTANCE> *object);
369///
370/// // CREATORS
371/// my_CountedHandleRep(INSTANCE *instance);
372/// ~my_CountedHandleRep();
373///
374/// // MANIPULATORS
375/// void increment();
376/// int decrement();
377/// };
378/// @endcode
379///
380/// #### Class my_CountedHandle {#bsls_atomicoperations-class-my_countedhandle}
381///
382///
383/// Then, we create class `my_CountedHandle` that provides an individual handle
384/// to the shared, reference-counted object. Each `my_CountedHandle` object
385/// acts as a smart pointer, supplying an overloaded `operator->` that provides
386/// access to the underlying `INSTANCE` object via pointer semantics.
387///
388/// `my_CountedHandle` can also be copied freely; the copy constructor will use
389/// the `increment` method from `my_CountedHandleRep` to note the extra copy.
390/// Similarly, the destructor will call `my_CountedHandleRep::decrement` to note
391/// that there is one fewer handle the underlying `INSTANCE` has, and delete the
392/// "rep" object when its reference count is reduced to zero:
393/// @code
394/// // ======================
395/// // class my_CountedHandle
396/// // ======================
397///
398/// template <class INSTANCE>
399/// class my_CountedHandle {
400///
401/// // DATA
402/// my_CountedHandleRep<INSTANCE> *d_rep_p; // shared rep.
403///
404/// public:
405/// // CREATORS
406/// my_CountedHandle(INSTANCE *instance);
407///
408/// my_CountedHandle(const my_CountedHandle<INSTANCE>& other);
409///
410/// ~my_CountedHandle();
411///
412/// // ACCESSORS
413/// INSTANCE *operator->() const;
414/// int numReferences() const;
415/// };
416/// @endcode
417///
418/// #### Function Definitions for my_CountedHandleRep {#bsls_atomicoperations-function-definitions-for-my_countedhandlerep}
419///
420///
421/// Next, we provide a definition for the `static` `deleteObject` method, which
422/// is called by the destructor for class `my_CountedHandle` for the last
423/// instance of `my_CountedHandle` using the given "rep" object:
424/// @code
425/// template <class INSTANCE>
426/// inline
427/// void my_CountedHandleRep<INSTANCE>::deleteObject(
428/// my_CountedHandleRep<INSTANCE> *object)
429/// {
430/// delete object;
431/// }
432/// @endcode
433/// Then, we write the constructor for the `my_CountedHandleRep<INSTANCE>`
434/// class. We initialize the atomic reference counter to one reference using
435/// `bsls::AtomicOperations::initInt`. This reflects the fact that this
436/// constructor will be called by a new instance of `my_CountedHandle`. That
437/// instance is our first and only handle when this constructor is called:
438/// @code
439/// template <class INSTANCE>
440/// inline
441/// my_CountedHandleRep<INSTANCE>::
442/// my_CountedHandleRep(INSTANCE *instance)
443/// : d_instance_p(instance)
444/// {
445/// bsls::AtomicOperations::initInt(&d_count, 1);
446/// }
447/// @endcode
448/// Then, we define the destructor, which just deletes `my_CountedHandle`
449/// `d_instance_p`:
450/// @code
451/// template <class INSTANCE>
452/// inline
453/// my_CountedHandleRep<INSTANCE>::~my_CountedHandleRep()
454/// {
455/// delete d_instance_p;
456/// }
457/// @endcode
458/// Next, we define method `increment`, which atomically increments the number
459/// of references to this `my_CountedHandleRep`. Since our caller is not
460/// interested in the result (and our return type is thus `void`), we use
461/// `incrementInt` instead of `incrementIntNv`.
462/// @code
463/// // MANIPULATORS
464/// template <class INSTANCE>
465/// inline
466/// void my_CountedHandleRep<INSTANCE>::increment()
467/// {
468/// bsls::AtomicOperations::incrementInt(&d_count);
469/// }
470/// @endcode
471/// Then, we implement method `decrement`, which atomically decrements the
472/// reference count; since our caller will need to check the resulting value to
473/// determine whether the `INSTANCE` should be deleted, we use `decrementIntNv`
474/// rather than `decrementInt`, and return the new number of references:
475/// @code
476/// template <class INSTANCE>
477/// inline
478/// int my_CountedHandleRep<INSTANCE>::decrement()
479/// {
480/// return bsls::AtomicOperations::decrementIntNv(&d_count);
481/// }
482/// @endcode
483///
484/// #### Function Definitions for my_CountedHandle {#bsls_atomicoperations-function-definitions-for-my_countedhandle}
485///
486///
487/// Next, we define the first constructor for `my_CountedHandle`, which is used
488/// when creating a handle for a new `INSTANCE`; note that the `INSTANCE` is
489/// constructed separately, and a pointer to that object is passed as the first
490/// argument (`object`):
491/// @code
492/// // ----------------------
493/// // class my_CountedHandle
494/// // ----------------------
495///
496/// template <class INSTANCE>
497/// inline
498/// my_CountedHandle<INSTANCE>::my_CountedHandle(INSTANCE *instance)
499/// {
500/// d_rep_p = new my_CountedHandleRep<INSTANCE>(instance);
501/// }
502/// @endcode
503/// Then, we define the copy constructor; the new object copies the underlying
504/// `my_CountedHandleRep` and then increments its counter:
505/// @code
506/// template <class INSTANCE>
507/// inline
508/// my_CountedHandle<INSTANCE>::my_CountedHandle(
509/// const my_CountedHandle<INSTANCE>& other)
510/// : d_rep_p(other.d_rep_p)
511/// {
512/// if (d_rep_p) {
513/// d_rep_p->increment();
514/// }
515/// }
516/// @endcode
517/// Next, we define the destructor that decrements the "rep" object's reference
518/// count using the `decrement` method. The `decrement` method returns the
519/// object's reference count after the decrement is completed, and
520/// `my_CountedHandle` uses this value to determine whether the "rep" object
521/// should be deleted:
522/// @code
523/// template <class INSTANCE>
524/// inline
525/// my_CountedHandle<INSTANCE>::~my_CountedHandle()
526/// {
527/// if (d_rep_p && 0 == d_rep_p->decrement()) {
528/// my_CountedHandleRep<INSTANCE>::deleteObject(d_rep_p);
529/// }
530/// }
531/// @endcode
532/// Now, we define member `operator->()`, which provides basic pointer semantics
533/// for `my_CountedHandle`:
534/// @code
535/// template <class INSTANCE>
536/// inline
537/// INSTANCE *my_CountedHandle<INSTANCE>::operator->() const
538/// {
539/// return d_rep_p->d_instance_p;
540/// }
541/// @endcode
542/// Finally, we define method `numReferences`, which returns the value of the
543/// reference counter:
544/// @code
545/// template <class INSTANCE>
546/// inline
547/// int my_CountedHandle<INSTANCE>::numReferences() const
548/// {
549/// return d_rep_p ? bsls::AtomicOperations::getInt(d_rep_p->d_count) : 0;
550/// }
551/// @endcode
552/// Note that, while class `my_CountedHandleRep` is itself fully thread-safe, it
553/// does not guarantee thread safety for the `INSTANCE` object. In order to
554/// provide thread safety for the `INSTANCE` in the general case, the "rep"
555/// would need to use a more general concurrency mechanism such as a mutex.
556///
557/// ### Example 3: Thread-Safe Lock-Free Singly-Linked List {#bsls_atomicoperations-example-3-thread-safe-lock-free-singly-linked-list}
558///
559///
560/// This example demonstrates the use of atomic pointers to implement a fast and
561/// thread-aware, yet fast single-linked list. The example class,
562/// `my_PtrStack`, is a templatized pointer stack, supporting `push` and `pop`
563/// methods. The class is implemented using a single-linked list. Nodes in the
564/// list are linked together using atomic operations. Instance of this
565/// structure are allocated using the provided allocator. When nodes are freed,
566/// they are cached on a free list. This free list is also implemented as a
567/// single-linked list, using atomic pointer operations.
568///
569/// First, we create class template, `my_PtrStack`, parameterized by `TYPE`.
570/// Instances of this template maintain a list of nodes and a free-node list.
571/// Each node has a pointer to a data item, `d_item_p`, a link to the next node
572/// in the list, `d_next_p`. The definition of the `my_PtrStack` class is
573/// provided below:
574/// @code
575/// template <class TYPE>
576/// class my_PtrStack {
577/// // TYPES
578/// struct Node {
579/// TYPE *d_item_p;
580/// Node *d_next_p;
581/// };
582///
583/// // DATA
584/// bsls::AtomicOperations::AtomicTypes::Pointer d_list_p;
585/// bsls::AtomicOperations::AtomicTypes::Pointer d_freeList_p;
586///
587/// // PRIVATE MANIPULATORS
588/// Node *allocateNode();
589/// void freeNode(Node *node);
590/// void deleteNodes(Node *node);
591///
592/// public:
593/// // CREATORS
594/// my_PtrStack();
595/// ~my_PtrStack();
596///
597/// // MANIPULATORS
598/// void push(TYPE *item);
599/// TYPE *pop();
600/// };
601/// @endcode
602/// Then, we write the constructor that initializes the pointers for the node
603/// list and the free list:
604/// @code
605/// // CREATORS
606/// template <class TYPE>
607/// inline my_PtrStack<TYPE>::my_PtrStack()
608/// {
609/// bsls::AtomicOperations::initPointer(&d_freeList_p, 0);
610/// bsls::AtomicOperations::initPointer(&d_list_p, 0);
611/// }
612/// @endcode
613/// Next, we define the `deleteNodes` and the destructor function to delete
614/// nodes that the `my_PtrStack` object owns. Note that we don't need to worry
615/// about the concurrent access to node lists in the destructor, as destructor
616/// can be executed in only a single thread:
617/// @code
618/// template <class TYPE>
619/// inline void my_PtrStack<TYPE>::deleteNodes(Node *node)
620/// {
621/// while (node) {
622/// Node *next = node->d_next_p;
623/// delete node;
624/// node = next;
625/// }
626/// }
627///
628/// template <class TYPE>
629/// inline my_PtrStack<TYPE>::~my_PtrStack()
630/// {
631/// deleteNodes(
632/// (Node *) bsls::AtomicOperations::getPtrRelaxed(&d_list_p));
633/// deleteNodes(
634/// (Node *) bsls::AtomicOperations::getPtrRelaxed(&d_freeList_p));
635/// }
636/// @endcode
637/// Then, we define method `allocateNode` to get a node from the free list in
638/// the thread-safe manner by leveraging atomic operations to ensure proper
639/// thread synchronization:
640/// @code
641/// // PRIVATE MANIPULATORS
642/// template <class TYPE>
643/// inline typename my_PtrStack<TYPE>::Node *my_PtrStack<TYPE>::allocateNode()
644/// {
645/// Node *node;
646/// @endcode
647/// To remove an item from this list, get the current list head using `getPtr`.
648/// Then, test and swap it with the next node. `testAndSwapPtr` compares
649/// `d_freeList_p` to `node`, replacing it with `node->d_next_p` only if it
650/// matches. If `d_freeList_p` did not match `node`, then the free list has
651/// been changed on another thread, between the calls to `getPtr` and
652/// `testAndSwapPtr`. If the list head has changed, then try again:
653/// @code
654/// do {
655/// node = (Node*) bsls::AtomicOperations::getPtr(&d_freeList_p);
656/// if (!node) break;
657/// } while (bsls::AtomicOperations::testAndSwapPtr(
658/// &d_freeList_p,
659/// node,
660/// node->d_next_p) != node);
661/// @endcode
662/// Next, we allocate a new node if there are no nodes in the free node list:
663/// @code
664/// if (!node) {
665/// node = new Node();
666/// }
667/// return node;
668/// }
669/// @endcode
670/// Then, we provide the `freeNode` method to add a given `node` to the free
671/// list. To add the node to the list, we set the next pointer of the new node
672/// to the current value of the list head, and atomically test and swap the head
673/// of the list with the new node. If the list head has been changed (by
674/// another thread), we try again:
675/// @code
676/// template <class TYPE>
677/// inline void my_PtrStack<TYPE>::freeNode(Node *node)
678/// {
679/// do {
680/// node->d_next_p = (Node*) bsls::AtomicOperations::getPtr(
681/// &d_freeList_p);
682/// } while (bsls::AtomicOperations::testAndSwapPtr(
683/// &d_freeList_p,
684/// node->d_next_p,
685/// node) != node->d_next_p);
686/// }
687/// @endcode
688/// Now, we begin to define the public "stack-like" interface for `my_PtrStack`.
689/// Note that the `push` method is similar to `freeNode`, except that it assigns
690/// an item value and operates on `d_list_p`, which maintains the list of active
691/// nodes:
692/// @code
693/// template <class TYPE>
694/// inline void my_PtrStack<TYPE>::push(TYPE *item)
695/// {
696/// Node *node = allocateNode();
697/// node->d_item_p = item;
698/// do {
699/// node->d_next_p = (Node*) bsls::AtomicOperations::getPtr(&d_list_p);
700/// } while (bsls::AtomicOperations::testAndSwapPtr(
701/// &d_list_p,
702/// node->d_next_p,
703/// node)!= node->d_next_p);
704/// }
705/// @endcode
706/// Finally, we define the `pop` method that removes the node from the top of
707/// active node list, `d_list_p`, adds it to the free-node list, and returns the
708/// data item contained in the node to the caller:
709/// @code
710/// template <class TYPE>
711/// inline TYPE *my_PtrStack<TYPE>::pop()
712/// {
713/// Node *node;
714/// do {
715/// node = (Node*) bsls::AtomicOperations::getPtr(&d_list_p);
716/// if (!node) break;
717/// } while (bsls::AtomicOperations::testAndSwapPtr(
718/// &d_freeList_p,
719/// node,
720/// node->d_next_p)!= node);
721/// TYPE *item = node ? node->d_item_p : 0;
722/// if (node)
723/// freeNode(node);
724/// return item;
725/// }
726/// @endcode
727/// Notice that if the stack was empty, a NULL pointer is returned.
728/// @}
729/** @} */
730/** @} */
731
732/** @addtogroup bsl
733 * @{
734 */
735/** @addtogroup bsls
736 * @{
737 */
738/** @addtogroup bsls_atomicoperations
739 * @{
740 */
741
742#include <bsls_platform.h>
743#include <bsls_types.h>
744
745#if defined(BSLS_PLATFORM_CMP_CLANG)
746#if __has_extension(c_atomic) || __has_extension(cxx_atomic) // clang 3.1+
747#define BSLS_ATOMICOPERATIONS_CLANG_ATOMICS
748#endif
749#endif
750
751#if defined(BSLS_ATOMICOPERATIONS_CLANG_ATOMICS)
752 // clang 3.1+
754
755#elif defined(BSLS_PLATFORM_CMP_GNU) && BSLS_PLATFORM_CMP_VERSION >= 40700
756 // GCC 4.7+
758
759#elif defined(BSLS_PLATFORM_CPU_X86)
760
761# if defined(BSLS_PLATFORM_CMP_GNU) || defined(BSLS_PLATFORM_CMP_CLANG)
763# elif defined(BSLS_PLATFORM_CMP_MSVC)
765# else
766# define BSLS_ATOMICOPERATIONS_ERROR
767# endif
768
769#elif defined(BSLS_PLATFORM_CPU_X86_64)
770
771# if defined(BSLS_PLATFORM_CMP_GNU) || defined(BSLS_PLATFORM_CMP_CLANG)
773# elif defined(BSLS_PLATFORM_CMP_MSVC)
775# else
776# define BSLS_ATOMICOPERATIONS_ERROR
777# endif
778
779#elif defined(BSLS_PLATFORM_CPU_POWERPC)
780
781# if defined(BSLS_PLATFORM_CMP_IBM)
782# if defined(BSLS_PLATFORM_CPU_64_BIT)
784# else
786# endif
787# elif defined(BSLS_PLATFORM_CMP_GNU)
789# else
790# define BSLS_ATOMICOPERATIONS_ERROR
791# endif
792
793#elif defined(BSLS_PLATFORM_CPU_SPARC_32) \
794 && (defined(BSLS_PLATFORM_CMP_GNU) || defined(BSLS_PLATFORM_CMP_SUN))
796
797#elif defined(BSLS_PLATFORM_CPU_SPARC_V9) \
798 && (defined(BSLS_PLATFORM_CMP_GNU) || defined(BSLS_PLATFORM_CMP_SUN))
800
801#elif defined(BSLS_PLATFORM_CPU_ARM)
802# if defined(BSLS_PLATFORM_CMP_GNU) || defined(BSLS_PLATFORM_CMP_CLANG)
804# elif defined(BSLS_PLATFORM_CMP_MSVC)
805# if defined(BSLS_PLATFORM_CPU_64_BIT)
807# else
809# endif
810# else
811# define BSLS_ATOMICOPERATIONS_ERROR
812# endif
813
814#else
815# define BSLS_ATOMICOPERATIONS_ERROR
816#endif
817
818#if defined(BSLS_ATOMICOPERATIONS_ERROR)
819# error "no implementation of atomics found for this platform"
820#endif
821
822
823
824namespace bsls {
825
826 // =======================
827 // struct AtomicOperations
828 // =======================
829
830/// `AtomicOperations` provides a namespace for a suite of atomic operations
831/// on the following types as defined by the `AtomicTypes` typedef:
832/// integer - `AtomicTypes::Int`, 64bit integer - `AtomicTypes::Int64`,
833/// pointer - `AtomicTypes::Pointer`.
835
836 // TYPES
837 typedef AtomicOperations_Imp Imp;
839
840 // *** atomic functions for int ***
841
842 // CLASS METHODS
843
844 /// Atomically retrieve the value of the specified `atomicInt`,
845 /// providing the sequential consistency memory ordering guarantee.
846 static int getInt(AtomicTypes::Int const *atomicInt);
847
848 /// Atomically retrieve the value of the specified `atomicInt`,
849 /// providing the acquire memory ordering guarantee.
850 static int getIntAcquire(AtomicTypes::Int const *atomicInt);
851
852 /// Atomically retrieve the value of the specified `atomicInt`, without
853 /// providing any memory ordering guarantees.
854 static int getIntRelaxed(AtomicTypes::Int const *atomicInt);
855
856 /// Initialize the specified `atomicInt` and set its value to the
857 /// optionally specified `initialValue`.
858 static void initInt(AtomicTypes::Int *atomicInt, int initialValue = 0);
859
860 /// Atomically set the value of the specified `atomicInt` to the
861 /// specified `value`, providing the sequential consistency memory
862 /// ordering guarantee.
863 static void setInt(AtomicTypes::Int *atomicInt, int value);
864
865 /// Atomically set the value of the specified `atomicInt` to the
866 /// specified `value`, without providing any memory ordering guarantees.
867 static void setIntRelaxed(AtomicTypes::Int *atomicInt, int value);
868
869 /// Atomically set the value of the specified `atomicInt` to the
870 /// specified `value`, providing the release memory ordering guarantee.
871 static void setIntRelease(AtomicTypes::Int *atomicInt, int value);
872
873 /// Atomically set the value of the specified `atomicInt` to the
874 /// specified `swapValue`, and return its previous value, providing the
875 /// sequential consistency memory ordering guarantee.
876 static int swapInt(AtomicTypes::Int *atomicInt, int swapValue);
877
878 /// Atomically set the value of the specified `atomicInt` to the
879 /// specified `swapValue`, and return its previous value, providing the
880 /// acquire/release memory ordering guarantee.
881 static int swapIntAcqRel(AtomicTypes::Int *atomicInt, int swapValue);
882
883 /// Conditionally set the value of the specified `atomicInt` to the
884 /// specified `swapValue` if and only if the value of `atomicInt` equals
885 /// the value of the specified `compareValue`, and return the initial
886 /// value of `atomicInt`, providing the sequential consistency memory
887 /// ordering guarantee. The whole operation is performed atomically.
888 static int testAndSwapInt(AtomicTypes::Int *atomicInt,
889 int compareValue,
890 int swapValue);
891
892 /// Conditionally set the value of the specified `atomicInt` to the
893 /// specified `swapValue` if and only if the value of `atomicInt` equals
894 /// the value of the specified `compareValue`, and return the initial
895 /// value of `atomicInt`, providing the acquire/release memory ordering
896 /// guarantee. The whole operation is performed atomically.
897 static int testAndSwapIntAcqRel(AtomicTypes::Int *atomicInt,
898 int compareValue,
899 int swapValue);
900
901 /// Atomically add to the specified `atomicInt` the specified `value`,
902 /// providing the sequential consistency memory ordering guarantee.
903 static void addInt(AtomicTypes::Int *atomicInt, int value);
904
905 /// Atomically add to the specified `atomicInt` the specified `value`,
906 /// providing the acquire/release memory ordering guarantee.
907 static void addIntAcqRel(AtomicTypes::Int *atomicInt, int value);
908
909 /// Atomically add to the specified `atomicInt` the specified `value`,
910 /// without providing any memory ordering guarantees.
911 static void addIntRelaxed(AtomicTypes::Int *atomicInt, int value);
912
913 /// Atomically add to the specified `atomicInt` the specified `value`
914 /// and return the resulting value, providing the sequential consistency
915 /// memory ordering guarantee.
916 static int addIntNv(AtomicTypes::Int *atomicInt, int value);
917
918 /// Atomically add to the specified `atomicInt` the specified `value`
919 /// and return the resulting value, providing the acquire/release memory
920 /// ordering guarantee.
921 static int addIntNvAcqRel(AtomicTypes::Int *atomicInt, int value);
922
923 /// Atomically add to the specified `atomicInt` the specified `value`
924 /// and return the resulting value, without providing any memory
925 /// ordering guarantees.
926 static int addIntNvRelaxed(AtomicTypes::Int *atomicInt, int value);
927
928 /// Atomically decrement the value of the specified `atomicInt` by 1,
929 /// providing the sequential consistency memory ordering guarantee.
930 static void decrementInt(AtomicTypes::Int *atomicInt);
931
932 /// Atomically decrement the value of the specified `atomicInt` by 1,
933 /// providing the acquire/release memory ordering guarantee.
934 static void decrementIntAcqRel(AtomicTypes::Int *atomicInt);
935
936 /// Atomically decrement the specified `atomicInt` by 1 and return the
937 /// resulting value, providing the sequential consistency memory
938 /// ordering guarantee.
939 static int decrementIntNv(AtomicTypes::Int *atomicInt);
940
941 /// Atomically decrement the specified `atomicInt` by 1 and return the
942 /// resulting value, providing the acquire/release memory ordering
943 /// guarantee.
944 static int decrementIntNvAcqRel(AtomicTypes::Int *atomicInt);
945
946 /// Atomically increment the value of the specified `atomicInt` by 1,
947 /// providing the sequential consistency memory ordering guarantee.
948 static void incrementInt(AtomicTypes::Int *atomicInt);
949
950 /// Atomically increment the value of the specified `atomicInt` by 1,
951 /// providing the acquire/release memory ordering guarantee.
952 static void incrementIntAcqRel(AtomicTypes::Int *atomicInt);
953
954 /// Atomically increment the specified `atomicInt` by 1 and return the
955 /// resulting value, providing the sequential consistency memory
956 /// ordering guarantee.
957 static int incrementIntNv(AtomicTypes::Int *atomicInt);
958
959 /// Atomically increment the specified `atomicInt` by 1 and return the
960 /// resulting value, providing the acquire/release memory ordering
961 /// guarantee.
962 static int incrementIntNvAcqRel(AtomicTypes::Int *atomicInt);
963
964 /// Atomically subtract from the specified `atomicInt` the specified
965 /// `value` and return the resulting value, providing the sequential
966 /// consistency memory ordering guarantee.
967 static int subtractIntNv(AtomicTypes::Int *atomicInt,int value);
968
969 /// Atomically subtract from the specified `atomicInt` the specified
970 /// `value` and return the resulting value, providing the
971 /// acquire/release memory ordering guarantee.
972 static int subtractIntNvAcqRel(AtomicTypes::Int *atomicInt, int value);
973
974 /// Atomically subtract from the specified `atomicInt` the specified
975 /// `value` and return the resulting value, without providing any memory
976 /// ordering guarantees.
977 static int subtractIntNvRelaxed(AtomicTypes::Int *atomicInt, int value);
978
979 // *** atomic functions for Int64 ***
980
981 /// Atomically retrieve the value of the specified `atomicInt`,
982 /// providing the sequential consistency memory ordering guarantee.
983 static Types::Int64 getInt64(AtomicTypes::Int64 const *atomicInt);
984
985 /// Atomically retrieve the value of the specified `atomicInt`,
986 /// providing the acquire memory ordering guarantee.
987 static Types::Int64 getInt64Acquire(AtomicTypes::Int64 const *atomicInt);
988
989 /// Atomically retrieve the value of the specified `atomicInt`, without
990 /// providing any memory ordering guarantees.
991 static Types::Int64 getInt64Relaxed(AtomicTypes::Int64 const *atomicInt);
992
993 /// Initialize the specified `atomicInt` and set its value to the
994 /// optionally specified `initialValue`.
995 static void initInt64(AtomicTypes::Int64 *atomicInt,
996 Types::Int64 initialValue = 0);
997
998 /// Atomically set the value of the specified `atomicInt` to the
999 /// specified `value`, providing the sequential consistency memory
1000 /// ordering guarantee.
1001 static void setInt64(AtomicTypes::Int64 *atomicInt,
1002 Types::Int64 value);
1003
1004 /// Atomically set the value of the specified `atomicInt` to the
1005 /// specified `value`, without providing any memory ordering guarantees.
1006 static void setInt64Relaxed(AtomicTypes::Int64 *atomicInt,
1007 Types::Int64 value);
1008
1009 /// Atomically set the value of the specified `atomicInt` to the
1010 /// specified `value`, providing the release memory ordering guarantee.
1011 static void setInt64Release(AtomicTypes::Int64 *atomicInt,
1012 Types::Int64 value);
1013
1014 /// Atomically set the value of the specified `atomicInt` to the
1015 /// specified `swapValue` and return its previous value, providing the
1016 /// sequential consistency memory ordering guarantee.
1017 static Types::Int64 swapInt64(AtomicTypes::Int64 *atomicInt,
1018 Types::Int64 swapValue);
1019
1020 /// Atomically set the value of the specified `atomicInt` to the
1021 /// specified `swapValue` and return its previous value, providing the
1022 /// acquire/release memory ordering guarantee.
1023 static Types::Int64 swapInt64AcqRel(AtomicTypes::Int64 *atomicInt,
1024 Types::Int64 swapValue);
1025
1026 /// Conditionally set the value of the specified `atomicInt` to the
1027 /// specified `swapValue` if and only if the value of `atomicInt` equals
1028 /// the value of the specified `compareValue`, and return the initial
1029 /// value of `atomicInt`, providing the sequential consistency memory
1030 /// ordering guarantee. The whole operation is performed atomically.
1031 static Types::Int64 testAndSwapInt64(AtomicTypes::Int64 *atomicInt,
1032 Types::Int64 compareValue,
1033 Types::Int64 swapValue);
1034
1035 /// Conditionally set the value of the specified `atomicInt` to the
1036 /// specified `swapValue` if and only if the value of `atomicInt` equals
1037 /// the value of the specified `compareValue`, and return the initial
1038 /// value of `atomicInt`, providing the acquire/release memory ordering
1039 /// guarantee. The whole operation is performed atomically.
1041 AtomicTypes::Int64 *atomicInt,
1042 Types::Int64 compareValue,
1043 Types::Int64 swapValue);
1044
1045 /// Atomically add to the specified `atomicInt` the specified `value`,
1046 /// providing the sequential consistency memory ordering guarantee.
1047 static void addInt64(AtomicTypes::Int64 *atomicInt,
1048 Types::Int64 value);
1049
1050 /// Atomically add to the specified `atomicInt` the specified `value`,
1051 /// providing the acquire/release memory ordering guarantee.
1052 static void addInt64AcqRel(AtomicTypes::Int64 *atomicInt,
1053 Types::Int64 value);
1054
1055 /// Atomically add to the specified `atomicInt` the specified `value`,
1056 /// without providing any memory ordering guarantees.
1057 static void addInt64Relaxed(AtomicTypes::Int64 *atomicInt,
1058 Types::Int64 value);
1059
1060 /// Atomically add to the specified `atomicInt` the specified `value`
1061 /// and return the resulting value, providing the sequential consistency
1062 /// memory ordering guarantee.
1063 static Types::Int64 addInt64Nv(AtomicTypes::Int64 *atomicInt,
1064 Types::Int64 value);
1065
1066 /// Atomically add to the specified `atomicInt` the specified `value`
1067 /// and return the resulting value, providing the acquire/release memory
1068 /// ordering guarantee.
1069 static Types::Int64 addInt64NvAcqRel(AtomicTypes::Int64 *atomicInt,
1070 Types::Int64 value);
1071
1072 /// Atomically add to the specified `atomicInt` the specified `value`
1073 /// and return the resulting value, without providing any memory
1074 /// ordering guarantees.
1075 static Types::Int64 addInt64NvRelaxed(AtomicTypes::Int64 *atomicInt,
1076 Types::Int64 value);
1077
1078 /// Atomically decrement the specified `atomicInt` by 1, providing the
1079 /// sequential consistency memory ordering guarantee.
1080 static void decrementInt64(AtomicTypes::Int64 *atomicInt);
1081
1082 /// Atomically decrement the specified `atomicInt` by 1, providing the
1083 /// acquire/release memory ordering guarantee.
1084 static void decrementInt64AcqRel(AtomicTypes::Int64 *atomicInt);
1085
1086 /// Atomically decrement the specified `atomicInt` by 1 and return the
1087 /// resulting value, providing the sequential consistency memory
1088 /// ordering guarantee.
1089 static Types::Int64 decrementInt64Nv(AtomicTypes::Int64 *atomicInt);
1090
1091 /// Atomically decrement the specified `atomicInt` by 1 and return the
1092 /// resulting value, providing the acquire/release memory ordering
1093 /// guarantee.
1094 static Types::Int64 decrementInt64NvAcqRel(AtomicTypes::Int64 *atomicInt);
1095
1096 /// Atomically increment the value of the specified `atomicInt` by 1,
1097 /// providing the sequential consistency memory ordering guarantee.
1098 static void incrementInt64(AtomicTypes::Int64 *atomicInt);
1099
1100 /// Atomically increment the value of the specified `atomicInt` by 1,
1101 /// providing the acquire/release memory ordering guarantee.
1102 static void incrementInt64AcqRel(AtomicTypes::Int64 *atomicInt);
1103
1104 /// Atomically increment the specified `atomicInt` by 1 and return the
1105 /// resulting value, providing the sequential consistency memory
1106 /// ordering guarantee.
1107 static Types::Int64 incrementInt64Nv(AtomicTypes::Int64 *atomicInt);
1108
1109 /// Atomically increment the specified `atomicInt` by 1 and return the
1110 /// resulting value, providing the acquire/release memory ordering
1111 /// guarantee.
1112 static Types::Int64 incrementInt64NvAcqRel(AtomicTypes::Int64 *atomicInt);
1113
1114 /// Atomically subtract from the specified `atomicInt` the specified
1115 /// `value` and return the resulting value, providing the sequential
1116 /// consistency memory ordering guarantee.
1117 static Types::Int64 subtractInt64Nv(AtomicTypes::Int64 *atomicInt,
1118 Types::Int64 value);
1119
1120 /// Atomically subtract from the specified `atomicInt` the specified
1121 /// `value` and return the resulting value, providing the
1122 /// acquire/release memory ordering guarantee.
1123 static Types::Int64 subtractInt64NvAcqRel(AtomicTypes::Int64 *atomicInt,
1124 Types::Int64 value);
1125
1126 /// Atomically subtract from the specified `atomicInt` the specified
1127 /// `value` and return the resulting value, without providing any memory
1128 /// ordering guarantees.
1129 static Types::Int64 subtractInt64NvRelaxed(AtomicTypes::Int64 *atomicInt,
1130 Types::Int64 value);
1131
1132 // *** atomic functions for unsigned int ***
1133
1134 // CLASS METHODS
1135
1136 /// Atomically retrieve the value of the specified `atomicUint`,
1137 /// providing the sequential consistency memory ordering guarantee.
1138 static unsigned int getUint(AtomicTypes::Uint const *atomicUint);
1139
1140 /// Atomically retrieve the value of the specified `atomicUint`,
1141 /// providing the acquire memory ordering guarantee.
1142 static unsigned int getUintAcquire(AtomicTypes::Uint const *atomicUint);
1143
1144 /// Atomically retrieve the value of the specified `atomicUint`, without
1145 /// providing any memory ordering guarantees.
1146 static unsigned int getUintRelaxed(AtomicTypes::Uint const *atomicUint);
1147
1148 /// Initialize the specified `atomicUint` and set its value to the
1149 /// optionally specified `initialValue`.
1150 static void initUint(AtomicTypes::Uint *atomicUint,
1151 unsigned int initialValue = 0);
1152
1153 /// Atomically set the value of the specified `atomicUint` to the
1154 /// specified `value`, providing the sequential consistency memory
1155 /// ordering guarantee.
1156 static void setUint(AtomicTypes::Uint *atomicUint, unsigned int value);
1157
1158 /// Atomically set the value of the specified `atomicUint` to the
1159 /// specified `value`, without providing any memory ordering guarantees.
1160 static void setUintRelaxed(AtomicTypes::Uint *atomicUint,
1161 unsigned int value);
1162
1163 /// Atomically set the value of the specified `atomicUint` to the
1164 /// specified `value`, providing the release memory ordering guarantee.
1165 static void setUintRelease(AtomicTypes::Uint *atomicUint,
1166 unsigned int value);
1167
1168 /// Atomically set the value of the specified `atomicUint` to the
1169 /// specified `swapValue`, and return its previous value, providing the
1170 /// sequential consistency memory ordering guarantee.
1171 static unsigned int swapUint(AtomicTypes::Uint *atomicUint,
1172 unsigned int swapValue);
1173
1174 /// Atomically set the value of the specified `atomicUint` to the
1175 /// specified `swapValue`, and return its previous value, providing the
1176 /// acquire/release memory ordering guarantee.
1177 static unsigned int swapUintAcqRel(AtomicTypes::Uint *atomicUint,
1178 unsigned int swapValue);
1179
1180 /// Conditionally set the value of the specified `atomicUint` to the
1181 /// specified `swapValue` if and only if the value of `atomicUint`
1182 /// equals the value of the specified `compareValue`, and return the
1183 /// initial value of `atomicUint`, providing the sequential consistency
1184 /// memory ordering guarantee. The whole operation is performed
1185 /// atomically.
1186 static unsigned int testAndSwapUint(AtomicTypes::Uint *atomicUint,
1187 unsigned int compareValue,
1188 unsigned int swapValue);
1189
1190 /// Conditionally set the value of the specified `atomicUint` to the
1191 /// specified `swapValue` if and only if the value of `atomicInt` equals
1192 /// the value of the specified `compareValue`, and return the initial
1193 /// value of `atomicUint`, providing the acquire/release memory ordering
1194 /// guarantee. The whole operation is performed atomically.
1195 static unsigned int testAndSwapUintAcqRel(AtomicTypes::Uint *atomicUint,
1196 unsigned int compareValue,
1197 unsigned int swapValue);
1198
1199 /// Atomically add to the specified `atomicUint` the specified `value`,
1200 /// providing the sequential consistency memory ordering guarantee.
1201 static void addUint(AtomicTypes::Uint *atomicUint, unsigned int value);
1202
1203 /// Atomically add to the specified `atomicUint` the specified `value`,
1204 /// providing the acquire/release memory ordering guarantee.
1205 static void addUintAcqRel(AtomicTypes::Uint *atomicUint,
1206 unsigned int value);
1207
1208 /// Atomically add to the specified `atomicUint` the specified `value`,
1209 /// without providing any memory ordering guarantees.
1210 static void addUintRelaxed(AtomicTypes::Uint *atomicUint,
1211 unsigned int value);
1212
1213 /// Atomically add to the specified `atomicUint` the specified `value`
1214 /// and return the resulting value, providing the sequential consistency
1215 /// memory ordering guarantee.
1216 static unsigned int addUintNv(AtomicTypes::Uint *atomicUint,
1217 unsigned int value);
1218
1219 /// Atomically add to the specified `atomicUint` the specified `value`
1220 /// and return the resulting value, providing the acquire/release memory
1221 /// ordering guarantee.
1222 static unsigned int addUintNvAcqRel(AtomicTypes::Uint *atomicUint,
1223 unsigned int value);
1224
1225 /// Atomically add to the specified `atomicUint` the specified `value`
1226 /// and return the resulting value, without providing any memory
1227 /// ordering guarantees.
1228 static unsigned int addUintNvRelaxed(AtomicTypes::Uint *atomicUint,
1229 unsigned int value);
1230
1231 /// Atomically decrement the value of the specified `atomicUint` by 1,
1232 /// providing the sequential consistency memory ordering guarantee.
1233 static void decrementUint(AtomicTypes::Uint *atomicUint);
1234
1235 /// Atomically decrement the value of the specified `atomicUint` by 1,
1236 /// providing the acquire/release memory ordering guarantee.
1237 static void decrementUintAcqRel(AtomicTypes::Uint *atomicUint);
1238
1239 /// Atomically decrement the specified `atomicUint` by 1 and return the
1240 /// resulting value, providing the sequential consistency memory
1241 /// ordering guarantee.
1242 static unsigned int decrementUintNv(AtomicTypes::Uint *atomicUint);
1243
1244 /// Atomically decrement the specified `atomicUint` by 1 and return the
1245 /// resulting value, providing the acquire/release memory ordering
1246 /// guarantee.
1247 static unsigned int decrementUintNvAcqRel(AtomicTypes::Uint *atomicUint);
1248
1249 /// Atomically increment the value of the specified `atomicUint` by 1,
1250 /// providing the sequential consistency memory ordering guarantee.
1251 static void incrementUint(AtomicTypes::Uint *atomicUint);
1252
1253 /// Atomically increment the value of the specified `atomicUint` by 1,
1254 /// providing the acquire/release memory ordering guarantee.
1255 static void incrementUintAcqRel(AtomicTypes::Uint *atomicUint);
1256
1257 /// Atomically increment the specified `atomicUint` by 1 and return the
1258 /// resulting value, providing the sequential consistency memory
1259 /// ordering guarantee.
1260 static unsigned int incrementUintNv(AtomicTypes::Uint *atomicUint);
1261
1262 /// Atomically increment the specified `atomicUint` by 1 and return the
1263 /// resulting value, providing the acquire/release memory ordering
1264 /// guarantee.
1265 static unsigned int incrementUintNvAcqRel(AtomicTypes::Uint *atomicUint);
1266
1267 /// Atomically subtract from the specified `atomicUint` the specified
1268 /// `value` and return the resulting value, providing the sequential
1269 /// consistency memory ordering guarantee.
1270 static unsigned int subtractUintNv(AtomicTypes::Uint *atomicUint,
1271 unsigned int value);
1272
1273 /// Atomically subtract from the specified `atomicUint` the specified
1274 /// `value` and return the resulting value, providing the
1275 /// acquire/release memory ordering guarantee.
1276 static unsigned int subtractUintNvAcqRel(AtomicTypes::Uint *atomicUint,
1277 unsigned int value);
1278
1279 /// Atomically subtract from the specified `atomicUint` the specified
1280 /// `value` and return the resulting value, without providing any memory
1281 /// ordering guarantees.
1282 static unsigned int subtractUintNvRelaxed(AtomicTypes::Uint *atomicUint,
1283 unsigned int value);
1284
1285 // *** atomic functions for Uint64 ***
1286
1287 /// Atomically retrieve the value of the specified `atomicUint`,
1288 /// providing the sequential consistency memory ordering guarantee.
1289 static Types::Uint64 getUint64(AtomicTypes::Uint64 const *atomicUint);
1290
1291 /// Atomically retrieve the value of the specified `atomicUint`,
1292 /// providing the acquire memory ordering guarantee.
1294 AtomicTypes::Uint64 const *atomicUint);
1295
1296 /// Atomically retrieve the value of the specified `atomicUint`, without
1297 /// providing any memory ordering guarantees.
1299 AtomicTypes::Uint64 const *atomicUint);
1300
1301 /// Initialize the specified `atomicUint` and set its value to the
1302 /// optionally specified `initialValue`.
1303 static void initUint64(AtomicTypes::Uint64 *atomicUint,
1304 Types::Uint64 initialValue = 0);
1305
1306 /// Atomically set the value of the specified `atomicUint` to the
1307 /// specified `value`, providing the sequential consistency memory
1308 /// ordering guarantee.
1309 static void setUint64(AtomicTypes::Uint64 *atomicUint,
1310 Types::Uint64 value);
1311
1312 /// Atomically set the value of the specified `atomicUint` to the
1313 /// specified `value`, without providing any memory ordering guarantees.
1314 static void setUint64Relaxed(AtomicTypes::Uint64 *atomicUint,
1315 Types::Uint64 value);
1316
1317 /// Atomically set the value of the specified `atomicUint` to the
1318 /// specified `value`, providing the release memory ordering guarantee.
1319 static void setUint64Release(AtomicTypes::Uint64 *atomicUint,
1320 Types::Uint64 value);
1321
1322 /// Atomically set the value of the specified `atomicUint` to the
1323 /// specified `swapValue` and return its previous value, providing the
1324 /// sequential consistency memory ordering guarantee.
1325 static Types::Uint64 swapUint64(AtomicTypes::Uint64 *atomicUint,
1326 Types::Uint64 swapValue);
1327
1328 /// Atomically set the value of the specified `atomicUint` to the
1329 /// specified `swapValue` and return its previous value, providing the
1330 /// acquire/release memory ordering guarantee.
1331 static Types::Uint64 swapUint64AcqRel(AtomicTypes::Uint64 *atomicUint,
1332 Types::Uint64 swapValue);
1333
1334 /// Conditionally set the value of the specified `atomicUint` to the
1335 /// specified `swapValue` if and only if the value of `atomicUint`
1336 /// equals the value of the specified `compareValue`, and return the
1337 /// initial value of `atomicUint`, providing the sequential consistency
1338 /// memory ordering guarantee. The whole operation is performed
1339 /// atomically.
1340 static Types::Uint64 testAndSwapUint64(AtomicTypes::Uint64 *atomicUint,
1341 Types::Uint64 compareValue,
1342 Types::Uint64 swapValue);
1343
1344 /// Conditionally set the value of the specified `atomicUint` to the
1345 /// specified `swapValue` if and only if the value of `atomicUint`
1346 /// equals the value of the specified `compareValue`, and return the
1347 /// initial value of `atomicUint`, providing the acquire/release memory
1348 /// ordering guarantee. The whole operation is performed atomically.
1350 AtomicTypes::Uint64 *atomicUint,
1351 Types::Uint64 compareValue,
1352 Types::Uint64 swapValue);
1353
1354 /// Atomically add to the specified `atomicUint` the specified `value`,
1355 /// providing the sequential consistency memory ordering guarantee.
1356 static void addUint64(AtomicTypes::Uint64 *atomicUint,
1357 Types::Uint64 value);
1358
1359 /// Atomically add to the specified `atomicUint` the specified `value`,
1360 /// providing the acquire/release memory ordering guarantee.
1361 static void addUint64AcqRel(AtomicTypes::Uint64 *atomicUint,
1362 Types::Uint64 value);
1363
1364 /// Atomically add to the specified `atomicUint` the specified `value`,
1365 /// without providing any memory ordering guarantees.
1366 static void addUint64Relaxed(AtomicTypes::Uint64 *atomicUint,
1367 Types::Uint64 value);
1368
1369 /// Atomically add to the specified `atomicUint` the specified `value`
1370 /// and return the resulting value, providing the sequential consistency
1371 /// memory ordering guarantee.
1372 static Types::Uint64 addUint64Nv(AtomicTypes::Uint64 *atomicUint,
1373 Types::Uint64 value);
1374
1375 /// Atomically add to the specified `atomicUint` the specified `value`
1376 /// and return the resulting value, providing the acquire/release memory
1377 /// ordering guarantee.
1378 static Types::Uint64 addUint64NvAcqRel(AtomicTypes::Uint64 *atomicUint,
1379 Types::Uint64 value);
1380
1381 /// Atomically add to the specified `atomicUint` the specified `value`
1382 /// and return the resulting value, without providing any memory
1383 /// ordering guarantees.
1384 static Types::Uint64 addUint64NvRelaxed(AtomicTypes::Uint64 *atomicUint,
1385 Types::Uint64 value);
1386
1387 /// Atomically decrement the specified `atomicUint` by 1, providing the
1388 /// sequential consistency memory ordering guarantee.
1389 static void decrementUint64(AtomicTypes::Uint64 *atomicUint);
1390
1391 /// Atomically decrement the specified `atomicUint` by 1, providing the
1392 /// acquire/release memory ordering guarantee.
1393 static void decrementUint64AcqRel(AtomicTypes::Uint64 *atomicUint);
1394
1395 /// Atomically decrement the specified `atomicUint` by 1 and return the
1396 /// resulting value, providing the sequential consistency memory
1397 /// ordering guarantee.
1398 static Types::Uint64 decrementUint64Nv(AtomicTypes::Uint64 *atomicUint);
1399
1400 /// Atomically decrement the specified `atomicUint` by 1 and return the
1401 /// resulting value, providing the acquire/release memory ordering
1402 /// guarantee.
1404 AtomicTypes::Uint64 *atomicUint);
1405
1406 /// Atomically increment the value of the specified `atomicUint` by 1,
1407 /// providing the sequential consistency memory ordering guarantee.
1408 static void incrementUint64(AtomicTypes::Uint64 *atomicUint);
1409
1410 /// Atomically increment the value of the specified `atomicUint` by 1,
1411 /// providing the acquire/release memory ordering guarantee.
1412 static void incrementUint64AcqRel(AtomicTypes::Uint64 *atomicUint);
1413
1414 /// Atomically increment the specified `atomicUint` by 1 and return the
1415 /// resulting value, providing the sequential consistency memory
1416 /// ordering guarantee.
1417 static Types::Uint64 incrementUint64Nv(AtomicTypes::Uint64 *atomicUint);
1418
1419 /// Atomically increment the specified `atomicUint` by 1 and return the
1420 /// resulting value, providing the acquire/release memory ordering
1421 /// guarantee.
1423 AtomicTypes::Uint64 *atomicUint);
1424
1425 /// Atomically subtract from the specified `atomicUint` the specified
1426 /// `value` and return the resulting value, providing the sequential
1427 /// consistency memory ordering guarantee.
1428 static Types::Uint64 subtractUint64Nv(AtomicTypes::Uint64 *atomicUint,
1429 Types::Uint64 value);
1430
1431 /// Atomically subtract from the specified `atomicUint` the specified
1432 /// `value` and return the resulting value, providing the
1433 /// acquire/release memory ordering guarantee.
1435 AtomicTypes::Uint64 *atomicUint,
1436 Types::Uint64 value);
1437
1438 /// Atomically subtract from the specified `atomicUint` the specified
1439 /// `value` and return the resulting value, without providing any memory
1440 /// ordering guarantees.
1442 AtomicTypes::Uint64 *atomicUint,
1443 Types::Uint64 value);
1444
1445 // *** atomic functions for pointer ***
1446
1447 /// Atomically retrieve the value of the specified `atomicPtr`,
1448 /// providing the sequential consistency memory ordering guarantee.
1449 static void *getPtr(AtomicTypes::Pointer const *atomicPtr);
1450
1451 /// Atomically retrieve the value of the specified `atomicPtr`,
1452 /// providing the acquire memory ordering guarantee.
1453 static void *getPtrAcquire(AtomicTypes::Pointer const *atomicPtr);
1454
1455 /// Atomically retrieve the value of the specified `atomicPtr`, without
1456 /// providing any memory ordering guarantees.
1457 static void *getPtrRelaxed(AtomicTypes::Pointer const *atomicPtr);
1458
1459 /// Initialize the specified `atomicPtr` and set its value to the
1460 /// optionally specified `initialValue`.
1461 static void initPointer(AtomicTypes::Pointer *atomicPtr,
1462 void *initialValue = 0);
1463
1464 /// Atomically set the value of the specified `atomicPtr` to the
1465 /// specified `value`, providing the sequential consistency memory
1466 /// ordering guarantee.
1467 static void setPtr(AtomicTypes::Pointer *atomicPtr,
1468 void *value);
1469
1470 /// Atomically set the value of the specified `atomicPtr` to the
1471 /// specified `value`, without providing any memory ordering guarantees.
1472 static void setPtrRelaxed(AtomicTypes::Pointer *atomicPtr,
1473 void *value);
1474
1475 /// Atomically set the value of the specified `atomicPtr` to the
1476 /// specified `value`, providing the release memory ordering guarantee.
1477 static void setPtrRelease(AtomicTypes::Pointer *atomicPtr,
1478 void *value);
1479
1480 /// Atomically set the value of the specified `atomicPtr` to the
1481 /// specified `swapValue`, and return its previous value, providing the
1482 /// sequential consistency memory ordering guarantee.
1483 static void *swapPtr(AtomicTypes::Pointer *atomicPtr,
1484 void *swapValue);
1485
1486 /// Atomically set the value of the specified `atomicPtr` to the
1487 /// specified `swapValue`, and return its previous value, providing the
1488 /// acquire/release memory ordering guarantee.
1489 static void *swapPtrAcqRel(AtomicTypes::Pointer *atomicPtr,
1490 void *swapValue);
1491
1492 /// Conditionally set the value of the specified `atomicPtr` to the
1493 /// specified `swapValue` if and only if the value of `atomicPtr` equals
1494 /// the value of the specified `compareValue`, and return the initial
1495 /// value of `atomicPtr`, providing the sequential consistency memory
1496 /// ordering guarantee. The whole operation is performed atomically.
1497 static void *testAndSwapPtr(AtomicTypes::Pointer *atomicPtr,
1498 void *compareValue,
1499 void *swapValue);
1500
1501 /// Conditionally set the value of the specified `atomicPtr` to the
1502 /// specified `swapValue` if and only if the value of `atomicPtr` equals
1503 /// the value of the specified `compareValue`, and return the initial
1504 /// value of `atomicPtr`, providing the acquire/release memory ordering
1505 /// guarantee. The whole operation is performed atomically.
1506 static void *testAndSwapPtrAcqRel(AtomicTypes::Pointer *atomicPtr,
1507 void *compareValue,
1508 void *swapValue);
1509};
1510
1511// ============================================================================
1512// INLINE FUNCTION DEFINITIONS
1513// ============================================================================
1514
1515 // -----------------------
1516 // struct AtomicOperations
1517 // -----------------------
1518
1519// *** atomic functions for int ***
1520
1521inline
1522int AtomicOperations::getInt(AtomicTypes::Int const *atomicInt)
1523{
1524 return Imp::getInt(atomicInt);
1525}
1526
1527inline
1528int AtomicOperations::getIntAcquire(AtomicTypes::Int const *atomicInt)
1529{
1530 return Imp::getIntAcquire(atomicInt);
1531}
1532
1533inline
1534int AtomicOperations::getIntRelaxed(AtomicTypes::Int const *atomicInt)
1535{
1536 return Imp::getIntRelaxed(atomicInt);
1537}
1538
1539inline
1540void AtomicOperations::initInt(AtomicTypes::Int *atomicInt, int initialValue)
1541{
1542 Imp::initInt(atomicInt, initialValue);
1543}
1544
1545inline
1546void AtomicOperations::setInt(AtomicTypes::Int *atomicInt, int value)
1547{
1548 Imp::setInt(atomicInt, value);
1549}
1550
1551inline
1552void AtomicOperations::setIntRelaxed(AtomicTypes::Int *atomicInt, int value)
1553{
1554 Imp::setIntRelaxed(atomicInt, value);
1555}
1556
1557inline
1558void AtomicOperations::setIntRelease(AtomicTypes::Int *atomicInt, int value)
1559{
1560 Imp::setIntRelease(atomicInt, value);
1561}
1562
1563inline
1564int AtomicOperations::swapInt(AtomicTypes::Int *atomicInt, int swapValue)
1565{
1566 return Imp::swapInt(atomicInt, swapValue);
1567}
1568
1569inline
1570int AtomicOperations::swapIntAcqRel(AtomicTypes::Int *atomicInt, int swapValue)
1571{
1572 return Imp::swapIntAcqRel(atomicInt, swapValue);
1573}
1574
1575inline
1576int AtomicOperations::testAndSwapInt(AtomicTypes::Int *atomicInt,
1577 int compareValue,
1578 int swapValue)
1579{
1580 return Imp::testAndSwapInt(atomicInt, compareValue, swapValue);
1581}
1582
1583inline
1584int AtomicOperations::testAndSwapIntAcqRel(AtomicTypes::Int *atomicInt,
1585 int compareValue,
1586 int swapValue)
1587{
1588 return Imp::testAndSwapIntAcqRel(atomicInt, compareValue, swapValue);
1589}
1590
1591// *** atomic arithmetic functions for int ***
1592
1593inline
1594void AtomicOperations::addInt(AtomicTypes::Int *atomicInt, int value)
1595{
1596 Imp::addInt(atomicInt, value);
1597}
1598
1599inline
1600void AtomicOperations::addIntAcqRel(AtomicTypes::Int *atomicInt, int value)
1601{
1602 Imp::addIntAcqRel(atomicInt, value);
1603}
1604
1605inline
1606void AtomicOperations::addIntRelaxed(AtomicTypes::Int *atomicInt, int value)
1607{
1608 Imp::addIntRelaxed(atomicInt, value);
1609}
1610
1611inline
1612int AtomicOperations::addIntNv(AtomicTypes::Int *atomicInt, int value)
1613{
1614 return Imp::addIntNv(atomicInt, value);
1615}
1616
1617inline
1618int AtomicOperations::addIntNvAcqRel(AtomicTypes::Int *atomicInt, int value)
1619{
1620 return Imp::addIntNvAcqRel(atomicInt, value);
1621}
1622
1623inline
1624int AtomicOperations::addIntNvRelaxed(AtomicTypes::Int *atomicInt, int value)
1625{
1626 return Imp::addIntNvRelaxed(atomicInt, value);
1627}
1628
1629inline
1630void AtomicOperations::decrementInt(AtomicTypes::Int *atomicInt)
1631{
1632 Imp::decrementInt(atomicInt);
1633}
1634
1635inline
1636void AtomicOperations::decrementIntAcqRel(AtomicTypes::Int *atomicInt)
1637{
1638 Imp::decrementIntAcqRel(atomicInt);
1639}
1640
1641inline
1642int AtomicOperations::decrementIntNv(AtomicTypes::Int *atomicInt)
1643{
1644 return Imp::decrementIntNv(atomicInt);
1645}
1646
1647inline
1648int AtomicOperations::decrementIntNvAcqRel(AtomicTypes::Int *atomicInt)
1649{
1650 return Imp::decrementIntNvAcqRel(atomicInt);
1651}
1652
1653inline
1654void AtomicOperations::incrementInt(AtomicTypes::Int *atomicInt)
1655{
1656 Imp::incrementInt(atomicInt);
1657}
1658
1659inline
1660void AtomicOperations::incrementIntAcqRel(AtomicTypes::Int *atomicInt)
1661{
1662 Imp::incrementIntAcqRel(atomicInt);
1663}
1664
1665inline
1666int AtomicOperations::incrementIntNv(AtomicTypes::Int *atomicInt)
1667{
1668 return Imp::incrementIntNv(atomicInt);
1669}
1670
1671inline
1672int AtomicOperations::incrementIntNvAcqRel(AtomicTypes::Int *atomicInt)
1673{
1674 return Imp::incrementIntNvAcqRel(atomicInt);
1675}
1676
1677inline
1678int AtomicOperations::subtractIntNv(AtomicTypes::Int *atomicInt, int value)
1679{
1680 return Imp::subtractIntNv(atomicInt, value);
1681}
1682
1683inline
1684int AtomicOperations::subtractIntNvAcqRel(AtomicTypes::Int *atomicInt,
1685 int value)
1686{
1687 return Imp::subtractIntNvAcqRel(atomicInt, value);
1688}
1689
1690inline
1691int AtomicOperations::subtractIntNvRelaxed(AtomicTypes::Int *atomicInt,
1692 int value)
1693{
1694 return Imp::subtractIntNvRelaxed(atomicInt, value);
1695}
1696
1697// *** atomic functions for Int64 ***
1698
1699inline
1701 AtomicOperations::getInt64(AtomicTypes::Int64 const *atomicInt)
1702{
1703 return Imp::getInt64(atomicInt);
1704}
1705
1706inline
1708 AtomicOperations::getInt64Acquire(AtomicTypes::Int64 const *atomicInt)
1709{
1710 return Imp::getInt64Acquire(atomicInt);
1711}
1712
1713inline
1715 AtomicOperations::getInt64Relaxed(AtomicTypes::Int64 const *atomicInt)
1716{
1717 return Imp::getInt64Relaxed(atomicInt);
1718}
1719
1720inline
1721void AtomicOperations::initInt64(AtomicTypes::Int64 *atomicInt,
1722 Types::Int64 initialValue)
1723{
1724 Imp::initInt64(atomicInt, initialValue);
1725}
1726
1727inline
1728void AtomicOperations::setInt64(AtomicTypes::Int64 *atomicInt,
1729 Types::Int64 value)
1730{
1731 Imp::setInt64(atomicInt, value);
1732}
1733
1734inline
1735void AtomicOperations::setInt64Relaxed(AtomicTypes::Int64 *atomicInt,
1736 Types::Int64 value)
1737{
1738 Imp::setInt64Relaxed(atomicInt, value);
1739}
1740
1741inline
1742void AtomicOperations::setInt64Release(AtomicTypes::Int64 *atomicInt,
1743 Types::Int64 value)
1744{
1745 Imp::setInt64Release(atomicInt, value);
1746}
1747
1748inline
1749Types::Int64 AtomicOperations::swapInt64(AtomicTypes::Int64 *atomicInt,
1750 Types::Int64 swapValue)
1751{
1752 return Imp::swapInt64(atomicInt, swapValue);
1753}
1754
1755inline
1757 Types::Int64 swapValue)
1758{
1759 return Imp::swapInt64AcqRel(atomicInt, swapValue);
1760}
1761
1762inline
1764 AtomicTypes::Int64 *atomicInt,
1765 Types::Int64 compareValue,
1766 Types::Int64 swapValue)
1767{
1768 return Imp::testAndSwapInt64(atomicInt, compareValue, swapValue);
1769}
1770
1771inline
1773 AtomicTypes::Int64 *atomicInt,
1774 Types::Int64 compareValue,
1775 Types::Int64 swapValue)
1776{
1777 return Imp::testAndSwapInt64AcqRel(atomicInt, compareValue, swapValue);
1778}
1779
1780// *** atomic arithmetic functions for Int64 ***
1781
1782inline
1783void AtomicOperations::addInt64(AtomicTypes::Int64 *atomicInt,
1784 Types::Int64 value)
1785{
1786 Imp::addInt64(atomicInt, value);
1787}
1788
1789inline
1790void AtomicOperations::addInt64AcqRel(AtomicTypes::Int64 *atomicInt,
1791 Types::Int64 value)
1792{
1793 Imp::addInt64AcqRel(atomicInt, value);
1794}
1795
1796inline
1797void AtomicOperations::addInt64Relaxed(AtomicTypes::Int64 *atomicInt,
1798 Types::Int64 value)
1799{
1800 Imp::addInt64Relaxed(atomicInt, value);
1801}
1802
1803inline
1804Types::Int64 AtomicOperations::addInt64Nv(AtomicTypes::Int64 *atomicInt,
1805 Types::Int64 value)
1806{
1807 return Imp::addInt64Nv(atomicInt, value);
1808}
1809
1810inline
1812 Types::Int64 value)
1813{
1814 return Imp::addInt64NvAcqRel(atomicInt, value);
1815}
1816
1817inline
1819 Types::Int64 value)
1820{
1821 return Imp::addInt64NvRelaxed(atomicInt, value);
1822}
1823
1824inline
1825void AtomicOperations::decrementInt64(AtomicTypes::Int64 *atomicInt)
1826{
1827 Imp::decrementInt64(atomicInt);
1828}
1829
1830inline
1831void AtomicOperations::decrementInt64AcqRel(AtomicTypes::Int64 *atomicInt)
1832{
1833 Imp::decrementInt64AcqRel(atomicInt);
1834}
1835
1836inline
1838 AtomicOperations::decrementInt64Nv(AtomicTypes::Int64 *atomicInt)
1839{
1840 return Imp::decrementInt64Nv(atomicInt);
1841}
1842
1843inline
1845 AtomicOperations::decrementInt64NvAcqRel(AtomicTypes::Int64 *atomicInt)
1846{
1847 return Imp::decrementInt64NvAcqRel(atomicInt);
1848}
1849
1850inline
1851void AtomicOperations::incrementInt64(AtomicTypes::Int64 *atomicInt)
1852{
1853 Imp::incrementInt64(atomicInt);
1854}
1855
1856inline
1857void AtomicOperations::incrementInt64AcqRel(AtomicTypes::Int64 *atomicInt)
1858{
1859 Imp::incrementInt64AcqRel(atomicInt);
1860}
1861
1862inline
1864 AtomicOperations::incrementInt64Nv(AtomicTypes::Int64 *atomicInt)
1865{
1866 return Imp::incrementInt64Nv(atomicInt);
1867}
1868
1869inline
1871 AtomicOperations::incrementInt64NvAcqRel(AtomicTypes::Int64 *atomicInt)
1872{
1873 return Imp::incrementInt64NvAcqRel(atomicInt);
1874}
1875
1876inline
1878 Types::Int64 value)
1879{
1880 return Imp::subtractInt64Nv(atomicInt, value);
1881}
1882
1883inline
1885 AtomicTypes::Int64 *atomicInt,
1886 Types::Int64 value)
1887{
1888 return Imp::subtractInt64NvAcqRel(atomicInt, value);
1889}
1890
1891inline
1893 AtomicTypes::Int64 *atomicInt,
1894 Types::Int64 value)
1895{
1896 return Imp::subtractInt64NvRelaxed(atomicInt, value);
1897}
1898
1899// *** atomic functions for unsigned int ***
1900
1901inline
1902unsigned int AtomicOperations::getUint(AtomicTypes::Uint const *atomicUint)
1903{
1904 return Imp::getUint(atomicUint);
1905}
1906
1907inline
1909 AtomicTypes::Uint const *atomicUint)
1910{
1911 return Imp::getUintAcquire(atomicUint);
1912}
1913
1914inline
1916 AtomicTypes::Uint const *atomicUint)
1917{
1918 return Imp::getUintRelaxed(atomicUint);
1919}
1920
1921inline
1922void AtomicOperations::initUint(AtomicTypes::Uint *atomicUint,
1923 unsigned int initialValue)
1924{
1925 Imp::initUint(atomicUint, initialValue);
1926}
1927
1928inline
1929void AtomicOperations::setUint(AtomicTypes::Uint *atomicUint,
1930 unsigned int value)
1931{
1932 Imp::setUint(atomicUint, value);
1933}
1934
1935inline
1936void AtomicOperations::setUintRelaxed(AtomicTypes::Uint *atomicUint,
1937 unsigned int value)
1938{
1939 Imp::setUintRelaxed(atomicUint, value);
1940}
1941
1942inline
1943void AtomicOperations::setUintRelease(AtomicTypes::Uint *atomicUint,
1944 unsigned int value)
1945{
1946 Imp::setUintRelease(atomicUint, value);
1947}
1948
1949inline
1950unsigned int AtomicOperations::swapUint(AtomicTypes::Uint *atomicUint,
1951 unsigned int swapValue)
1952{
1953 return Imp::swapUint(atomicUint, swapValue);
1954}
1955
1956inline
1957unsigned int AtomicOperations::swapUintAcqRel(AtomicTypes::Uint *atomicUint,
1958 unsigned int swapValue)
1959{
1960 return Imp::swapUintAcqRel(atomicUint, swapValue);
1961}
1962
1963inline
1964unsigned int AtomicOperations::testAndSwapUint(AtomicTypes::Uint *atomicUint,
1965 unsigned int compareValue,
1966 unsigned int swapValue)
1967{
1968 return Imp::testAndSwapUint(atomicUint, compareValue, swapValue);
1969}
1970
1971inline
1973 AtomicTypes::Uint *atomicUint,
1974 unsigned int compareValue,
1975 unsigned int swapValue)
1976{
1977 return Imp::testAndSwapUintAcqRel(atomicUint, compareValue, swapValue);
1978}
1979
1980// *** atomic arithmetic functions for unsigned int ***
1981
1982inline
1983void AtomicOperations::addUint(AtomicTypes::Uint *atomicUint,
1984 unsigned int value)
1985{
1986 Imp::addUint(atomicUint, value);
1987}
1988
1989inline
1990void AtomicOperations::addUintAcqRel(AtomicTypes::Uint *atomicUint,
1991 unsigned int value)
1992{
1993 Imp::addUintAcqRel(atomicUint, value);
1994}
1995
1996inline
1997void AtomicOperations::addUintRelaxed(AtomicTypes::Uint *atomicUint,
1998 unsigned int value)
1999{
2000 Imp::addUintRelaxed(atomicUint, value);
2001}
2002
2003inline
2004unsigned int AtomicOperations::addUintNv(AtomicTypes::Uint *atomicUint,
2005 unsigned int value)
2006{
2007 return Imp::addUintNv(atomicUint, value);
2008}
2009
2010inline
2011unsigned int AtomicOperations::addUintNvAcqRel(AtomicTypes::Uint *atomicUint,
2012 unsigned int value)
2013{
2014 return Imp::addUintNvAcqRel(atomicUint, value);
2015}
2016
2017inline
2018unsigned int AtomicOperations::addUintNvRelaxed(AtomicTypes::Uint *atomicUint,
2019 unsigned int value)
2020{
2021 return Imp::addUintNvRelaxed(atomicUint, value);
2022}
2023
2024inline
2025void AtomicOperations::decrementUint(AtomicTypes::Uint *atomicUint)
2026{
2027 Imp::decrementUint(atomicUint);
2028}
2029
2030inline
2031void AtomicOperations::decrementUintAcqRel(AtomicTypes::Uint *atomicUint)
2032{
2033 Imp::decrementUintAcqRel(atomicUint);
2034}
2035
2036inline
2037unsigned int AtomicOperations::decrementUintNv(AtomicTypes::Uint *atomicUint)
2038{
2039 return Imp::decrementUintNv(atomicUint);
2040}
2041
2042inline
2044 AtomicTypes::Uint *atomicUint)
2045{
2046 return Imp::decrementUintNvAcqRel(atomicUint);
2047}
2048
2049inline
2050void AtomicOperations::incrementUint(AtomicTypes::Uint *atomicUint)
2051{
2052 Imp::incrementUint(atomicUint);
2053}
2054
2055inline
2056void AtomicOperations::incrementUintAcqRel(AtomicTypes::Uint *atomicUint)
2057{
2058 Imp::incrementUintAcqRel(atomicUint);
2059}
2060
2061inline
2062unsigned int AtomicOperations::incrementUintNv(AtomicTypes::Uint *atomicUint)
2063{
2064 return Imp::incrementUintNv(atomicUint);
2065}
2066
2067inline
2069 AtomicTypes::Uint *atomicUint)
2070{
2071 return Imp::incrementUintNvAcqRel(atomicUint);
2072}
2073
2074inline
2075unsigned int AtomicOperations::subtractUintNv(AtomicTypes::Uint *atomicUint,
2076 unsigned int value)
2077{
2078 return Imp::subtractUintNv(atomicUint, value);
2079}
2080
2081inline
2083 AtomicTypes::Uint *atomicUint,
2084 unsigned int value)
2085{
2086 return Imp::subtractUintNvAcqRel(atomicUint, value);
2087}
2088
2089inline
2091 AtomicTypes::Uint *atomicUint,
2092 unsigned int value)
2093{
2094 return Imp::subtractUintNvRelaxed(atomicUint, value);
2095}
2096
2097// *** atomic functions for Uint64 ***
2098
2099inline
2101 AtomicOperations::getUint64(AtomicTypes::Uint64 const *atomicUint)
2102{
2103 return Imp::getUint64(atomicUint);
2104}
2105
2106inline
2108 AtomicOperations::getUint64Acquire(AtomicTypes::Uint64 const *atomicUint)
2109{
2110 return Imp::getUint64Acquire(atomicUint);
2111}
2112
2113inline
2115 AtomicOperations::getUint64Relaxed(AtomicTypes::Uint64 const *atomicUint)
2116{
2117 return Imp::getUint64Relaxed(atomicUint);
2118}
2119
2120inline
2121void AtomicOperations::initUint64(AtomicTypes::Uint64 *atomicUint,
2122 Types::Uint64 initialValue)
2123{
2124 Imp::initUint64(atomicUint, initialValue);
2125}
2126
2127inline
2128void AtomicOperations::setUint64(AtomicTypes::Uint64 *atomicUint,
2129 Types::Uint64 value)
2130{
2131 Imp::setUint64(atomicUint, value);
2132}
2133
2134inline
2135void AtomicOperations::setUint64Relaxed(AtomicTypes::Uint64 *atomicUint,
2136 Types::Uint64 value)
2137{
2138 Imp::setUint64Relaxed(atomicUint, value);
2139}
2140
2141inline
2142void AtomicOperations::setUint64Release(AtomicTypes::Uint64 *atomicUint,
2143 Types::Uint64 value)
2144{
2145 Imp::setUint64Release(atomicUint, value);
2146}
2147
2148inline
2149Types::Uint64 AtomicOperations::swapUint64(AtomicTypes::Uint64 *atomicUint,
2150 Types::Uint64 swapValue)
2151{
2152 return Imp::swapUint64(atomicUint, swapValue);
2153}
2154
2155inline
2157 AtomicTypes::Uint64 *atomicUint,
2158 Types::Uint64 swapValue)
2159{
2160 return Imp::swapUint64AcqRel(atomicUint, swapValue);
2161}
2162
2163inline
2165 AtomicTypes::Uint64 *atomicUint,
2166 Types::Uint64 compareValue,
2167 Types::Uint64 swapValue)
2168{
2169 return Imp::testAndSwapUint64(atomicUint, compareValue, swapValue);
2170}
2171
2172inline
2174 AtomicTypes::Uint64 *atomicUint,
2175 Types::Uint64 compareValue,
2176 Types::Uint64 swapValue)
2177{
2178 return Imp::testAndSwapUint64AcqRel(atomicUint, compareValue, swapValue);
2179}
2180
2181// *** atomic arithmetic functions for Uint64 ***
2182
2183inline
2184void AtomicOperations::addUint64(AtomicTypes::Uint64 *atomicUint,
2185 Types::Uint64 value)
2186{
2187 Imp::addUint64(atomicUint, value);
2188}
2189
2190inline
2191void AtomicOperations::addUint64AcqRel(AtomicTypes::Uint64 *atomicUint,
2192 Types::Uint64 value)
2193{
2194 Imp::addUint64AcqRel(atomicUint, value);
2195}
2196
2197inline
2198void AtomicOperations::addUint64Relaxed(AtomicTypes::Uint64 *atomicUint,
2199 Types::Uint64 value)
2200{
2201 Imp::addUint64Relaxed(atomicUint, value);
2202}
2203
2204inline
2205Types::Uint64 AtomicOperations::addUint64Nv(AtomicTypes::Uint64 *atomicUint,
2206 Types::Uint64 value)
2207{
2208 return Imp::addUint64Nv(atomicUint, value);
2209}
2210
2211inline
2213 AtomicTypes::Uint64 *atomicUint,
2214 Types::Uint64 value)
2215{
2216 return Imp::addUint64NvAcqRel(atomicUint, value);
2217}
2218
2219inline
2221 AtomicTypes::Uint64 *atomicUint,
2222 Types::Uint64 value)
2223{
2224 return Imp::addUint64NvRelaxed(atomicUint, value);
2225}
2226
2227inline
2228void AtomicOperations::decrementUint64(AtomicTypes::Uint64 *atomicUint)
2229{
2230 Imp::decrementUint64(atomicUint);
2231}
2232
2233inline
2234void AtomicOperations::decrementUint64AcqRel(AtomicTypes::Uint64 *atomicUint)
2235{
2236 Imp::decrementUint64AcqRel(atomicUint);
2237}
2238
2239inline
2241 AtomicOperations::decrementUint64Nv(AtomicTypes::Uint64 *atomicUint)
2242{
2243 return Imp::decrementUint64Nv(atomicUint);
2244}
2245
2246inline
2248 AtomicOperations::decrementUint64NvAcqRel(AtomicTypes::Uint64 *atomicUint)
2249{
2250 return Imp::decrementUint64NvAcqRel(atomicUint);
2251}
2252
2253inline
2254void AtomicOperations::incrementUint64(AtomicTypes::Uint64 *atomicUint)
2255{
2256 Imp::incrementUint64(atomicUint);
2257}
2258
2259inline
2260void AtomicOperations::incrementUint64AcqRel(AtomicTypes::Uint64 *atomicUint)
2261{
2262 Imp::incrementUint64AcqRel(atomicUint);
2263}
2264
2265inline
2267 AtomicOperations::incrementUint64Nv(AtomicTypes::Uint64 *atomicUint)
2268{
2269 return Imp::incrementUint64Nv(atomicUint);
2270}
2271
2272inline
2274 AtomicOperations::incrementUint64NvAcqRel(AtomicTypes::Uint64 *atomicUint)
2275{
2276 return Imp::incrementUint64NvAcqRel(atomicUint);
2277}
2278
2279inline
2281 AtomicTypes::Uint64 *atomicUint,
2282 Types::Uint64 value)
2283{
2284 return Imp::subtractUint64Nv(atomicUint, value);
2285}
2286
2287inline
2289 AtomicTypes::Uint64 *atomicUint,
2290 Types::Uint64 value)
2291{
2292 return Imp::subtractUint64NvAcqRel(atomicUint, value);
2293}
2294
2295inline
2297 AtomicTypes::Uint64 *atomicUint,
2298 Types::Uint64 value)
2299{
2300 return Imp::subtractUint64NvRelaxed(atomicUint, value);
2301}
2302
2303// *** atomic functions for pointer ***
2304
2305inline
2306void *AtomicOperations::getPtr(AtomicTypes::Pointer const *atomicPtr)
2307{
2308 return Imp::getPtr(atomicPtr);
2309}
2310
2311inline
2312void * AtomicOperations::getPtrAcquire(AtomicTypes::Pointer const *atomicPtr)
2313{
2314 return Imp::getPtrAcquire(atomicPtr);
2315}
2316
2317inline
2318void * AtomicOperations::getPtrRelaxed(AtomicTypes::Pointer const *atomicPtr)
2319{
2320 return Imp::getPtrRelaxed(atomicPtr);
2321}
2322
2323inline
2324void AtomicOperations::initPointer(AtomicTypes::Pointer *atomicPtr,
2325 void *initialValue)
2326{
2327 Imp::initPointer(atomicPtr, initialValue);
2328}
2329
2330inline
2331void AtomicOperations::setPtr(AtomicTypes::Pointer *atomicPtr,
2332 void *value)
2333{
2334 Imp::setPtr(atomicPtr, value);
2335}
2336
2337inline
2338void AtomicOperations::setPtrRelaxed(AtomicTypes::Pointer *atomicPtr,
2339 void *value)
2340{
2341 Imp::setPtrRelaxed(atomicPtr, value);
2342}
2343
2344inline
2345void AtomicOperations::setPtrRelease(AtomicTypes::Pointer *atomicPtr,
2346 void *value)
2347{
2348 Imp::setPtrRelease(atomicPtr, value);
2349}
2350
2351inline
2352void *AtomicOperations::swapPtr(AtomicTypes::Pointer *atomicPtr,
2353 void *swapValue)
2354{
2355 return Imp::swapPtr(atomicPtr, swapValue);
2356}
2357
2358inline
2359void *AtomicOperations::swapPtrAcqRel(AtomicTypes::Pointer *atomicPtr,
2360 void *swapValue)
2361{
2362 return Imp::swapPtrAcqRel(atomicPtr, swapValue);
2363}
2364
2365inline
2366void *AtomicOperations::testAndSwapPtr(AtomicTypes::Pointer *atomicPtr,
2367 void *compareValue,
2368 void *swapValue)
2369{
2370 return Imp::testAndSwapPtr(atomicPtr, compareValue, swapValue);
2371}
2372
2373inline
2375 AtomicTypes::Pointer *atomicPtr,
2376 void *compareValue,
2377 void *swapValue)
2378{
2379 return Imp::testAndSwapPtrAcqRel(atomicPtr, compareValue, swapValue);
2380}
2381
2382} // close package namespace
2383
2384
2385
2386#endif
2387
2388// ----------------------------------------------------------------------------
2389// Copyright 2013 Bloomberg Finance L.P.
2390//
2391// Licensed under the Apache License, Version 2.0 (the "License");
2392// you may not use this file except in compliance with the License.
2393// You may obtain a copy of the License at
2394//
2395// http://www.apache.org/licenses/LICENSE-2.0
2396//
2397// Unless required by applicable law or agreed to in writing, software
2398// distributed under the License is distributed on an "AS IS" BASIS,
2399// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2400// See the License for the specific language governing permissions and
2401// limitations under the License.
2402// ----------------------------- END-OF-FILE ----------------------------------
2403
2404/** @} */
2405/** @} */
2406/** @} */
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
Definition bdlt_iso8601util.h:691
Definition bsls_atomicoperations.h:834
static void setInt(AtomicTypes::Int *atomicInt, int value)
Definition bsls_atomicoperations.h:1546
static void incrementInt64AcqRel(AtomicTypes::Int64 *atomicInt)
Definition bsls_atomicoperations.h:1857
static Types::Uint64 getUint64Relaxed(AtomicTypes::Uint64 const *atomicUint)
Definition bsls_atomicoperations.h:2115
static void decrementUint(AtomicTypes::Uint *atomicUint)
Definition bsls_atomicoperations.h:2025
static unsigned int swapUintAcqRel(AtomicTypes::Uint *atomicUint, unsigned int swapValue)
Definition bsls_atomicoperations.h:1957
static int subtractIntNvRelaxed(AtomicTypes::Int *atomicInt, int value)
Definition bsls_atomicoperations.h:1691
static void * swapPtrAcqRel(AtomicTypes::Pointer *atomicPtr, void *swapValue)
Definition bsls_atomicoperations.h:2359
static int getIntAcquire(AtomicTypes::Int const *atomicInt)
Definition bsls_atomicoperations.h:1528
static Types::Int64 swapInt64(AtomicTypes::Int64 *atomicInt, Types::Int64 swapValue)
Definition bsls_atomicoperations.h:1749
static void * getPtr(AtomicTypes::Pointer const *atomicPtr)
Definition bsls_atomicoperations.h:2306
static void setPtrRelaxed(AtomicTypes::Pointer *atomicPtr, void *value)
Definition bsls_atomicoperations.h:2338
static int incrementIntNvAcqRel(AtomicTypes::Int *atomicInt)
Definition bsls_atomicoperations.h:1672
static void addUint64Relaxed(AtomicTypes::Uint64 *atomicUint, Types::Uint64 value)
Definition bsls_atomicoperations.h:2198
static void setPtr(AtomicTypes::Pointer *atomicPtr, void *value)
Definition bsls_atomicoperations.h:2331
static unsigned int getUintAcquire(AtomicTypes::Uint const *atomicUint)
Definition bsls_atomicoperations.h:1908
static void setUint64Relaxed(AtomicTypes::Uint64 *atomicUint, Types::Uint64 value)
Definition bsls_atomicoperations.h:2135
static unsigned int decrementUintNv(AtomicTypes::Uint *atomicUint)
Definition bsls_atomicoperations.h:2037
static unsigned int getUintRelaxed(AtomicTypes::Uint const *atomicUint)
Definition bsls_atomicoperations.h:1915
static void addUint(AtomicTypes::Uint *atomicUint, unsigned int value)
Definition bsls_atomicoperations.h:1983
static Types::Uint64 addUint64Nv(AtomicTypes::Uint64 *atomicUint, Types::Uint64 value)
Definition bsls_atomicoperations.h:2205
static int addIntNvRelaxed(AtomicTypes::Int *atomicInt, int value)
Definition bsls_atomicoperations.h:1624
AtomicOperations_Imp Imp
Definition bsls_atomicoperations.h:837
static void setInt64Release(AtomicTypes::Int64 *atomicInt, Types::Int64 value)
Definition bsls_atomicoperations.h:1742
static unsigned int testAndSwapUint(AtomicTypes::Uint *atomicUint, unsigned int compareValue, unsigned int swapValue)
Definition bsls_atomicoperations.h:1964
static void setUint64(AtomicTypes::Uint64 *atomicUint, Types::Uint64 value)
Definition bsls_atomicoperations.h:2128
static void setIntRelease(AtomicTypes::Int *atomicInt, int value)
Definition bsls_atomicoperations.h:1558
static Types::Uint64 incrementUint64Nv(AtomicTypes::Uint64 *atomicUint)
Definition bsls_atomicoperations.h:2267
static void initPointer(AtomicTypes::Pointer *atomicPtr, void *initialValue=0)
Definition bsls_atomicoperations.h:2324
static void initInt64(AtomicTypes::Int64 *atomicInt, Types::Int64 initialValue=0)
Definition bsls_atomicoperations.h:1721
static unsigned int addUintNvRelaxed(AtomicTypes::Uint *atomicUint, unsigned int value)
Definition bsls_atomicoperations.h:2018
static int decrementIntNvAcqRel(AtomicTypes::Int *atomicInt)
Definition bsls_atomicoperations.h:1648
static void decrementUintAcqRel(AtomicTypes::Uint *atomicUint)
Definition bsls_atomicoperations.h:2031
static void setUintRelaxed(AtomicTypes::Uint *atomicUint, unsigned int value)
Definition bsls_atomicoperations.h:1936
static Types::Int64 testAndSwapInt64AcqRel(AtomicTypes::Int64 *atomicInt, Types::Int64 compareValue, Types::Int64 swapValue)
Definition bsls_atomicoperations.h:1772
static void setInt64Relaxed(AtomicTypes::Int64 *atomicInt, Types::Int64 value)
Definition bsls_atomicoperations.h:1735
static Types::Int64 subtractInt64Nv(AtomicTypes::Int64 *atomicInt, Types::Int64 value)
Definition bsls_atomicoperations.h:1877
static Types::Uint64 testAndSwapUint64(AtomicTypes::Uint64 *atomicUint, Types::Uint64 compareValue, Types::Uint64 swapValue)
Definition bsls_atomicoperations.h:2164
static void setUintRelease(AtomicTypes::Uint *atomicUint, unsigned int value)
Definition bsls_atomicoperations.h:1943
static Types::Uint64 addUint64NvRelaxed(AtomicTypes::Uint64 *atomicUint, Types::Uint64 value)
Definition bsls_atomicoperations.h:2220
static void incrementUint64(AtomicTypes::Uint64 *atomicUint)
Definition bsls_atomicoperations.h:2254
static unsigned int subtractUintNvRelaxed(AtomicTypes::Uint *atomicUint, unsigned int value)
Definition bsls_atomicoperations.h:2090
static Types::Int64 getInt64(AtomicTypes::Int64 const *atomicInt)
Definition bsls_atomicoperations.h:1701
static Types::Int64 addInt64NvAcqRel(AtomicTypes::Int64 *atomicInt, Types::Int64 value)
Definition bsls_atomicoperations.h:1811
static Types::Int64 incrementInt64Nv(AtomicTypes::Int64 *atomicInt)
Definition bsls_atomicoperations.h:1864
static void decrementInt64(AtomicTypes::Int64 *atomicInt)
Definition bsls_atomicoperations.h:1825
static void setInt64(AtomicTypes::Int64 *atomicInt, Types::Int64 value)
Definition bsls_atomicoperations.h:1728
static void * getPtrAcquire(AtomicTypes::Pointer const *atomicPtr)
Definition bsls_atomicoperations.h:2312
static unsigned int swapUint(AtomicTypes::Uint *atomicUint, unsigned int swapValue)
Definition bsls_atomicoperations.h:1950
static void setUint(AtomicTypes::Uint *atomicUint, unsigned int value)
Definition bsls_atomicoperations.h:1929
static unsigned int addUintNv(AtomicTypes::Uint *atomicUint, unsigned int value)
Definition bsls_atomicoperations.h:2004
static void * testAndSwapPtrAcqRel(AtomicTypes::Pointer *atomicPtr, void *compareValue, void *swapValue)
Definition bsls_atomicoperations.h:2374
static void setIntRelaxed(AtomicTypes::Int *atomicInt, int value)
Definition bsls_atomicoperations.h:1552
static Types::Uint64 testAndSwapUint64AcqRel(AtomicTypes::Uint64 *atomicUint, Types::Uint64 compareValue, Types::Uint64 swapValue)
Definition bsls_atomicoperations.h:2173
static unsigned int testAndSwapUintAcqRel(AtomicTypes::Uint *atomicUint, unsigned int compareValue, unsigned int swapValue)
Definition bsls_atomicoperations.h:1972
Atomic_TypeTraits< Imp > AtomicTypes
Definition bsls_atomicoperations.h:838
static unsigned int getUint(AtomicTypes::Uint const *atomicUint)
Definition bsls_atomicoperations.h:1902
static void addIntAcqRel(AtomicTypes::Int *atomicInt, int value)
Definition bsls_atomicoperations.h:1600
static unsigned int subtractUintNvAcqRel(AtomicTypes::Uint *atomicUint, unsigned int value)
Definition bsls_atomicoperations.h:2082
static int incrementIntNv(AtomicTypes::Int *atomicInt)
Definition bsls_atomicoperations.h:1666
static Types::Uint64 swapUint64(AtomicTypes::Uint64 *atomicUint, Types::Uint64 swapValue)
Definition bsls_atomicoperations.h:2149
static int getIntRelaxed(AtomicTypes::Int const *atomicInt)
Definition bsls_atomicoperations.h:1534
static int getInt(AtomicTypes::Int const *atomicInt)
Definition bsls_atomicoperations.h:1522
static Types::Int64 subtractInt64NvRelaxed(AtomicTypes::Int64 *atomicInt, Types::Int64 value)
Definition bsls_atomicoperations.h:1892
static void * testAndSwapPtr(AtomicTypes::Pointer *atomicPtr, void *compareValue, void *swapValue)
Definition bsls_atomicoperations.h:2366
static void decrementUint64(AtomicTypes::Uint64 *atomicUint)
Definition bsls_atomicoperations.h:2228
static void decrementInt64AcqRel(AtomicTypes::Int64 *atomicInt)
Definition bsls_atomicoperations.h:1831
static void setPtrRelease(AtomicTypes::Pointer *atomicPtr, void *value)
Definition bsls_atomicoperations.h:2345
static void addIntRelaxed(AtomicTypes::Int *atomicInt, int value)
Definition bsls_atomicoperations.h:1606
static void initInt(AtomicTypes::Int *atomicInt, int initialValue=0)
Definition bsls_atomicoperations.h:1540
static int testAndSwapIntAcqRel(AtomicTypes::Int *atomicInt, int compareValue, int swapValue)
Definition bsls_atomicoperations.h:1584
static void addInt64AcqRel(AtomicTypes::Int64 *atomicInt, Types::Int64 value)
Definition bsls_atomicoperations.h:1790
static int subtractIntNv(AtomicTypes::Int *atomicInt, int value)
Definition bsls_atomicoperations.h:1678
static void addUint64(AtomicTypes::Uint64 *atomicUint, Types::Uint64 value)
Definition bsls_atomicoperations.h:2184
static Types::Uint64 swapUint64AcqRel(AtomicTypes::Uint64 *atomicUint, Types::Uint64 swapValue)
Definition bsls_atomicoperations.h:2156
static void addInt64Relaxed(AtomicTypes::Int64 *atomicInt, Types::Int64 value)
Definition bsls_atomicoperations.h:1797
static void incrementUint(AtomicTypes::Uint *atomicUint)
Definition bsls_atomicoperations.h:2050
static int addIntNv(AtomicTypes::Int *atomicInt, int value)
Definition bsls_atomicoperations.h:1612
static void incrementInt64(AtomicTypes::Int64 *atomicInt)
Definition bsls_atomicoperations.h:1851
static Types::Uint64 addUint64NvAcqRel(AtomicTypes::Uint64 *atomicUint, Types::Uint64 value)
Definition bsls_atomicoperations.h:2212
static Types::Int64 getInt64Acquire(AtomicTypes::Int64 const *atomicInt)
Definition bsls_atomicoperations.h:1708
static void incrementUintAcqRel(AtomicTypes::Uint *atomicUint)
Definition bsls_atomicoperations.h:2056
static Types::Int64 incrementInt64NvAcqRel(AtomicTypes::Int64 *atomicInt)
Definition bsls_atomicoperations.h:1871
static Types::Uint64 subtractUint64NvRelaxed(AtomicTypes::Uint64 *atomicUint, Types::Uint64 value)
Definition bsls_atomicoperations.h:2296
static void incrementUint64AcqRel(AtomicTypes::Uint64 *atomicUint)
Definition bsls_atomicoperations.h:2260
static unsigned int decrementUintNvAcqRel(AtomicTypes::Uint *atomicUint)
Definition bsls_atomicoperations.h:2043
static Types::Int64 testAndSwapInt64(AtomicTypes::Int64 *atomicInt, Types::Int64 compareValue, Types::Int64 swapValue)
Definition bsls_atomicoperations.h:1763
static Types::Int64 decrementInt64NvAcqRel(AtomicTypes::Int64 *atomicInt)
Definition bsls_atomicoperations.h:1845
static void initUint64(AtomicTypes::Uint64 *atomicUint, Types::Uint64 initialValue=0)
Definition bsls_atomicoperations.h:2121
static void addUintRelaxed(AtomicTypes::Uint *atomicUint, unsigned int value)
Definition bsls_atomicoperations.h:1997
static unsigned int incrementUintNv(AtomicTypes::Uint *atomicUint)
Definition bsls_atomicoperations.h:2062
static Types::Int64 addInt64Nv(AtomicTypes::Int64 *atomicInt, Types::Int64 value)
Definition bsls_atomicoperations.h:1804
static void decrementUint64AcqRel(AtomicTypes::Uint64 *atomicUint)
Definition bsls_atomicoperations.h:2234
static void * swapPtr(AtomicTypes::Pointer *atomicPtr, void *swapValue)
Definition bsls_atomicoperations.h:2352
static void decrementInt(AtomicTypes::Int *atomicInt)
Definition bsls_atomicoperations.h:1630
static Types::Uint64 getUint64(AtomicTypes::Uint64 const *atomicUint)
Definition bsls_atomicoperations.h:2101
static void addUint64AcqRel(AtomicTypes::Uint64 *atomicUint, Types::Uint64 value)
Definition bsls_atomicoperations.h:2191
static int swapIntAcqRel(AtomicTypes::Int *atomicInt, int swapValue)
Definition bsls_atomicoperations.h:1570
static int testAndSwapInt(AtomicTypes::Int *atomicInt, int compareValue, int swapValue)
Definition bsls_atomicoperations.h:1576
static int addIntNvAcqRel(AtomicTypes::Int *atomicInt, int value)
Definition bsls_atomicoperations.h:1618
static Types::Uint64 subtractUint64NvAcqRel(AtomicTypes::Uint64 *atomicUint, Types::Uint64 value)
Definition bsls_atomicoperations.h:2288
static unsigned int subtractUintNv(AtomicTypes::Uint *atomicUint, unsigned int value)
Definition bsls_atomicoperations.h:2075
static unsigned int incrementUintNvAcqRel(AtomicTypes::Uint *atomicUint)
Definition bsls_atomicoperations.h:2068
static void incrementIntAcqRel(AtomicTypes::Int *atomicInt)
Definition bsls_atomicoperations.h:1660
static void addInt(AtomicTypes::Int *atomicInt, int value)
Definition bsls_atomicoperations.h:1594
static void addUintAcqRel(AtomicTypes::Uint *atomicUint, unsigned int value)
Definition bsls_atomicoperations.h:1990
static int swapInt(AtomicTypes::Int *atomicInt, int swapValue)
Definition bsls_atomicoperations.h:1564
static void addInt64(AtomicTypes::Int64 *atomicInt, Types::Int64 value)
Definition bsls_atomicoperations.h:1783
static Types::Int64 decrementInt64Nv(AtomicTypes::Int64 *atomicInt)
Definition bsls_atomicoperations.h:1838
static Types::Uint64 getUint64Acquire(AtomicTypes::Uint64 const *atomicUint)
Definition bsls_atomicoperations.h:2108
static Types::Int64 addInt64NvRelaxed(AtomicTypes::Int64 *atomicInt, Types::Int64 value)
Definition bsls_atomicoperations.h:1818
static unsigned int addUintNvAcqRel(AtomicTypes::Uint *atomicUint, unsigned int value)
Definition bsls_atomicoperations.h:2011
static Types::Int64 subtractInt64NvAcqRel(AtomicTypes::Int64 *atomicInt, Types::Int64 value)
Definition bsls_atomicoperations.h:1884
static int decrementIntNv(AtomicTypes::Int *atomicInt)
Definition bsls_atomicoperations.h:1642
static Types::Uint64 subtractUint64Nv(AtomicTypes::Uint64 *atomicUint, Types::Uint64 value)
Definition bsls_atomicoperations.h:2280
static void initUint(AtomicTypes::Uint *atomicUint, unsigned int initialValue=0)
Definition bsls_atomicoperations.h:1922
static Types::Uint64 incrementUint64NvAcqRel(AtomicTypes::Uint64 *atomicUint)
Definition bsls_atomicoperations.h:2274
static Types::Int64 swapInt64AcqRel(AtomicTypes::Int64 *atomicInt, Types::Int64 swapValue)
Definition bsls_atomicoperations.h:1756
static void decrementIntAcqRel(AtomicTypes::Int *atomicInt)
Definition bsls_atomicoperations.h:1636
static void * getPtrRelaxed(AtomicTypes::Pointer const *atomicPtr)
Definition bsls_atomicoperations.h:2318
static void incrementInt(AtomicTypes::Int *atomicInt)
Definition bsls_atomicoperations.h:1654
static Types::Uint64 decrementUint64NvAcqRel(AtomicTypes::Uint64 *atomicUint)
Definition bsls_atomicoperations.h:2248
static void setUint64Release(AtomicTypes::Uint64 *atomicUint, Types::Uint64 value)
Definition bsls_atomicoperations.h:2142
static int subtractIntNvAcqRel(AtomicTypes::Int *atomicInt, int value)
Definition bsls_atomicoperations.h:1684
static Types::Uint64 decrementUint64Nv(AtomicTypes::Uint64 *atomicUint)
Definition bsls_atomicoperations.h:2241
static Types::Int64 getInt64Relaxed(AtomicTypes::Int64 const *atomicInt)
Definition bsls_atomicoperations.h:1715
Definition bsls_atomicoperations_default.h:333
unsigned long long Uint64
Definition bsls_types.h:137
long long Int64
Definition bsls_types.h:132