Skip to the content.

gcc atomic

__atomic_compare_exchange_n

  bool __atomic_compare_exchange_n(
      type *ptr,
      type *expected,
      type desired,
      bool weak,
      int success_memorder,
      int failure_memorder
  );

一直在使用这个函数,但是没搞懂这里的几个参数都是做什么的,这里问了一下 codex ,回答应该是非常正确的: 还有一些疑问这个到底是如何实现的,但是暂时先这样了:

  1. 是如何提供 success_memorder 和 failure_memorder 的,也许看看
  2. 为什么会有 weak 这种失败的情况
Built-in Function: bool __atomic_compare_exchange_n (type *ptr, type *expected, type desired, bool weak, int success_memorder, int failure_memorder)
This built-in function implements an atomic compare and exchange operation. This compares the contents of *ptr with the contents of *expected. If equal, the operation is a read-modify-write operation that writes desired into *ptr. If they are not equal, the operation is a read and the current contents of *ptr are written into *expected. weak is true for weak compare_exchange, which may fail spuriously, and false for the strong variation, which never fails spuriously. Many targets only offer the strong variation and ignore the parameter. When in doubt, use the strong variation.

If desired is written into *ptr then true is returned and memory is affected according to the memory order specified by success_memorder. There are no restrictions on what memory order can be used here.

核心语义:

  1. 比较 *ptr 和 *expected
  2. 如果相等:
    • 把 desired 写入 *ptr
    • 返回 true
  3. 如果不相等:
    • 不写 desired
    • 把当前 *ptr 的值回写到 *expected
    • 返回 false

weak 参数

典型理解:

do {
    expected = old;
} while (!__atomic_compare_exchange_n(&x, &expected, new, true, ...));

这里用 weak=true 很常见,因为失败了就继续重试。

这里举一个例子说明下,什么时候 weak 不可以为 false:

例如,这里仅仅可以执行 release 业务一次,那么如何才可以:

	if (!__atomic_compare_exchange_n(&vi->release, &expected, 1, false,
					 __ATOMIC_ACQ_REL, __ATOMIC_RELAXED))
		return;
	// do the release

如果 weak = true ,如果出现 “无缘无故失败” ,那么就会放弃了通知

memorder

success_memorder

这个表示:

常见值:

直觉上:

failure_memorder

这个表示:

因为失败时只是读,没有写,所以它不能带 release 语义。

所以 GCC 要求:

常见搭配:

  - success = __ATOMIC_ACQUIRE, failure = __ATOMIC_RELAXED
  - success = __ATOMIC_ACQ_REL, failure = __ATOMIC_ACQUIRE
  - success = __ATOMIC_SEQ_CST, failure = __ATOMIC_SEQ_CST

细节

__atomic_exchange_n__atomic_compare_exchange_n

本站所有文章转发 CSDN 将按侵权追究法律责任,其它情况随意。