使用GCC内置函数移植InterlockedExchange

4

Windows API提供了InterlockedExchange函数,可原子地设置内存中的值。使用仅有的GCC内建函数,我想要创建一个等效于该函数的函数。将值设置后调用内存障碍是否足够(请参见下面的代码)?

template <typename T>
T InterlockedExchange(volatile T& _data, T _value)
{
    const T oldValue = _data;
    _data = _value;
    __sync_synchronize();
    return oldValue;
}

谢谢。

编辑: 提供的代码片段不是解决问题的正确方案,因为它显然不具有原子性(但是,好吧,至少我要尝试一下)。


你将 _data 参数声明为引用,但后来使用指针解引用访问它。 - Some programmer dude
2个回答

10

使用 __sync_lock_test_and_set 而不是 __sync_val_compare_and_swap __sync_synchronize

这与 InterlockedExchange 的功能完全相同。

类似于以下代码(未经测试!):

template<typename T> T InterlockedExchange(T& data, T& new_val)
{
    return __sync_lock_test_and_set(&data, new_val);
}

编辑:
嗨,我看错了,你想要的是InterlockedExchange而不是InterlockedCompareExchange...所以你需要使用__sync_lock_test_and_set(这个名称可能会误导你,但它确实是你想要的)。
请参见此处,页面底部。


3
请注意,__sync_lock_test_and_set()只具有获取语义,因此这仅相当于InterlockedExchangeAcquire()。如果您需要完整的内存屏障,则需要添加__sync_synchronize();,相当于InterlockedExchange() - caf

0

你提供的例子不等价,因为它不是原子性的。两个竞争的线程执行你的函数时,可能都会取回相同的旧值,其中一个新值会被“丢失”。


确实,一旦我找到解决方案,我就会立即更改 :) - qdii

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接