121a88fd4Skaashoek #include "types.h" 221a88fd4Skaashoek #include "defs.h" 321a88fd4Skaashoek #include "x86.h" 47837c71bSkaashoek #include "mmu.h" 5*4e8f237bSrtm #include "param.h" 6*4e8f237bSrtm #include "proc.h" 7*4e8f237bSrtm #include "spinlock.h" 821a88fd4Skaashoek 95ce9751cSrsc #define DEBUG 0 1021a88fd4Skaashoek 115ce9751cSrsc int getcallerpc(void *v) { 125ce9751cSrsc return ((int*)v)[-1]; 135ce9751cSrsc } 145ce9751cSrsc 1521a88fd4Skaashoek void 16*4e8f237bSrtm acquire(struct spinlock * lock) 1721a88fd4Skaashoek { 18*4e8f237bSrtm struct proc * cp = curproc[cpu()]; 1921a88fd4Skaashoek 205ce9751cSrsc // on a real machine there would be a memory barrier here 21*4e8f237bSrtm if(DEBUG) cprintf("cpu%d: acquiring at %x\n", cpu(), getcallerpc(&lock)); 22*4e8f237bSrtm if (cp && lock->p == cp && lock->locked){ 23*4e8f237bSrtm lock->count += 1; 24*4e8f237bSrtm } else { 25b548df15Srtm cli(); 26*4e8f237bSrtm while ( cmpxchg(0, 1, &lock->locked) != 1 ) { ; } 27*4e8f237bSrtm lock->locker_pc = getcallerpc(&lock); 28*4e8f237bSrtm lock->count = 1; 29*4e8f237bSrtm lock->p = cp; 30*4e8f237bSrtm } 31*4e8f237bSrtm if(DEBUG) cprintf("cpu%d: acquired at %x\n", cpu(), getcallerpc(&lock)); 3221a88fd4Skaashoek } 3321a88fd4Skaashoek 3421a88fd4Skaashoek void 35*4e8f237bSrtm release(struct spinlock * lock) 3621a88fd4Skaashoek { 37*4e8f237bSrtm struct proc * cp = curproc[cpu()]; 38*4e8f237bSrtm 39*4e8f237bSrtm if(DEBUG) cprintf ("cpu%d: releasing at %x\n", cpu(), getcallerpc(&lock)); 40*4e8f237bSrtm 41*4e8f237bSrtm if(lock->p != cp || lock->count < 1 || lock->locked != 1) 42*4e8f237bSrtm panic("release"); 43*4e8f237bSrtm 44*4e8f237bSrtm lock->count -= 1; 45*4e8f237bSrtm if(lock->count < 1){ 46*4e8f237bSrtm lock->p = 0; 47*4e8f237bSrtm cmpxchg(1, 0, &lock->locked); 48b548df15Srtm sti(); 49*4e8f237bSrtm // on a real machine there would be a memory barrier here 5021a88fd4Skaashoek } 5121a88fd4Skaashoek } 52