Rejigger spinlock.c

上级 b0ecf098
......@@ -8,6 +8,58 @@
#include "spinlock.h"
#include "mtrace.h"
static inline void
locking(struct spinlock *lk)
{
#if SPINLOCK_DEBUG
if(holding(lk)) {
cprintf("%p\n", __builtin_return_address(0));
panic("acquire");
}
#endif
mtlock(lk);
}
static inline void
locked(struct spinlock *lk)
{
mtacquired(lk);
#if SPINLOCK_DEBUG
// Record info about lock acquisition for debugging.
lk->cpu = mycpu();
getcallerpcs(&lk, lk->pcs, NELEM(lk->pcs));
#endif
}
static inline void
releasing(struct spinlock *lk)
{
#if SPINLOCK_DEBUG
if(!holding(lk)) {
cprintf("lock: %s\n", lk->name);
panic("release");
}
#endif
mtunlock(lk);
#if SPINLOCK_DEBUG
lk->pcs[0] = 0;
lk->cpu = 0;
#endif
}
// Check whether this cpu is holding the lock.
#if SPINLOCK_DEBUG
int
holding(struct spinlock *lock)
{
return lock->locked && lock->cpu == mycpu();
}
#endif
void
initlock(struct spinlock *lk, const char *name)
{
......@@ -21,27 +73,13 @@ initlock(struct spinlock *lk, const char *name)
int
tryacquire(struct spinlock *lk)
{
pushcli(); // disable interrupts to avoid deadlock.
#if SPINLOCK_DEBUG
if(holding(lk)) {
cprintf("%p\n", __builtin_return_address(0));
panic("acquire");
}
#endif
mtlock(lk);
pushcli();
locking(lk);
if (xchg32(&lk->locked, 1) != 0) {
popcli();
return 0;
}
mtacquired(lk);
#if SPINLOCK_DEBUG
// Record info about lock acquisition for debugging.
lk->cpu = mycpu();
getcallerpcs(&lk, lk->pcs, NELEM(lk->pcs));
#endif
locked(lk);
return 1;
}
......@@ -52,47 +90,21 @@ tryacquire(struct spinlock *lk)
void
acquire(struct spinlock *lk)
{
pushcli(); // disable interrupts to avoid deadlock.
#if SPINLOCK_DEBUG
if(holding(lk)) {
cprintf("%p\n", __builtin_return_address(0));
panic("acquire");
}
#endif
mtlock(lk);
pushcli();
locking(lk);
// The xchg is atomic.
// It also serializes, so that reads after acquire are not
// reordered before it.
while(xchg32(&lk->locked, 1) != 0)
;
mtacquired(lk);
#if SPINLOCK_DEBUG
// Record info about lock acquisition for debugging.
lk->cpu = mycpu();
getcallerpcs(&lk, lk->pcs, NELEM(lk->pcs));
#endif
locked(lk);
}
// Release the lock.
void
release(struct spinlock *lk)
{
#if SPINLOCK_DEBUG
if(!holding(lk)) {
cprintf("lock: %s\n", lk->name);
panic("release");
}
#endif
mtunlock(lk);
#if SPINLOCK_DEBUG
lk->pcs[0] = 0;
lk->cpu = 0;
#endif
releasing(lk);
// The xchg serializes, so that reads before release are
// not reordered after it. The 1996 PentiumPro manual (Volume 3,
......@@ -107,12 +119,3 @@ release(struct spinlock *lk)
popcli();
}
// Check whether this cpu is holding the lock.
#if SPINLOCK_DEBUG
int
holding(struct spinlock *lock)
{
return lock->locked && lock->cpu == mycpu();
}
#endif
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论