inline bool swap_if_null(head_t **p, head_t *np) {
register head_t *old;
asm volatile(
"lock;\n\t"
"cmpxchgq %3, %2"
: "=a"(old)
: "0"(0), "m"(*p), "r"(np)
: "memory");
return old == NULL;
}
如果为 NULL *p
,此函数将“交换” 的内容。np
*p
它通过使用cmpxchgq
(Compare and Exchange, quadword [64 bits]) 指令来做到这一点,换句话说,将*p
( %2
) 处的 64 位值与0
(在参数 0 中,即rax
) 进行比较,如果该rax
值与内存匹配位置,将新值存储在np
, ( %3
) 中。最后,old
如果进行了替换,则包含内存位置中的 WAS 值,因此我们可以检查它NULL
在被替换时是否为 WAS。lock
前缀确保处理器具有对内存的独占访问权限,目前没有其他处理器可以写入该位置 。
这样做是为了避免在链表末尾插入某些内容时使用互斥锁。如果有多个线程试图插入,则需要确保在将元素添加到列表末尾时,列表末尾确实为 NULL,否则会出错(特别是列表将“掉落”物品)。该cmpxchg
指令是针对这种“如果值是这个,用这个另一个值替换它”。