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 |
- atomic_add:无返回值。
- atomic_add_return:返回变化后的值。
- 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是四个互斥原子操作函数。它们的区别如下:
- xchg函数:是最基础的互斥原子操作函数,用于交换给定内存位置的值与一个新值,并返回原始值。在此过程中,不会对内存的访问模型(如内存屏障)进行显式的约束。
- xchg_acquire函数:是xchg函数的一种变体,它在交换值的同时也会提供一个acquire内存屏障,确保该原子操作之前的内存访问在该原子操作之前完成,而该原子操作之后的内存访问将不会越过该原子操作。
- xchg_release函数:是xchg函数的另一种变体,它在交换值的同时也会提供一个release内存屏障,确保该原子操作之后的内存访问在该原子操作之后开始,并且该原子操作之前的内存访问不会越过该原子操作。
- 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, ...)