Rejigger spinlock.c

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