diff options
author | rtm <rtm> | 2006-07-12 11:15:38 +0000 |
---|---|---|
committer | rtm <rtm> | 2006-07-12 11:15:38 +0000 |
commit | 8148b6ee535b85e97f3b5f3a850b70fdfbbcaf2d (patch) | |
tree | ea279d5ca141449bb8f363594c57d7e8fc142db0 /spinlock.c | |
parent | 664324745e2257289f7a61e43892ce6e8b8ed9b7 (diff) | |
download | xv6-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.c | 32 |
1 files changed, 23 insertions, 9 deletions
@@ -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 } } |