天天看點

linux kernel spinlock ticket彙編實作解讀

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表示修改了标志寄存器。
}      

繼續閱讀