我在 i686 架构中使用 cmpxchg(比较和交换)进行 32 位比较和交换,如下所示。
(编者注:最初的 32 位示例有问题,但问题不在于它。我相信这个版本是安全的,并且作为奖励,它也可以为 x86-64 正确编译。 另请注意,内联 asm 不是为此需要或推荐;或在 i486 和 x86-64 上或上__atomic_compare_exchange_n
的较旧__sync_bool_compare_and_swap
工作int32_t
int64_t
。但这个问题是关于使用内联汇编来完成的,以防万一。)
// note that this function doesn't return the updated oldVal
static int CAS(int *ptr, int oldVal, int newVal)
{
unsigned char ret;
__asm__ __volatile__ (
" lock\n"
" cmpxchgl %[newval], %[mem]\n"
" sete %0\n"
: "=q" (ret), [mem] "+m" (*ptr), "+a" (oldVal)
: [newval]"r" (newVal)
: "memory"); // barrier for compiler reordering around this
return ret; // ZF result, 1 on success else 0
}
64 位比较和交换的 x86_64 架构的等效项是什么
static int CAS(long *ptr, long oldVal, long newVal)
{
unsigned char ret;
// ?
return ret;
}