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. 1132630628Srtm //#define cprintf dont_use_cprintf 1221a88fd4Skaashoek 13*5be0039cSrtm #define LOCKMAGIC 0x6673ffea 14*5be0039cSrtm 15b74f4b57Srsc extern int use_console_lock; 168148b6eeSrtm 170e84a0ecSrtm void 18*5be0039cSrtm initlock(struct spinlock *lock, char *name) 19*5be0039cSrtm { 20*5be0039cSrtm lock->magic = LOCKMAGIC; 21*5be0039cSrtm lock->name = name; 22*5be0039cSrtm lock->locked = 0; 23*5be0039cSrtm lock->cpu = 0xffffffff; 24*5be0039cSrtm } 25*5be0039cSrtm 26*5be0039cSrtm void 270e84a0ecSrtm getcallerpcs(void *v, uint pcs[]) 2865bd8e13Srsc { 290e84a0ecSrtm uint *ebp = (uint*)v - 2; 300e84a0ecSrtm int i; 310e84a0ecSrtm for(i = 0; i < 10 && ebp && ebp != (uint*)0xffffffff; ebp = (uint*)*ebp, i++){ 320e84a0ecSrtm pcs[i] = *(ebp + 1); 330e84a0ecSrtm } 340e84a0ecSrtm for( ; i < 10; i++) 350e84a0ecSrtm pcs[i] = 0; 365ce9751cSrsc } 375ce9751cSrsc 3821a88fd4Skaashoek void 39679a977cSrsc acquire(struct spinlock * lock) 4021a88fd4Skaashoek { 41*5be0039cSrtm if(lock->magic != LOCKMAGIC) 42*5be0039cSrtm panic("weird lock magic"); 430e84a0ecSrtm if(holding(lock)) 440dd42537Srsc panic("acquire"); 450dd42537Srsc 468a8be1b8Srtm if(cpus[cpu()].nlock == 0) 47b548df15Srtm cli(); 488a8be1b8Srtm cpus[cpu()].nlock++; 498a8be1b8Srtm 5065bd8e13Srsc while(cmpxchg(0, 1, &lock->locked) == 1) 5165bd8e13Srsc ; 5265bd8e13Srsc cpuid(0, 0, 0, 0, 0); // memory barrier 530e84a0ecSrtm getcallerpcs(&lock, lock->pcs); 540e84a0ecSrtm lock->cpu = cpu() + 10; 5532630628Srtm cpus[cpu()].lastacquire = lock; 5621a88fd4Skaashoek } 5721a88fd4Skaashoek 5821a88fd4Skaashoek void 59679a977cSrsc release(struct spinlock * lock) 6021a88fd4Skaashoek { 61*5be0039cSrtm if(lock->magic != LOCKMAGIC) 62*5be0039cSrtm panic("weird lock magic"); 63*5be0039cSrtm 640dd42537Srsc if(!holding(lock)) 650dd42537Srsc panic("release"); 660dd42537Srsc 6732630628Srtm cpus[cpu()].lastrelease = lock; 680e84a0ecSrtm lock->pcs[0] = 0; 690e84a0ecSrtm lock->cpu = 0xffffffff; 7065bd8e13Srsc cpuid(0, 0, 0, 0, 0); // memory barrier 7165bd8e13Srsc lock->locked = 0; 72b74f4b57Srsc if(--cpus[cpu()].nlock == 0) 73b548df15Srtm sti(); 7421a88fd4Skaashoek } 7546bbd72fSrtm 760dd42537Srsc int 770dd42537Srsc holding(struct spinlock *lock) 780dd42537Srsc { 790e84a0ecSrtm return lock->locked && lock->cpu == cpu() + 10; 800dd42537Srsc } 81