__ATOMIC_RELAXED
means that the operation itself is atomic, without there being additional ordering constraints. In other words, the operation itself is atomic: another thread will only ever see the state before or after the operation, but never an intermediate state where the operation is partially executed. However the compiler, CPU, and memory system are free to reorder the operation with respect to other operations on other variables.
(shared = 2; tmp = shared;
with a relaxed store and load can't run as tmp = shared; shared = 2;
. RELAXED Operations on the same variable by the same thread are still ordered wrt. each other, but not wrt. anything else. See http://eel.is/c++draft/intro.races#19)
The gcc atomics are basically a copy of the C++11 spec, regardless of whether you use them in C or C++. Here is what the gcc atomics manual says (boldface emphasis on C++11 references is mine)
The following built-in functions approximately match the requirements
for the C++11 memory model. They are all identified by being prefixed
with ‘__atomic’ and most are overloaded so that they work with
multiple types.
⋮
The description of each memory order is only meant to roughly
illustrate the effects and is not a specification; see the C++11
memory model for precise semantics.
This explains the lack of detailed description of the memory orders.
So, turning to the C++11 spec, we find the following detail for __ATOMIC_RELAXED
:
Relaxed operation: there are no synchronization or ordering
constraints imposed on other reads or writes, only this operation's
atomicity is guaranteed (see Relaxed ordering below).
__atomic_exchange
or ordering theload
andstore
used by the function__atomic_exchange
? – Biller