【问题标题】:Porting InterlockedExchange, using GCC intrinsics only移植 InterlockedExchange,仅使用 GCC 内在函数
【发布时间】: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 参数声明为引用,但稍后使用指针解引用访问它。

标签: c gcc port atomic


【解决方案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】:

您提出的示例不等效,因为它不是原子的。执行您的函数的两个竞赛线程都可以检索相同的旧值,其中一个新值“丢失”。

【讨论】:

  • 确实,我一找到解决办法就改:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-02
  • 1970-01-01
  • 2015-05-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多