6

以下两个引用似乎相互矛盾:

https://www.kernel.org/doc/Documentation/atomic_ops.txt

int atomic_cmpxchg(atomic_t *v, int old, int new);

这将对原子值 v 与给定的旧值和新值执行原子比较交换操作。与所有 atomic_xxx 操作一样,只要 *v 的所有其他访问都通过 atomic_xxx 操作执行,atomic_cmpxchg 只会满足其原子性语义。

atomic_cmpxchg 需要操作周围的显式内存屏障。

对比

https://www.kernel.org/doc/Documentation/memory-barriers.txt

任何修改内存中的某些状态并返回有关状态(旧的或新的)信息的原子操作都意味着在实际操作的每一侧都有一个 SMP 条件通用内存屏障 (smp_mb())(显式锁定操作除外,描述之后)。这些包括:

      <...>   
      atomic_xchg();  
      atomic_cmpxchg();
      <...> 

这些用于实现 LOCK 类和 UNLOCK 类操作以及调整引用计数器以实现对象破坏等事情,因此隐式内存屏障效果是必要的。

那么是否应该atomic_xchg()手动设置内存屏障?

4

1 回答 1

3

我还不知道 Linux 内核编程细节,所以这里是部分(一般)答案。

在 x86 上,这个操作带有完整的内存栅栏,不需要 in mfence// around op。lfencesfencecmpxchg

在其他具有宽松内存模型的架构上,它可以与其他内存语义相结合,例如“释放”,具体取决于如何atomic_cmpxchg()转换为操作码。

它在处理器方面。但是,有编译器也可以重新排序操作,所以如果编译器障碍不是由atomic_cmpxchg()(例如__asm__ __volatile__)暗示的,你需要一个。

于 2014-05-14T01:53:02.780 回答