1. 后缀说明

acquire操作指的是在这条语句之后的所有内存操作只准在这条语句之后,不准被提前到这条语句之前。 release操作指的是在这条语句之前的所有内存操作只准在这条语句之前,不准被延后到这条语句之后。 relaxed操作指的是不保证任何的内存顺序。

2. 读写

1atomic_read(const atomic_t *v)
2atomic_read_acquire(const atomic_t *v)
3
4atomic_set(atomic_t *v, int i)
5atomic_set_release(atomic_t *v, int i)
col1 col2
(const atomic_t *v) (atomic_t *v, int i)
atomic_read atomic_set
atomic_read_acquire atomic_set_release

3. 加减

col1 col2 col3 col3
(int i, atomic_t *v) (int i, atomic_t *v) (atomic_t *v) (atomic_t *v)
atomic_add atomic_sub atomic_inc atomic_dec
atomic_add_return atomic_sub_return atomic_inc_return atomic_dec_return
atomic_add_return_acquire atomic_sub_return_acquire atomic_inc_return_acquire atomic_dec_return_acquire
atomic_add_return_release atomic_sub_return_release atomic_inc_return_release atomic_dec_return_release
atomic_add_return_relaxed atomic_sub_return_relaxed atomic_inc_return_relaxed atomic_dec_return_relaxed
atomic_fetch_add atomic_fetch_sub atomic_fetch_inc atomic_fetch_dec
atomic_fetch_add_acquire atomic_fetch_sub_acquire atomic_fetch_inc_acquire atomic_fetch_dec_acquire
atomic_fetch_add_release atomic_fetch_sub_release atomic_fetch_inc_release atomic_fetch_dec_release
atomic_fetch_add_relaxed atomic_fetch_sub_relaxed atomic_fetch_inc_relaxed atomic_fetch_dec_relaxed
  1. atomic_add:无返回值。
  2. atomic_add_return:返回变化后的值。
  3. atomic_fetch_add:返回变化前的值。

4. 位操作

col1 col2 col3 col3
(int i, atomic_t *v) (int i, atomic_t *v) (int i, atomic_t *v) (int i, atomic_t *v)
atomic_and atomic_andnot atomic_or atomic_xor
atomic_fetch_and atomic_fetch_andnot atomic_fetch_or atomic_fetch_xor
atomic_fetch_and_acquire atomic_fetch_andnot_acquire atomic_fetch_or_acquire atomic_fetch_xor_acquire
atomic_fetch_and_release atomic_fetch_andnot_release atomic_fetch_or_release atomic_fetch_xor_release
atomic_fetch_and_relaxed atomic_fetch_andnot_relaxed atomic_fetch_or_relaxed atomic_fetch_xor_relaxed

5. 交换

col1 col2 col3
(atomic_t *v, int i) (atomic_t *v, int old, int new) (atomic_t *v, int *old, int new)
atomic_xchg atomic_cmpxchg atomic_try_cmpxchg
atomic_xchg_acquire atomic_cmpxchg_acquire atomic_try_cmpxchg_acquire
atomic_xchg_release atomic_cmpxchg_release atomic_try_cmpxchg_release
atomic_xchg_relaxed atomic_cmpxchg_relaxed atomic_try_cmpxchg_relaxed

6. 对比

 1atomic_sub_and_test(int i, atomic_t *v)
 2atomic_dec_and_test(atomic_t *v)
 3atomic_inc_and_test(atomic_t *v)
 4
 5atomic_add_negative(int i, atomic_t *v)
 6atomic_fetch_add_unless(atomic_t *v, int a, int u)
 7atomic_add_unless(atomic_t *v, int a, int u)
 8atomic_inc_not_zero(atomic_t *v)
 9atomic_inc_unless_negative(atomic_t *v)
10atomic_dec_unless_positive(atomic_t *v)
11atomic_dec_if_positive(atomic_t *v)

7. xchg/cmpxchg

用于非atomic类型的变量,比如unsigned int

在Linux内核中,xchg、xchg_acquire、xchg_release和xchg_relaxed是四个互斥原子操作函数。它们的区别如下:

  1. xchg函数:是最基础的互斥原子操作函数,用于交换给定内存位置的值与一个新值,并返回原始值。在此过程中,不会对内存的访问模型(如内存屏障)进行显式的约束。
  2. xchg_acquire函数:是xchg函数的一种变体,它在交换值的同时也会提供一个acquire内存屏障,确保该原子操作之前的内存访问在该原子操作之前完成,而该原子操作之后的内存访问将不会越过该原子操作。
  3. xchg_release函数:是xchg函数的另一种变体,它在交换值的同时也会提供一个release内存屏障,确保该原子操作之后的内存访问在该原子操作之后开始,并且该原子操作之前的内存访问不会越过该原子操作。
  4. xchg_relaxed函数:是xchg函数的松散变体,它在交换值的过程中不提供任何内存屏障。这意味着对该原子操作之前和之后的内存访问没有明确的约束,可能会出现乱序执行或内存重排序。因此,xchg_relaxed通常用于对内存访问保持较低的一致性要求的情况下,以获得较高的性能。

总之,xchg_acquire和xchg_release函数提供了显式的内存屏障,用于明确约束原子操作之前和之后的内存访问序列。而xchg函数和xchg_relaxed函数则没有提供这样的约束,可以在一定程度上提高性能,但可能会牺牲一致性。因此,在选择使用这些函数时,需要根据具体的需求权衡性能和一致性。

col1 col2 col3 col2 col3
(ptr, …) (ptr, …) (ptr, oldp, …) (ptr, …) (ptr, oldp, …)
xchg cmpxchg try_cmpxchg cmpxchg64 try_cmpxchg64
xchg_acquire cmpxchg_acquire try_cmpxchg_acquire cmpxchg64_acquire try_cmpxchg64_acquire
xchg_release cmpxchg_release try_cmpxchg_release cmpxchg64_release try_cmpxchg64_release
xchg_relaxed cmpxchg_relaxed try_cmpxchg_relaxed cmpxchg64_relaxed try_cmpxchg64_relaxed
1cmpxchg_local(ptr, ...)
2cmpxchg64_local(ptr, ...)
1sync_cmpxchg(ptr, ...)
2cmpxchg_double(ptr, ...)
3cmpxchg_double_local(ptr, ...)

8. 参考资料

原子操作 | SuperSong的博客 (songyoulin.github.io)