ticket
linux kernel spinlock ticket彙編實作解讀 static __always_inline void __ticket_spin_lock(raw_spinlock_t *lock)
{
short inc = 0x0100; // next為1,owner為0
asm volatile (
LOCK_PREFIX "xaddw %w0, %1/n" // xaddw指%w0 = %1和%1 += %w0同時進行。LOCK_PREFIX讓xaddw是原子的。%w0表示第0個input (inc)的低16位。%1表示第1個input (lock->slock)。總的意思就是inc = lock->slock和++lock->slock.next同時進行。
"1:/t" // 标号
"cmpb %h0, %b0/n/t" // 比較inc的高8位(next)和低8位(owner)
"je 2f/n/t" // 如果相等則跳轉到下面的标号2,其中f代表forward。
"rep ; nop/n/t" // 相當于pause。詳見http://blog.sina.com.cn/s/blog_4bbf98c00100ysdq.html
"movb %1, %b0/n/t" // inc.owner = lock->slock.owner
/* don't need lfence here, because loads are in-order */
"jmp 1b/n" // 跳到上面的标号1。其中b代表backward。
"2:"
: "+Q" (inc), "+m" (lock->slock) // 兩個input。+表示讀寫,Q在x86中表示寄存器a、b、c或者d。
:
: "memory", "cc"); // memory表示記憶體屏障(可是這裡為什麼要記憶體屏障呢?)。cc表示修改了标志寄存器。
}