atomic Template Class

Summary

Template class for atomic operations.

Syntax

template<typename T> atomic;

Header

#include "tbb/atomic.h"

Description

An atomic<T> supports atomic read, write, fetch-and-add, fetch-and-store, and compare-and-swap. Type T may be an integral type, enumeration type, or a pointer type. When T is a pointer type, arithmetic operations are interpreted as pointer arithmetic. For example, if x has type atomic<float*> and a float occupies four bytes, then ++x advances x by four bytes. Arithmetic on atomic<T> is not allowed if T is an enumeration type, void*, or bool.

Some of the methods have template method variants that permit more selective memory fencing. On IA-32 and Intel® 64 architecture processors, they have the same effect as the non-templated variants. On processors with IA-64 architecture, they may improve performance by allowing the memory subsystem more latitude on the orders of reads and write. Using them may improve performance. The table below shows the fencing for the non-template form.

Operation Order Implied by Non-Template Methods

Kind

Description

Default For

acquire

Operations after the atomic operation never move over it.

read

release

Operations before the atomic operation never move over it.

write

sequentially consistent

Operations on either side never move over it and furthermore, the sequentially consistent atomic operations have a global order.

fetch_and_store, fetch_and_add, compare_and_swap

CAUTION

The copy constructor for class atomic<T> is not atomic. To atomically copy an atomic<T>, default-construct the copy first and assign to it. Below is an example that shows the difference.

      
           atomic<T> y(x);  // Not atomic
           atomic<T> z;
           z=x;             // Atomic assignment

The copy constructor is not atomic because it is compiler generated. In C++03 introducing any non-trivial constructors might remove an important property of atomic<T>: namespace scope instances are zero-initialized before namespace scope dynamic initializers run. This property can be essential for code executing early during program startup.

In C++03, to create an atomic<T> with a specific value, default-construct it first, and afterwards assign a value to it. Since C++11, a constexpr single argument constructor is available.

Members

namespace tbb {
                enum memory_semantics {
                    acquire,
                    release
                };
             
                struct atomic<T> {
                    typedef T value_type;
                    
                    // Supported since C++11
                    atomic() = default;
                    constexpr atomic(T arg)
             
                    template<memory_semantics M>
                    value_type compare_and_swap( value_type new_value, 
                                                 value_type comparand );
             
                    value_type compare_and_swap( value_type new_value, 
                                                 value_type comparand );
             
                    template<memory_semantics M>
                    value_type fetch_and_store( value_type new_value );
             
                    value_type fetch_and_store( value_type new_value );
             
                    operator value_type() const;
             
                    value_type operator=( value_type new_value );
                    atomic<T>& operator=( const atomic<T>& value );
             
                    // The following members exist only if T is an integral 
                    // or pointer type.
             
                    template<memory_semantics M>
                    value_type fetch_and_add( value_type addend );
             
                    value_type fetch_and_add( value_type addend );
             
                    template<memory_semantics M>
                    value_type fetch_and_increment();
             
                    value_type fetch_and_increment();
             
                    template<memory_semantics M>
                    value_type fetch_and_decrement();
             
                    value_type fetch_and_decrement();
             
                    value_type operator+=(value_type);
                    value_type operator-=(value_type);
                    value_type operator++();
                    value_type operator++(int);
                    value_type operator--();
                    value_type operator--(int);
                };
            } 

So that an atomic<T*> can be used like a pointer to T, the specialization atomic<T*> also defines:

        T* operator->() const;
The following table provides additional information on the members of this template class.
Member Description
memory_semantics Enum

Defines values used to select the template variants that permit more selective control over visibility of operations (see the table above).

atomic() = default

Supported since C++11.

Default constructor generated by compiler. This constructor behaves same as if there were no user defined constrcutors declared at all.

constexpr atomic(value_type arg)

Supported since C++11.

Initialize *this with value of arg. If the argument is a translation time constant, then initialization is performed during translation time, overwise initialization is performed at run time.

value_type fetch_and_add( value_type addend )

Let x be the value of *this. Atomically updates x = x + addend.

Returns: Original value of x.

value_type fetch_and_increment()

Let x be the value of *this. Atomically updates x = x + 1.

Returns: Original value of x.

value_type fetch_and_decrement()

Let x be the value of *this. Atomically updates x = x - 1.

Returns: Original value of x.

value_type compare_and_swap

value_type compare_and_swap( value_type new_value, value_type comparand )

Let x be the value of *this. Atomically compares x with comparand, and if they are equal, sets x=new_value.

Returns: Original value of x.

value_type fetch_and_store( value_type new_value )

Let x be the value of *this. Atomically exchanges old value of x with new_value.

Returns: Original value of x.

For more complete information about compiler optimizations, see our Optimization Notice.