I use C11 * atomics to control the state enumeration between multiple threads. The code resembles the following:
static _Atomic State state;
void setToFoo(void)
{
atomic_store_explicit(&state, STATE_FOO, memory_order_release);
}
bool stateIsBar(void)
{
return atomic_load_explicit(&state, memory_order_acquire) == STATE_BAR;
}
This compiles (for ARM Cortex-M4):
<setToFoo>:
ldr r3, [pc,
dmb sy ; Memory barrier
movs r2,
strb r2, [r3,
bx lr
.word 0x00000000
<stateIsBar>:
ldr r3, [pc,
ldrb r0, [r3,
dmb sy ; Memory barrier
sub.w r0, r0, #2 ; Comparison and return follows
clz r0, r0
lsrs r0, r0,
bx lr
.word 0x00000000
Why does the fence face release and after acquisition? My mental model assumed that after release, a barrier will be placed (to “distribute” the stored variable and all other stores to other flows) and until received (to receive all previous stores from other flows).
* C11, ++ 11, ( ), . gcc
g++
. . http://en.cppreference.com/w/c/atomic/memory_order http://en.cppreference.com/w/cpp/atomic/memory_order