模块契约Atomic

错误

空地址、错误对齐、空 Expected 或非法内存顺序设置 XERR_ARGUMENT。失败的写操作不修改对象。成功操作不会清除调用前已有错误。Init、Store、栅栏与 Pause 对非法参数一律静默忽略(空操作),读改写族在参数非法时返回零值/假并设置错误。

约束适用函数
加载顺序(RELAXED/ACQUIRE/SEQ_CST)全部 Load
存储顺序(RELAXED/RELEASE/SEQ_CST)全部 Store
五种顺序Exchange、Fetch*、ThreadFence、SignalFence
失败顺序不得含 Release、不得强于成功顺序全部 CompareExchange

完整可编译示例位于 examples/core/atomic,并发计数与单头文件测试分别位于 tests/core/test_atomic_threads.c 和 tests/single/test_single_atomic.c。

裁剪与依赖

启用 XRT_FEATURE_ATOMIC 即可使用本模块,只依赖 core。未启用时不声明原子类型和函数,也不会编译平台原子实现。

类型与初始化

xatomic64 声明为至少 8 字节对齐,xatomicptr 按指针宽度对齐。对象发布给其他执行流后,只能通过 Atomic API 访问 Value;不能混用普通读写、memcpy 或直接赋值。

TinyCC x86 不会把成员类型的 8 字节对齐要求传播到栈上外层结构。XRT 对正常对齐对象仍使用无锁指令;对该编译器产生的 4 字节对齐 xatomic64 使用内部 64 槽分片锁,并提供不弱于请求的内存顺序。其他编译器仍拒绝未按类型自然对齐的 64 位对象。

自动和动态对象在发布前使用 xrtAtomic32Init()、xrtAtomic64Init()、xrtAtomicPtrInit()。静态对象使用 XRT_ATOMIC32_INIT()、XRT_ATOMIC64_INIT()、XRT_ATOMICPTR_INIT():

初始化不是并发操作。对象仍被其他线程访问时,不得重新初始化、移动或销毁。

内存顺序

  • RELAXED 只保证该值原子更新,适合独立统计计数。
  • ACQUIRE 用于读取已经发布的数据。
  • RELEASE 用于发布此前写入的数据。
  • ACQ_REL 用于同时读取并发布的读改写操作。
  • SEQ_CST 提供最直观的全局顺序,适合控制路径和尚未证明可放宽的代码。

加载只接受 RELAXED、ACQUIRE、SEQ_CST;存储只接受 RELAXED、RELEASE、SEQ_CST。比较交换失败顺序不能包含 Release,并且不能强于成功顺序。非法组合设置 XERR_ARGUMENT,对象保持不变。

GCC 和 Clang 直接使用对应的内存顺序。只提供全栅栏原语的平台会采用更强顺序,绝不会弱化公开合同。

32 位与 64 位整数

32 位和 64 位类型都提供 Load、Store、Exchange、CompareExchange、FetchAdd、FetchSub、FetchAnd、FetchOr、FetchXor。Fetch* 返回修改前的值,无符号加减按模宽度回绕。

强比较交换不产生伪失败。成功时写入 Desired;失败时对象不变,并把当前实际值写回 Expected,因此调用方可直接继续 CAS 循环。Expected 必须指向调用方独占的普通标量,不得与原子对象重叠;它本身的并发保护由调用方负责。

原生后端直接使用平台的加法和按位读改写指令。必须走 CAS 的退化路径会复用失败操作返回的实际值,不会在每次竞争失败后额外执行一次原子加载。

原子指针

空指针是合法值。CompareExchange 通过布尔结果区分成功与失败,不依赖返回指针是否为空。Atomic 只管理指针槽,不负责目标对象的引用计数、生命周期或内存回收;无锁链表仍必须单独解决 ABA 和安全回收问题。

类型与初始化

xrtAtomicIsLockFree函数

查询自然对齐的指定字节宽度是否由当前目标无锁实现。

