spinlock.c源码分析
初始化lock
void
initlock(struct spinlock *lk, char *name)
{
lk->name = name;
lk->locked = 0;
lk->cpu = 0;
}
acquire获得锁,首先利用pushcli进行关中断,之后通过holding(lk)判断此锁已经被当前CPU获得,如果已经获得返回true,则会panic。如果没有获得或者被其他cpu获得,返回false,进入while(xchg(&lk->locked, 1) != 0)通过汇编指令原子的进行交换。如果锁没有被获得,则&lk->locked为0,此时xchg为0为0,成功获得锁,更改lk->cpu并且获得寄存器的值。如果锁被其他cpu获得&lk->locked为1,此时xchg为1,会进入轮询访问
void
acquire(struct spinlock *lk)
{
pushcli(); // disable interrupts to avoid deadlock.
if(holding(lk))
panic(“acquire”);
while(xchg(&lk->locked, 1) != 0)
lk->cpu = cpu;
getcallerpcs(&lk, lk->pcs);
}
只有获得锁的cpu才能够释放锁,如果不是此cpu调用指令,通过!holding(lk)产生panic。如果是,则 lk->pc