我正在使用 C11* atomics 来管理几个线程之间的状态枚举。代码类似于以下内容:
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;
}
这组装(对于 ARM Cortex-M4)到:
<setToFoo>:
ldr r3, [pc, #8]
dmb sy ; Memory barrier
movs r2, #0
strb r2, [r3, #0] ; store STATE_FOO
bx lr
.word 0x00000000
<stateIsBar>:
ldr r3, [pc, #16]
ldrb r0, [r3, #0] ; load state
dmb sy ; Memory barrier
sub.w r0, r0, #2 ; Comparison and return follows
clz r0, r0
lsrs r0, r0, #5
bx lr
.word 0x00000000
为什么要在发布之前和获取之后放置围栏?我的心智模型假设在释放之后(将要存储的变量和所有其他存储“传播”到其他线程)和获取之前(从其他线程接收所有先前的存储)之后放置障碍。
*虽然这个特定示例是在 C11 中给出的,但在 C++11 中的情况是相同的,因为在内存排序方面,两者共享相同的概念(甚至相同的枚举)。gcc
并g++
在这种情况下发出相同的机器代码。请参阅http://en.cppreference.com/w/c/atomic/memory_order和http://en.cppreference.com/w/cpp/atomic/memory_order