bool xrtAtomicIsLockFree(size_t iSize)

参数

参数方向约束说明
iSize输入—字节宽度;当前公开标量只认 4、8 与指针宽度
返回值
返回含义失败时状态
true该宽度由目标无锁实现(保守口径:静态可证明才为真)—
false其他宽度,或后端无法静态证明无锁纯查询,不设置错误
错误
  • 无 — 查询采用保守口径:返回 false 不表示对应 Atomic API 失去原子语义。需要对外宣称 lock-free 的算法必须先检查其最大原子宽度。

范例已编译验证

core/atomic_tour · 杂项 · 发布无锁算法前先检查宽度

if ( !xrtAtomicIsLockFree(sizeof(uint32)) ||
	!xrtAtomicIsLockFree(sizeof(uint64)) ) {
	goto Cleanup;
}

xrtAtomic32Init函数

把 32 位原子对象置为指定值。仅用于发布前的单线程初始化,不是并发操作。

void xrtAtomic32Init(xatomic32* pAtomic, uint32 iValue)

参数

参数方向约束说明
pAtomic输出建议非空目标对象;空或未对齐指针是空操作
iValue输入—初始值
返回值
返回含义
无地址非法时静默忽略,不设置错误

范例已编译验证

core/atomic_tour · RMW 补集 · 初始化后立即交换取旧值

xrtAtomic32Init(&A32, 0x0Fu);
iOld32 = xrtAtomic32Exchange(&A32, 0x3Cu, XMEMORY_ACQ_REL);

xrtAtomic64Init函数

把 64 位原子对象置为指定值。仅用于发布前的单线程初始化。

void xrtAtomic64Init(xatomic64* pAtomic, uint64 iValue)

参数

参数方向约束说明
pAtomic输出建议非空、8 字节对齐目标对象;地址非法时是空操作
iValue输入—初始值
返回值
返回含义
无地址非法时静默忽略,不设置错误

范例已编译验证

core/atomic_tour · 64 位 · 初始 100,交换为 50

xrtAtomic64Init(&A64, UINT64_C(100));
iOld64 = xrtAtomic64Exchange(&A64, UINT64_C(50),
	XMEMORY_ACQ_REL);

xrtAtomicPtrInit函数

把原子指针对象置为指定值。仅用于发布前的单线程初始化;空指针是合法值。

void xrtAtomicPtrInit(xatomicptr* pAtomic, ptr pValue)

参数

参数方向约束说明
pAtomic输出建议非空目标对象
pValue输入允许空初始指针值
返回值
返回含义
无地址非法时静默忽略,不设置错误

范例已编译验证

core/atomic_tour · 指针 · 发布后再交换

xrtAtomicPtrInit(&APtr, (ptr)&s_Target[0]);
pOld = xrtAtomicPtrExchange(&APtr, (ptr)&s_Target[1],
	XMEMORY_ACQ_REL);

xmemoryorder类型

原子操作的内存顺序与 C11 语义一致。

值语义
XMEMORY_RELAXEDRELAXED
XMEMORY_ACQUIREACQUIRE
XMEMORY_RELEASERELEASE
XMEMORY_ACQ_RELACQREL
XMEMORY_SEQ_CST顺序一致(默认最强)
typedef enum xmemoryorder { XMEMORY_RELAXED = 0, XMEMORY_ACQUIRE = 1, XMEMORY_RELEASE = 2, XMEMORY_ACQ_REL = 3, XMEMORY_SEQ_CST = 4 } xmemoryorder;
32 位与 64 位整数

xrtAtomic32Load函数

原子读取 32 位值。

uint32 xrtAtomic32Load(const xatomic32* pAtomic, xmemoryorder iOrder)

参数

