121a88fd4Skaashoek #include "types.h" 221a88fd4Skaashoek #include "defs.h" 321a88fd4Skaashoek #include "x86.h" 47837c71bSkaashoek #include "mmu.h" 54e8f237bSrtm #include "param.h" 64e8f237bSrtm #include "proc.h" 74e8f237bSrtm #include "spinlock.h" 821a88fd4Skaashoek 965bd8e13Srsc // Can't call cprintf from inside these routines, 1065bd8e13Srsc // because cprintf uses them itself. 1165bd8e13Srsc #define cprintf dont_use_cprintf 1221a88fd4Skaashoek 13b74f4b57Srsc extern int use_console_lock; 148148b6eeSrtm 1565bd8e13Srsc int 1665bd8e13Srsc getcallerpc(void *v) 1765bd8e13Srsc { 185ce9751cSrsc return ((int*)v)[-1]; 195ce9751cSrsc } 205ce9751cSrsc 2121a88fd4Skaashoek void 22679a977cSrsc acquire(struct spinlock * lock) 2321a88fd4Skaashoek { 24*0dd42537Srsc if(holding(lock)) 25*0dd42537Srsc panic("acquire"); 26*0dd42537Srsc 2765bd8e13Srsc if(cpus[cpu()].nlock++ == 0) 28b548df15Srtm cli(); 2965bd8e13Srsc while(cmpxchg(0, 1, &lock->locked) == 1) 3065bd8e13Srsc ; 3165bd8e13Srsc cpuid(0, 0, 0, 0, 0); // memory barrier 32*0dd42537Srsc lock->pc = getcallerpc(&lock); 33*0dd42537Srsc lock->cpu = cpu(); 3421a88fd4Skaashoek } 3521a88fd4Skaashoek 3621a88fd4Skaashoek void 37679a977cSrsc release(struct spinlock * lock) 3821a88fd4Skaashoek { 39*0dd42537Srsc if(!holding(lock)) 40*0dd42537Srsc panic("release"); 41*0dd42537Srsc 4265bd8e13Srsc cpuid(0, 0, 0, 0, 0); // memory barrier 4365bd8e13Srsc lock->locked = 0; 44b74f4b57Srsc if(--cpus[cpu()].nlock == 0) 45b548df15Srtm sti(); 4621a88fd4Skaashoek } 4746bbd72fSrtm 48*0dd42537Srsc int 49*0dd42537Srsc holding(struct spinlock *lock) 50*0dd42537Srsc { 51*0dd42537Srsc return lock->locked && lock->cpu == cpu(); 52*0dd42537Srsc } 53