移植 InterlockedExchange,仅使用 GCC 内在函数
Posted
技术标签:
【中文标题】移植 InterlockedExchange,仅使用 GCC 内在函数【英文标题】:Porting InterlockedExchange, using GCC intrinsics only 【发布时间】:2012-01-06 06:47:27 【问题描述】:Windows API 提供InterlockedExchange
,它以原子方式在内存中设置一个值。仅使用 GCC 内部函数,我想创建一个与该函数等效的函数。设置值然后调用内存屏障就足够了(参见下面的代码)?
template <typename T>
T InterlockedExchange(volatile T& _data, T _value)
const T oldValue = _data;
_data = _value;
__sync_synchronize();
return oldValue;
谢谢。
编辑:建议的 sn-p 不是解决问题的正确方法,因为它显然不是原子的(但是,我不得不试一试至少)。
【问题讨论】:
您将_data
参数声明为引用,但稍后使用指针解引用访问它。
【参考方案1】:
使用 __sync_val_compare_and_swap
__sync_lock_test_and_set
,而不是 __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
(这个名字是一个误导性的英特尔名词,但它正是你想要的)。
请参阅页面底部的here。
【讨论】:
注意__sync_lock_test_and_set()
只有Acquire语义,所以这仅相当于InterlockedExchangeAcquire()
。您需要为完整的内存屏障添加__sync_synchronize();
,相当于InterlockedExchange()
。【参考方案2】:
您提出的示例不等效,因为它不是原子的。执行您的函数的两个竞赛线程都可以检索相同的旧值,其中一个新值“丢失”。
【讨论】:
确实,我一找到解决办法就改:)以上是关于移植 InterlockedExchange,仅使用 GCC 内在函数的主要内容,如果未能解决你的问题,请参考以下文章
找不到名为“interlockedexchange”的入口点
InterlockedExchange() 类型函数/内在函数的 MSDN 文档不一致?