linuxsampler 2.3.1
lsatomic.h File Reference

Implementation of a small subset of the C++11 atomic operations. More...

Go to the source code of this file.

Classes

class  LinuxSampler::atomic< int >
 

Namespaces

namespace  LinuxSampler
 

Enumerations

enum  LinuxSampler::memory_order { LinuxSampler::memory_order_relaxed , LinuxSampler::memory_order_acquire , LinuxSampler::memory_order_release , LinuxSampler::memory_order_seq_cst }
 

Functions

void LinuxSampler::atomic_thread_fence (memory_order order)
 

Detailed Description

Implementation of a small subset of the C++11 atomic operations.

Note: When working with multithreading on modern CPUs, it's important not only to make sure that concurrent access to shared variables is made atomically, but also to be aware of the order the stores get visible to the loads in other threads. For example, if x and y are shared variables with initial values of 0, the following program:

// thread 1:
x.store(1, memory_order_relaxed);
r1 = y.load(memory_order_relaxed);
// thread 2:
y.store(1, memory_order_relaxed);
r2 = x.load(memory_order_relaxed);

would have a possible outcome of r1 == 0 and r2 == 0. The threads might for example run on separate CPU cores with separate caches, and the propagation of the store to the other core might be delayed and done after the loads. In that case, both loads will read the original value of 0 from the core's own cache.

The C++11 style operations use the memory_order parameter to let the programmer control the way shared memory stores get visible to loads in other threads. In the example above, relaxed order was used, which allows the CPU and compiler to reorder the memory accesses very freely. If memory_order_seq_cst had been used instead, the r1 == 0 and r2 == 0 outcome would have been impossible, as sequential consistency means that the execution of the program can be modeled by simply interleaving the instructions of the threads.

The default order is memory_order_seq_cst, as it is the easiest one to understand. It is however also the slowest. The relaxed order is the fastest, but it can't be used if the shared variable is used to synchronize threads for any other shared data. The third order is acquire/release, where an acquire-load is synchronizing with a release-store to the same variable.

See for example http://gcc.gnu.org/wiki/Atomic/GCCMM/AtomicSync for more information about the memory order parameter.

The supported operations of the implementation in this file are:

  • fences (acquire, release and seq_cst)
  • load and store of atomic<int> with relaxed, acquire/release or seq_cst memory ordering

The supported architectures are x86, powerpc and ARMv7.

Definition in file lsatomic.h.