refcount_t API 与 atomic_t 的比较 【ChatGPT】
refcount_t API 与 atomic_t 的比较
介绍
相关的内存排序类型
函数比较
-
非“读/修改/写”(RMW)操作
-
基于增量的操作,不返回值
-
基于减量的 RMW 操作,不返回值
-
基于增量的 RMW 操作,返回值
-
通用的减法/减量基于 RMW 操作,返回值
-
其他基于减量的 RMW 操作,返回值
-
基于锁的 RMW
介绍
refcount_t API 的目标是为实现对象的引用计数器提供一个最小的 API。虽然 lib/refcount.c 中的通用体系结构无关实现使用原子操作,但是在一些 refcount_() 和 atomic_() 函数之间存在一些差异,涉及内存排序保证。本文档概述了这些差异,并提供了相应的示例,以帮助维护者验证其代码针对这些内存排序保证的变化。
本文档中使用的术语试图遵循 tools/memory-model/Documentation/explanation.txt 中定义的正式 LKMM。
memory-barriers.txt 和 atomic_t.txt 提供了更多关于内存排序的背景知识,特别是针对原子操作。
相关的内存排序类型
注意
以下部分仅涵盖了原子操作和引用计数器相关的一些内存排序类型,并在本文档中使用。要了解更广泛的情况,请参阅 memory-barriers.txt 文档。
在没有任何内存排序保证的情况下(即完全无序),原子操作和引用计数器仅提供原子性和程序顺序(po)关系(在同一 CPU 上)。它保证每个 atomic_() 和 refcount_() 操作都是原子的,并且指令在单个 CPU 上按程序顺序执行。这是使用 READ_ONCE()/WRITE_ONCE() 和比较交换原语实现的。
强(完全)内存排序保证了在同一 CPU 上所有先前的加载和存储(所有 po-更早的指令)在执行同一 CPU 上的任何 po-后续指令之前完成。它还保证了在同一 CPU 上所有先前的存储和来自其他 CPU 的所有传播存储必须在原始 CPU 上执行任何 po-后续指令之前传播到所有其他 CPU(具有累积属性)。这是使用 smp_mb() 实现的。
RELEASE 内存排序保证了在同一 CPU 上所有先前的加载和存储(所有 po-更早的指令)在操作之前完成。它还保证了在同一 CPU 上所有先前的存储和来自其他 CPU 的所有传播存储必须在释放操作之前传播到所有其他 CPU(具有累积属性)。这是使用 smp_store_release() 实现的。
ACQUIRE 内存排序保证了在同一 CPU 上所有后续的加载和存储(所有 po-后续指令)在获取操作之后完成。它还保证了在同一 CPU 上所有后续的存储在获取操作执行后必须传播到所有其他 CPU。这是使用 smp_acquire__after_ctrl_dep() 实现的。
对于引用计数器的成功控制依赖性保证了如果成功获取对象的引用(引用计数增加或添加发生,函数返回 true),则进一步的存储将按顺序执行。对于存储的控制依赖性不是使用任何显式的屏障实现的,而是依赖于 CPU 不对存储进行推测。这仅是单个 CPU 关系,并且不对其他 CPU 提供任何保证。
函数比较
-
非“读/修改/写”(RMW)操作
函数变更:
- atomic_set() --> refcount_set()
- atomic_read() --> refcount_read()
内存排序保证变更:
- 无(均完全无序)
-
基于增量的操作,不返回值
函数变更:
- atomic_inc() --> refcount_inc()
- atomic_add() --> refcount_add()
内存排序保证变更:
- 无(均完全无序)
-
基于减量的 RMW 操作,不返回值
函数变更:
- atomic_dec() --> refcount_dec()
内存排序保证变更:
- 完全无序 --> RELEASE 排序
-
基于增量的 RMW 操作,返回值
函数变更:
- atomic_inc_not_zero() --> refcount_inc_not_zero()
- 无原子对应项 --> refcount_add_not_zero()
内存排序保证变更:
- 完全有序 --> 成功时对存储进行控制依赖
注意
我们在这里真的假设获得对象指针时提供了必要的排序!
-
通用的减法/减量基于 RMW 操作,返回值
函数变更:
- atomic_dec_and_test() --> refcount_dec_and_test()
- atomic_sub_and_test() --> refcount_sub_and_test()
内存排序保证变更:
- 完全有序 --> RELEASE 排序 + 成功时的 ACQUIRE 排序
-
其他基于减量的 RMW 操作,返回值
函数变更:
- 无原子对应项 --> refcount_dec_if_one()
- atomic_add_unless(&var, -1, 1) --> refcount_dec_not_one(&var)
内存排序保证变更:
- 完全有序 --> RELEASE 排序 + 控制依赖
注意
atomic_add_unless() 仅在成功时提供完全排序。
-
基于锁的 RMW
函数变更:
- atomic_dec_and_lock() --> refcount_dec_and_lock()
- atomic_dec_and_mutex_lock() --> refcount_dec_and_mutex_lock()
内存排序保证变更:
- 完全有序 --> RELEASE 排序 + 控制依赖 + 成功时持有 spin_lock()
本文来自博客园,作者:摩斯电码,未经同意,禁止转载