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
andの内容を「交換」します。np
*p
これは、 (Compare and Exchange, quadword [64 bits]) 命令を使用して、つまり、( )cmpxchgq
の 64 ビット値を*p
(引数 0、つまり) と比較し、値がメモリと一致するかどうかによって行われます。 、( )に新しい値を格納します。最後に、置換が行われた場合にメモリ位置にあった値が含まれているため、置換されたときにそれがあったことを確認できます。プレフィックスにより、プロセッサがメモリに排他的にアクセスできるようになり、現在、他のプロセッサがこの場所に書き込むことはできません。 %2
0
rax
rax
np
%3
old
NULL
lock
これは、リンクされたリストの最後に何かを挿入するときにミューテックスを使用しないようにするために行われます。複数のスレッドが挿入しようとしている場合、要素をリストの最後に追加する時点で、リストの最後が本当に NULL であることを確認する必要があります。ドロップ」アイテム)。cmpxchg
このような「値がこの値なら、別の値に置き換える」という指示が出されます。