如何在没有内存障碍的情况下实现InterlockedIncrement

时间:2012-10-15 03:08:12

标签: c multithreading interlocked

我实现了一个引用计数模式,为此我需要互锁设备,但没有内存栅栏(据我所知)。

不幸的是,只有Windows具有InterlockedDecrementNoFence编译器内在函数。 我怎么能用asm内联做到这一点?我也需要这个用于gcc / clang。

2 个答案:

答案 0 :(得分:1)

缺少至少一个固有的内存栅栏操作(取决于平台)对于此操作的语义来说几乎是不可能的。为了使原子增量/减量起作用,另一个处理器必须保证在它们对变量执行自己的操作之前看到原子操作的值,并且对变量的操作的可见性必须有一些保证总量订购。内存障碍,甚至是内存障碍,例如x86等强内存模型,其中标准内存操作具有获取/释放语义,对于原子递增/递减操作的正确性至关重要。

请记住,即使MSVC / gcc的文档说存在内存障碍,在x86上也不会应用实际的内存屏障(即MFENCE指令),因为强 - 平台的内存模型,而是锁定内存总线,以确保操作的原子性。另一方面,由于该平台的内存模型较弱,IA64将需要内存屏障。 ARM也是如此。

答案 1 :(得分:1)

这不是一个直接的答案,而是一个替代提案。如果你可以使用C11(或C ++ 11),那么memory_order_relaxed的原子操作怎么样?您的编译器可能在弱内存模型平台上不生成内存栅栏。 (这取决于编译器供应商/版本)

#include <stdatomic.h>

atomic_int var;
int oldval;

oldval = atomic_fetch_sub_explicit(&var, 1, memory_order_relaxed);