Is it wrong to assume that atomic :: load should also act as a memory barrier to ensure that all previous non-atomic records become visible by other threads?
To illustrate:
volatile bool arm1 = false; std::atomic_bool arm2 = false; bool triggered = false;
Thread1:
arm1 = true; //std::std::atomic_thread_fence(std::memory_order_seq_cst); // this would do the trick if (arm2.load()) triggered = true;
Thread 2:
arm2.store(true); if (arm1) triggered = true;
I expected that after the execution of both the "running" would be true. Please do not suggest making arm1 atomic, you need to investigate the behavior of the atomic :: load.
Although I must admit that I do not fully understand the formal definitions of various relaxed semantics, the memory order I thought that the sequential ordering sequence was quite simple, because it ensures that "there is a single general order in which all threads follow all modifications in the same order" . For me, this means that std :: atomic :: load with the default memory order for std :: memory_order_seq_cst will also act as a memory pick. This is confirmed by the following statement in the “Consistent reconciliation” section:
Complete sequential sequencing requires a full CPU CPU command for all multi-core systems.
However, my simple example shows that this does not apply to MSVC 2013, gcc 4.9 (x86) and clang 3.5.1 (x86), where the atomic load is simply translated into a load statement.
#include <atomic> std::atomic_long al; #ifdef _WIN32 __declspec(noinline) #else __attribute__((noinline)) #endif long load() { return al.load(std::memory_order_seq_cst); } int main(int argc, char* argv[]) { long r = load(); }
With gcc, it looks like this:
load(): mov rax, QWORD PTR al[rip] ; <--- plain load here, no fence or xchg ret main: call load() xor eax, eax ret
I omit msvc and clang, which are essentially identical. Now on gcc for ARM we get what I expected:
load(): dmb sy ; <---- data memory barrier here movw r3,
This is not an academic question; it leads to a subtle race condition in our code, which casts doubt on my understanding of the behavior of std :: atomic.