xv6/spinlock.c
rtm 8148b6ee53 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)
2006-07-12 11:15:38 +00:00

65 lines
1.2 KiB
C

#include "types.h"
#include "defs.h"
#include "x86.h"
#include "mmu.h"
#include "param.h"
#include "proc.h"
#include "spinlock.h"
#define DEBUG 0
extern use_printf_lock;
int getcallerpc(void *v) {
return ((int*)v)[-1];
}
void
acquire(struct spinlock * lock)
{
unsigned who;
if(curproc[cpu()])
who = (unsigned) curproc[cpu()];
else
who = cpu() + 1;
if(DEBUG) cprintf("cpu%d: acquiring at %x\n", cpu(), getcallerpc(&lock));
if (lock->who == who && lock->locked){
lock->count += 1;
} else {
cli();
// 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->who = who;
}
if(DEBUG) cprintf("cpu%d: acquired at %x\n", cpu(), getcallerpc(&lock));
}
void
release(struct spinlock * lock)
{
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->who != who || lock->count < 1 || lock->locked != 1)
panic("release");
lock->count -= 1;
if(lock->count < 1){
lock->who = 0;
cmpxchg(1, 0, &lock->locked);
sti();
}
}