_InterlockedCompareExchange128 内部函数
Microsoft 专用
执行 128 位联锁比较和交换。
语法
unsigned char _InterlockedCompareExchange128(
__int64 volatile * Destination,
__int64 ExchangeHigh,
__int64 ExchangeLow,
__int64 * ComparandResult
);
unsigned char _InterlockedCompareExchange128_acq(
__int64 volatile * Destination,
__int64 ExchangeHigh,
__int64 ExchangeLow,
__int64 * ComparandResult
);
unsigned char _InterlockedCompareExchange128_nf(
__int64 volatile * Destination,
__int64 ExchangeHigh,
__int64 ExchangeLow,
__int64 * ComparandResult
);
unsigned char _InterlockedCompareExchange128_np(
__int64 volatile * Destination,
__int64 ExchangeHigh,
__int64 ExchangeLow,
__int64 * ComparandResult
);
unsigned char _InterlockedCompareExchange128_rel(
__int64 volatile * Destination,
__int64 ExchangeHigh,
__int64 ExchangeLow,
__int64 * ComparandResult
);
参数
目标
[in,out] 指向目标的指针,它是两个 64 位整数的数组,被视为 128 位字段。 目标数据必须对齐 16 字节,以避免出现常规保护错误。
ExchangeHigh
[in] 可与目标高部分交换的 64 位整数。
ExchangeLow
[in] 可与目标低部分交换的 64 位整数。
ComparandResult
[in,out] 指向两个 64 位整数(被视为 128 位字段)的数组的指针,用于跟目标比较。 在输出中,此数组被目标的原始值覆盖。
返回值
如果 128 位比较数与目标的原始值相等,则为 1。 ExchangeHigh
和 ExchangeLow
覆盖 128 位目标。
如果比较数不等于目标的原始值,则为 0。 目标的值不变,比较数的值将被目标的值覆盖。
要求
Intrinsic | 体系结构 |
---|---|
_InterlockedCompareExchange128 |
x64、ARM64 |
.- . | ARM64 |
_InterlockedCompareExchange128_np |
x64 |
头文件<intrin.h>
备注
_InterlockedCompareExchange128
内部函数生成前缀为 lock
的 cmpxchg16b
指令,以执行 128 位锁定比较和交换。 AMD 64 位硬件的早期版本不支持此指令。 若要检查 cmpxchg16b
指令的硬件支持,请使用 InfoType=0x00000001 (standard function 1)
调用 __cpuid
内部函数。 如果支持指令,则 13 位 CPUInfo[2]
(ECX) 为 1。
注意
值 ComparandResult
始终被覆盖。 指令 lock
后,此内部函数会立即将初始值 Destination
复制到 ComparandResult
。 因此,ComparandResult
和 Destination
应指向单独的内存位置以避免意外行为。
尽管 _InterlockedCompareExchange128
可用于低级线程同步,但如果可以使用较小的同步函数(比如另一个 _InterlockedCompareExchange
内部函数),则无需同步超过 128 位。 如果要在内存中对 128 位值进行原子访问,请使用 _InterlockedCompareExchange128
。
如果在不支持 cmpxchg16b
指令的硬件上运行使用内部函数的代码,则结果是不可预测的。
在 ARM 平台上,可以使用带 _acq
和 _rel
后缀的内部函数获取和发布语义,例如在临界区的起始位置。 带 _nf
(“无围墙”)后缀的 ARM 内部函数不能充当内存屏障。
带 _np
(“无预取”)后缀的函数可以阻止编译器插入可能的预取操作。
此例程仅可用作内部函数。
示例
此示例使用 _InterlockedCompareExchange128
将两个 64 位整数数组的高字替换为其高字和低字的总和,并递增低字。 对 BigInt.Int
数组的访问是原子访问,但此示例使用单线程,并忽略锁定以简化操作。
// cmpxchg16b.c
// processor: x64
// compile with: /EHsc /O2
#include <stdio.h>
#include <intrin.h>
typedef struct _LARGE_INTEGER_128 {
__int64 Int[2];
} LARGE_INTEGER_128, *PLARGE_INTEGER_128;
volatile LARGE_INTEGER_128 BigInt;
// This AtomicOp() function atomically performs:
// BigInt.Int[1] += BigInt.Int[0]
// BigInt.Int[0] += 1
void AtomicOp ()
{
LARGE_INTEGER_128 Comparand;
Comparand.Int[0] = BigInt.Int[0];
Comparand.Int[1] = BigInt.Int[1];
do {
; // nothing
} while (_InterlockedCompareExchange128(BigInt.Int,
Comparand.Int[0] + Comparand.Int[1],
Comparand.Int[0] + 1,
Comparand.Int) == 0);
}
// In a real application, several threads contend for the value
// of BigInt.
// Here we focus on the compare and exchange for simplicity.
int main(void)
{
BigInt.Int[1] = 23;
BigInt.Int[0] = 11;
AtomicOp();
printf("BigInt.Int[1] = %d, BigInt.Int[0] = %d\n",
BigInt.Int[1],BigInt.Int[0]);
}
BigInt.Int[1] = 34, BigInt.Int[0] = 12
结束 Microsoft 专用