参数方向约束说明
pAtomic输入非空、4 字节对齐目标对象
iOrder输入RELAXED/ACQUIRE/SEQ_CST加载允许的顺序
返回值
返回含义失败时状态
当前值原子快照参数非法时返回 0;错误经 xrtGetError() 报告
错误
  • XERR_ARGUMENT — 指针为空/未对齐,或顺序不是三种加载顺序之一

范例已编译验证

core/atomic_tour · RMW 补集 · ACQUIRE 配对发布写

if ( (iOld32 != 0x0Fu) ||
	(xrtAtomic32Load(&A32, XMEMORY_ACQUIRE) != 0x3Cu) ) {

xrtAtomic32Store函数

原子写入 32 位值。

void xrtAtomic32Store(xatomic32* pAtomic, uint32 iValue, xmemoryorder iOrder)

参数

参数方向约束说明
pAtomic输入非空、4 字节对齐目标对象
iValue输入—新值
iOrder输入RELAXED/RELEASE/SEQ_CST存储允许的顺序
返回值
返回含义
无参数非法时不写入、不设置错误

范例已编译验证

core/atomic_tour · RMW 补集 · RELEASE 发布后紧接读改写

xrtAtomic32Store(&A32, 0x33u, XMEMORY_RELEASE);
iOld32 = xrtAtomic32FetchAdd(&A32, 0x0Cu, XMEMORY_ACQ_REL);

xrtAtomic32Exchange函数

原子替换 32 位值并返回旧值。

uint32 xrtAtomic32Exchange(xatomic32* pAtomic, uint32 iValue, xmemoryorder iOrder)

参数

参数方向约束说明
pAtomic输入/输出非空、4 字节对齐目标对象
iValue输入—新值
iOrder输入五种顺序均可读改写顺序
返回值
返回含义失败时状态
旧值替换前的原子快照参数非法时返回 0 且对象不变;错误经 xrtGetError() 报告
错误
  • XERR_ARGUMENT — 指针非法或顺序非法

范例已编译验证

core/atomic_tour · RMW 补集 · 交换取旧值再核对

xrtAtomic32Init(&A32, 0x0Fu);
iOld32 = xrtAtomic32Exchange(&A32, 0x3Cu, XMEMORY_ACQ_REL);

xrtAtomic32CompareExchange函数

强比较交换:当前值等于 *pExpected 时写入 iDesired;失败时把实际值写回 *pExpected,不产生伪失败。

bool xrtAtomic32CompareExchange(xatomic32* pAtomic, uint32* pExpected, uint32 iDesired, xmemoryorder iSuccess, xmemoryorder iFailure)

参数

参数方向约束说明
pAtomic输入/输出非空、4 字节对齐目标对象
pExpected输入/输出非空、调用方独占期望值;失败时被改写为实际值
iDesired输入—成功时写入的值
iSuccess输入五种顺序均可成功路径顺序
iFailure输入加载顺序,且不强于成功失败路径顺序;不能含 Release
返回值
返回含义失败时状态
true匹配并已写入 iDesired—
false不匹配(对象不变,*pExpected 已回写)或参数非法参数非法时对象与 *pExpected 均不变;错误经 xrtGetError() 报告
错误
  • XERR_ARGUMENT — 指针为空/未对齐、pExpected 为空、失败顺序含 Release 或强于成功顺序

范例已编译验证

core/atomic_tour · CAS · 失败路径把实际值 0x0A 回写

iExpected = 0x99u;  /* 期望错误:失败并把实际值 0x0A 写回 */
if ( xrtAtomic32CompareExchange(&A32, &iExpected, 0x0Bu,
		XMEMORY_ACQ_REL, XMEMORY_ACQUIRE) ||
	(iExpected != 0x0Au) ) {
	goto Cleanup;
}

xrtAtomic32FetchAdd函数

原子加并返回旧值;无符号按模 2^32 回绕。

uint32 xrtAtomic32FetchAdd(xatomic32* pAtomic, uint32 iValue, xmemoryorder iOrder)

参数

参数方向约束说明
pAtomic输入/输出非空、4 字节对齐目标对象
iValue输入—加数
iOrder输入五种顺序均可读改写顺序
返回值
返回含义失败时状态
旧值加法前的原子快照参数非法时返回 0 且对象不变;错误经 xrtGetError() 报告
错误
  • XERR_ARGUMENT — 指针非法或顺序非法

范例已编译验证

core/atomic_tour · RMW 补集 · 0x33 + 0x0C = 0x3F

iOld32 = xrtAtomic32FetchAdd(&A32, 0x0Cu, XMEMORY_ACQ_REL);
if ( (iOld32 != 0x33u) ||
	(xrtAtomic32Load(&A32, XMEMORY_ACQUIRE) != 0x3Fu) ) {

xrtAtomic32FetchSub函数

原子减并返回旧值;无符号按模 2^32 回绕。

uint32 xrtAtomic32FetchSub(xatomic32* pAtomic, uint32 iValue, xmemoryorder iOrder)

参数

参数方向约束说明
pAtomic输入/输出非空、4 字节对齐目标对象
iValue输入—减数
iOrder输入五种顺序均可读改写顺序
返回值
返回含义失败时状态
旧值减法前的原子快照参数非法时返回 0 且对象不变;错误经 xrtGetError() 报告
错误
  • XERR_ARGUMENT — 指针非法或顺序非法

范例已编译验证

core/atomic_tour · RMW 补集 · 0x3F − 0x0F = 0x30

iOld32 = xrtAtomic32FetchSub(&A32, 0x0Fu, XMEMORY_ACQ_REL);
if ( (iOld32 != 0x3Fu) ||
	(xrtAtomic32Load(&A32, XMEMORY_ACQUIRE) != 0x30u) ) {

xrtAtomic32FetchAnd函数

原子按位与并返回旧值。

uint32 xrtAtomic32FetchAnd(xatomic32* pAtomic, uint32 iValue, xmemoryorder iOrder)

参数

参数方向约束说明
pAtomic输入/输出非空、4 字节对齐目标对象
iValue输入—掩码
iOrder输入五种顺序均可读改写顺序
返回值
返回含义失败时状态
旧值与运算前的原子快照参数非法时返回 0 且对象不变;错误经 xrtGetError() 报告
错误
  • XERR_ARGUMENT — 指针非法或顺序非法

范例已编译验证

core/atomic_tour · RMW 补集 · 0x3C & 0x0F = 0x0C

iOldAnd = xrtAtomic32FetchAnd(&A32, 0x0Fu, XMEMORY_ACQ_REL);
if ( iOldAnd != 0x3Cu ) {

xrtAtomic32FetchOr函数

原子按位或并返回旧值。

uint32 xrtAtomic32FetchOr(xatomic32* pAtomic, uint32 iValue, xmemoryorder iOrder)

参数

参数方向约束说明
pAtomic输入/输出非空、4 字节对齐目标对象
iValue输入—置位掩码
iOrder输入五种顺序均可读改写顺序
返回值
返回含义失败时状态
旧值或运算前的原子快照参数非法时返回 0 且对象不变;错误经 xrtGetError() 报告
错误
  • XERR_ARGUMENT — 指针非法或顺序非法

范例已编译验证

core/atomic_tour · RMW 补集 · 0x0C | 0x06 = 0x0E

iOldOr = xrtAtomic32FetchOr(&A32, 0x06u, XMEMORY_ACQ_REL);
if ( iOldOr != 0x0Cu ) {

xrtAtomic32FetchXor函数

原子按位异或并返回旧值。

uint32 xrtAtomic32FetchXor(xatomic32* pAtomic, uint32 iValue, xmemoryorder iOrder)

参数

参数方向约束说明
pAtomic输入/输出非空、4 字节对齐目标对象
iValue输入—翻转掩码
iOrder输入五种顺序均可读改写顺序
返回值
返回含义失败时状态
旧值异或运算前的原子快照参数非法时返回 0 且对象不变;错误经 xrtGetError() 报告
错误
  • XERR_ARGUMENT — 指针非法或顺序非法

范例已编译验证

core/atomic_tour · RMW 补集 · 0x0E ^ 0x0B = 0x05

iOld32 = xrtAtomic32FetchXor(&A32, 0x0Bu, XMEMORY_ACQ_REL);
if ( (iOld32 != 0x0Eu) ||
	(xrtAtomic32Load(&A32, XMEMORY_ACQUIRE) != 0x05u) ) {

xrtAtomic64Load函数

原子读取 64 位值。顺序与错误契约同 32 位形态。

uint64 xrtAtomic64Load(const xatomic64* pAtomic, xmemoryorder iOrder)

参数

参数方向约束说明
pAtomic输入非空、8 字节对齐目标对象
iOrder输入RELAXED/ACQUIRE/SEQ_CST加载允许的顺序
返回值
返回含义失败时状态
当前值原子快照参数非法时返回 0;错误经 xrtGetError() 报告
错误
  • XERR_ARGUMENT — 指针为空/未按 8 字节对齐,或顺序非法

范例已编译验证

core/atomic · 计数器 · 纯计数读用 RELAXED 足够

printf("counter=%llu\n", (unsigned long long)xrtAtomic64Load(&Counter, XMEMORY_RELAXED));

xrtAtomic64Store函数

原子写入 64 位值。失败时不写入、不设置错误。

void xrtAtomic64Store(xatomic64* pAtomic, uint64 iValue, xmemoryorder iOrder)

参数

参数方向约束说明
pAtomic输入非空、8 字节对齐目标对象
iValue输入—新值
iOrder输入RELAXED/RELEASE/SEQ_CST存储允许的顺序
返回值
返回含义
无参数非法时不写入、不设置错误

范例已编译验证

core/atomic_tour · 64 位 · RELEASE 写入后 ACQUIRE 核对

xrtAtomic64Store(&A64, UINT64_C(7), XMEMORY_RELEASE);
if ( xrtAtomic64Load(&A64, XMEMORY_ACQUIRE) != UINT64_C(7) ) {

xrtAtomic64Exchange函数

原子替换 64 位值并返回旧值。

uint64 xrtAtomic64Exchange(xatomic64* pAtomic, uint64 iValue, xmemoryorder iOrder)

参数

参数方向约束说明
pAtomic输入/输出非空、8 字节对齐目标对象
iValue输入—新值
iOrder输入五种顺序均可读改写顺序
返回值
返回含义失败时状态
旧值替换前的原子快照参数非法时返回 0 且对象不变;错误经 xrtGetError() 报告
错误
  • XERR_ARGUMENT — 指针非法或顺序非法

范例已编译验证

core/atomic_tour · 64 位 · 100 换 50,取回 100

xrtAtomic64Init(&A64, UINT64_C(100));
iOld64 = xrtAtomic64Exchange(&A64, UINT64_C(50),
	XMEMORY_ACQ_REL);

xrtAtomic64CompareExchange函数

64 位强比较交换;失败时把实际值写回 *pExpected,不产生伪失败。

bool xrtAtomic64CompareExchange(xatomic64* pAtomic, uint64* pExpected, uint64 iDesired, xmemoryorder iSuccess, xmemoryorder iFailure)

参数

参数方向约束说明
pAtomic输入/输出非空、8 字节对齐目标对象
pExpected输入/输出非空、调用方独占期望值;失败时被改写为实际值
iDesired输入—成功时写入的值
iSuccess输入五种顺序均可成功路径顺序
iFailure输入加载顺序,且不强于成功失败路径顺序;不能含 Release
返回值
返回含义失败时状态
true匹配并已写入 iDesired—
false不匹配或参数非法不匹配时 *pExpected 已回写;参数非法时对象不变;错误经 xrtGetError() 报告
错误
  • XERR_ARGUMENT — 指针为空/未对齐、pExpected 为空、失败顺序含 Release 或强于成功顺序

范例已编译验证

core/atomic · CAS · 成功序 ACQ_REL + 失败序 ACQUIRE

if (
	xrtAtomic64CompareExchange(
		&Counter,
		&iExpected,
		10u,
		XMEMORY_ACQ_REL,
		XMEMORY_ACQUIRE
	)
) {

xrtAtomic64FetchAdd函数

原子加并返回旧值;无符号按模 2^64 回绕。

uint64 xrtAtomic64FetchAdd(xatomic64* pAtomic, uint64 iValue, xmemoryorder iOrder)

参数

参数方向约束说明
pAtomic输入/输出非空、8 字节对齐目标对象
iValue输入—加数
iOrder输入五种顺序均可读改写顺序
返回值
返回含义失败时状态
旧值加法前的原子快照参数非法时返回 0 且对象不变;错误经 xrtGetError() 报告
错误
  • XERR_ARGUMENT — 指针非法或顺序非法

范例已编译验证

core/atomic · 计数器 · 纯计数用 RELAXED

(void)xrtAtomic64FetchAdd(&Counter, 1u, XMEMORY_RELAXED);

xrtAtomic64FetchSub函数

原子减并返回旧值;无符号按模 2^64 回绕。

uint64 xrtAtomic64FetchSub(xatomic64* pAtomic, uint64 iValue, xmemoryorder iOrder)

参数

参数方向约束说明
pAtomic输入/输出非空、8 字节对齐目标对象
iValue输入—减数
iOrder输入五种顺序均可读改写顺序
返回值
返回含义失败时状态
旧值减法前的原子快照参数非法时返回 0 且对象不变;错误经 xrtGetError() 报告
错误
  • XERR_ARGUMENT — 指针非法或顺序非法

范例已编译验证

core/atomic_tour · 64 位 · 50 − 20 = 30

iOld64 = xrtAtomic64FetchSub(&A64, UINT64_C(20),
	XMEMORY_ACQ_REL);
if ( (iOld64 != UINT64_C(50)) ||
	(xrtAtomic64Load(&A64, XMEMORY_ACQUIRE) != UINT64_C(30)) ) {

xrtAtomic64FetchAnd函数

原子按位与并返回旧值。

uint64 xrtAtomic64FetchAnd(xatomic64* pAtomic, uint64 iValue, xmemoryorder iOrder)

参数

参数方向约束说明
pAtomic输入/输出非空、8 字节对齐目标对象
iValue输入—掩码
iOrder输入五种顺序均可读改写顺序
返回值
返回含义失败时状态
旧值与运算前的原子快照参数非法时返回 0 且对象不变;错误经 xrtGetError() 报告
错误
  • XERR_ARGUMENT — 指针非法或顺序非法

范例已编译验证

core/atomic_tour · 64 位 · 30 & 28 = 28

iOld64 = xrtAtomic64FetchAnd(&A64, UINT64_C(0x1C),
	XMEMORY_ACQ_REL);
if ( (iOld64 != UINT64_C(30)) ||
	(xrtAtomic64Load(&A64, XMEMORY_ACQUIRE) != UINT64_C(28)) ) {

xrtAtomic64FetchOr函数

原子按位或并返回旧值。

uint64 xrtAtomic64FetchOr(xatomic64* pAtomic, uint64 iValue, xmemoryorder iOrder)

参数

参数方向约束说明
pAtomic输入/输出非空、8 字节对齐目标对象
iValue输入—置位掩码
iOrder输入五种顺序均可读改写顺序
返回值
返回含义失败时状态
旧值或运算前的原子快照参数非法时返回 0 且对象不变;错误经 xrtGetError() 报告
错误
  • XERR_ARGUMENT — 指针非法或顺序非法

范例已编译验证

core/atomic_tour · 64 位 · 28 | 3 = 31

iOld64 = xrtAtomic64FetchOr(&A64, UINT64_C(3),
	XMEMORY_ACQ_REL);
if ( (iOld64 != UINT64_C(28)) ||
	(xrtAtomic64Load(&A64, XMEMORY_ACQUIRE) != UINT64_C(31)) ) {

xrtAtomic64FetchXor函数

原子按位异或并返回旧值。

uint64 xrtAtomic64FetchXor(xatomic64* pAtomic, uint64 iValue, xmemoryorder iOrder)

参数

参数方向约束说明
pAtomic输入/输出非空、8 字节对齐目标对象
iValue输入—翻转掩码
iOrder输入五种顺序均可读改写顺序
返回值
返回含义失败时状态
旧值异或运算前的原子快照参数非法时返回 0 且对象不变;错误经 xrtGetError() 报告
错误
  • XERR_ARGUMENT — 指针非法或顺序非法

范例已编译验证

core/atomic_tour · 64 位 · 31 ^ 31 = 0

iOld64 = xrtAtomic64FetchXor(&A64, UINT64_C(31),
	XMEMORY_ACQ_REL);
if ( (iOld64 != UINT64_C(31)) ||
	(xrtAtomic64Load(&A64, XMEMORY_ACQUIRE) != 0u) ) {
原子指针

xrtAtomicPtrLoad函数

原子读取指针值。

ptr xrtAtomicPtrLoad(const xatomicptr* pAtomic, xmemoryorder iOrder)

参数

参数方向约束说明
pAtomic输入非空、按指针对齐目标对象
iOrder输入RELAXED/ACQUIRE/SEQ_CST加载允许的顺序
返回值
返回含义失败时状态
当前指针原子快照;空指针是合法值参数非法时返回 NULL;错误经 xrtGetError() 报告
错误
  • XERR_ARGUMENT — 指针非法或顺序非法

范例已编译验证

core/atomic_tour · 指针 · ACQUIRE 读取交换结果

if ( (pOld != (ptr)&s_Target[0]) ||
	(xrtAtomicPtrLoad(&APtr, XMEMORY_ACQUIRE) !=
		(ptr)&s_Target[1]) ) {

xrtAtomicPtrStore函数

原子写入指针值。失败时不写入、不设置错误。

void xrtAtomicPtrStore(xatomicptr* pAtomic, ptr pValue, xmemoryorder iOrder)

参数

参数方向约束说明
pAtomic输入非空、按指针对齐目标对象
pValue输入允许空新指针值
iOrder输入RELAXED/RELEASE/SEQ_CST存储允许的顺序
返回值
返回含义
无参数非法时不写入、不设置错误

范例已编译验证

core/atomic_tour · 指针 · CAS 后直接写回

xrtAtomicPtrStore(&APtr, (ptr)&s_Target[1], XMEMORY_RELEASE);
if ( xrtAtomicPtrLoad(&APtr, XMEMORY_ACQUIRE) !=
	(ptr)&s_Target[1] ) {

xrtAtomicPtrExchange函数

原子替换指针并返回旧值。

ptr xrtAtomicPtrExchange(xatomicptr* pAtomic, ptr pValue, xmemoryorder iOrder)

参数

参数方向约束说明
pAtomic输入/输出非空、按指针对齐目标对象
pValue输入允许空新指针值
iOrder输入五种顺序均可读改写顺序
返回值
返回含义失败时状态
旧指针替换前的原子快照参数非法时返回 NULL 且对象不变;错误经 xrtGetError() 报告
错误
  • XERR_ARGUMENT — 指针非法或顺序非法

范例已编译验证

core/atomic_tour · 指针 · 发布后立即交换

xrtAtomicPtrInit(&APtr, (ptr)&s_Target[0]);
pOld = xrtAtomicPtrExchange(&APtr, (ptr)&s_Target[1],
	XMEMORY_ACQ_REL);

xrtAtomicPtrCompareExchange函数

指针强比较交换;失败时把实际指针写回 *pExpected,不产生伪失败。

bool xrtAtomicPtrCompareExchange(xatomicptr* pAtomic, ptr* pExpected, ptr pDesired, xmemoryorder iSuccess, xmemoryorder iFailure)

参数

参数方向约束说明
pAtomic输入/输出非空、按指针对齐目标对象
pExpected输入/输出非空、调用方独占期望指针;失败时被改写为实际值
pDesired输入允许空成功时写入的指针
iSuccess输入五种顺序均可成功路径顺序
iFailure输入加载顺序,且不强于成功失败路径顺序;不能含 Release
返回值
返回含义失败时状态
true匹配并已写入 pDesired—
false不匹配(对象不变,*pExpected 已回写)或参数非法参数非法时对象与 *pExpected 均不变;错误经 xrtGetError() 报告
错误
  • XERR_ARGUMENT — 指针为空、pExpected 为空、失败顺序含 Release 或强于成功顺序

范例已编译验证

core/atomic_tour · 指针 · 错误期望触发失败回写

pExpected = (ptr)&s_Target[0];  /* 错误期望:失败回写 */
if ( xrtAtomicPtrCompareExchange(&APtr, &pExpected,
		(ptr)&s_Target[0], XMEMORY_ACQ_REL,
		XMEMORY_ACQUIRE) ||
	(pExpected != (ptr)&s_Target[1]) ) {
	goto Cleanup;
}
栅栏与自旋

xrtAtomicThreadFence函数

建立线程间栅栏;参数非法时是空操作。

void xrtAtomicThreadFence(xmemoryorder iOrder)

参数

参数方向约束说明
iOrder输入五种顺序均可栅栏强度;RELAXED 无同步效果
返回值
返回含义
无非法顺序静默忽略,不设置错误

范例已编译验证

core/atomic_tour · 杂项 · 与读改写配对

xrtAtomicThreadFence(XMEMORY_ACQ_REL);
xrtAtomicSignalFence(XMEMORY_SEQ_CST);
xrtAtomicPause();

xrtAtomicSignalFence函数

只约束编译器对当前线程与信号处理器可见访问的重排,不生成 CPU 栅栏。

void xrtAtomicSignalFence(xmemoryorder iOrder)

参数

参数方向约束说明
iOrder输入五种顺序均可编译器重排约束强度
返回值
返回含义
无非法顺序静默忽略,不设置错误

范例已编译验证

core/atomic_tour · 杂项 · 三件套并置

xrtAtomicThreadFence(XMEMORY_ACQ_REL);
xrtAtomicSignalFence(XMEMORY_SEQ_CST);
xrtAtomicPause();

xrtAtomicPause函数

短自旋提示:不让出时间片、不等待事件,也不保证公平性。长等待应使用后续同步原语或任务等待源。

void xrtAtomicPause()

参数

参数方向约束说明
无——无参数
返回值
返回含义
无纯提示,不会失败

范例已编译验证

core/atomic_tour · 杂项 · 自旋循环体内插入

xrtAtomicThreadFence(XMEMORY_ACQ_REL);
xrtAtomicSignalFence(XMEMORY_SEQ_CST);
xrtAtomicPause();

常量索引常量

以下常量在本页所属头文件中定义,语义见公共头注释。

常量说明
XMEMORY_ACQUIRE见头文件注释
XMEMORY_ACQ_REL见头文件注释
XMEMORY_RELAXED见头文件注释
XMEMORY_RELEASE见头文件注释
XMEMORY_SEQ_CST见头文件注释
XRT_ATOMIC32_INIT见头文件注释
XRT_ATOMIC64_INIT见头文件注释
XRT_ATOMICPTR_INIT见头文件注释
XRT_ATOMIC_ALIGN见头文件注释
XRT_ATOMIC_PTR_ALIGNMENT见头文件注释