summaryrefslogtreecommitdiff
path: root/spinlock.c
diff options
context:
space:
mode:
authorrtm <rtm>2006-07-12 11:15:38 +0000
committerrtm <rtm>2006-07-12 11:15:38 +0000
commit8148b6ee535b85e97f3b5f3a850b70fdfbbcaf2d (patch)
treeea279d5ca141449bb8f363594c57d7e8fc142db0 /spinlock.c
parent664324745e2257289f7a61e43892ce6e8b8ed9b7 (diff)
downloadxv6-labs-8148b6ee535b85e97f3b5f3a850b70fdfbbcaf2d.tar.gz
xv6-labs-8148b6ee535b85e97f3b5f3a850b70fdfbbcaf2d.tar.bz2
xv6-labs-8148b6ee535b85e97f3b5f3a850b70fdfbbcaf2d.zip
i think my cmpxchg use was wrong in acquire
nesting cli/sti: release shouldn't always enable interrupts separate setup of lapic from starting of other cpus, so cpu() works earlier flag to disable locking in console output make locks work even when curproc==0 (still crashes in clock interrupt)
Diffstat (limited to 'spinlock.c')
-rw-r--r--spinlock.c32
1 files changed, 23 insertions, 9 deletions
diff --git a/spinlock.c b/spinlock.c
index 9f840a8..bd6bff5 100644
--- a/spinlock.c
+++ b/spinlock.c
@@ -8,6 +8,8 @@
#define DEBUG 0
+extern use_printf_lock;
+
int getcallerpc(void *v) {
return ((int*)v)[-1];
}
@@ -15,37 +17,49 @@ int getcallerpc(void *v) {
void
acquire(struct spinlock * lock)
{
- struct proc * cp = curproc[cpu()];
+ unsigned who;
+
+ if(curproc[cpu()])
+ who = (unsigned) curproc[cpu()];
+ else
+ who = cpu() + 1;
- // on a real machine there would be a memory barrier here
if(DEBUG) cprintf("cpu%d: acquiring at %x\n", cpu(), getcallerpc(&lock));
- if (cp && lock->p == cp && lock->locked){
+
+ if (lock->who == who && lock->locked){
lock->count += 1;
} else {
cli();
- while ( cmpxchg(0, 1, &lock->locked) != 1 ) { ; }
+ // if we get the lock, eax will be zero
+ // if we don't get the lock, eax will be one
+ while ( cmpxchg(0, 1, &lock->locked) == 1 ) { ; }
lock->locker_pc = getcallerpc(&lock);
lock->count = 1;
- lock->p = cp;
+ lock->who = who;
}
+
if(DEBUG) cprintf("cpu%d: acquired at %x\n", cpu(), getcallerpc(&lock));
}
void
release(struct spinlock * lock)
{
- struct proc * cp = curproc[cpu()];
+ unsigned who;
+
+ if(curproc[cpu()])
+ who = (unsigned) curproc[cpu()];
+ else
+ who = cpu() + 1;
if(DEBUG) cprintf ("cpu%d: releasing at %x\n", cpu(), getcallerpc(&lock));
- if(lock->p != cp || lock->count < 1 || lock->locked != 1)
+ if(lock->who != who || lock->count < 1 || lock->locked != 1)
panic("release");
lock->count -= 1;
if(lock->count < 1){
- lock->p = 0;
+ lock->who = 0;
cmpxchg(1, 0, &lock->locked);
sti();
- // on a real machine there would be a memory barrier here
}
}