4.3 qspinlock加锁流程
如前所述,qspinlock加锁分三个阶段:
- 在qspinlock结构上竞争。
- 在mcs_spinlock队列上排队。
- 获取锁。
“在qspinlock结构上竞争”时,又分以下几种情况:
- 情况一:锁当前是unlock状态,直接加锁。
- 情况二:临时状态,此时(tail, pending, lock)的值为(0, 1, 0)。
- 情况三:tail != 0 || pending != 0,进入mcs_spinlock队列排队。
- 情况四:设置pending位成功,在qspinlock的locked值上自旋。
- 情况五:竞争pending位失败,进入mcs_spinlock队列排队。
“在mcs_spinlock队列上排队”时,也分两种情况:
- 排队情况一:已经排到队列头,在qspinlock的pending | locked上自旋。等待(tail, pending, lock)从(*, x, y)变为(*, 0, 0)。
- 排队情况二:在mcs_spinlock队列中,在CPU的per-cpu MCS spinlock的locked上自旋,直到到达队列头部。
当锁的持有者释放锁之后,mcs_spinlock队列头的CPU可以进入“获取锁”阶段,也分两种情况:
- 获取锁情况一:没有其他排队的竞争者,加锁并将qspinlock的tail清空。
- 获取锁情况二:有其他排队的竞争者,加锁并让mcs_spinlock队列中的下一个CPU成为队列头。
qspinlock加锁流程如下图所示:

下面的描述中将省略(tail, pending, lock),出现形如(x, y, z)均表示qspinlock结构中的tail == x && pending == y && lock == z。