xref: /xv6-public/spinlock.c (revision 0e84a0ec)
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 
13b74f4b57Srsc extern int use_console_lock;
148148b6eeSrtm 
15*0e84a0ecSrtm void
16*0e84a0ecSrtm getcallerpcs(void *v, uint pcs[])
1765bd8e13Srsc {
18*0e84a0ecSrtm   uint *ebp = (uint*)v - 2;
19*0e84a0ecSrtm   int i;
20*0e84a0ecSrtm   for(i = 0; i < 10 && ebp && ebp != (uint*)0xffffffff; ebp = (uint*)*ebp, i++){
21*0e84a0ecSrtm     pcs[i] = *(ebp + 1);
22*0e84a0ecSrtm   }
23*0e84a0ecSrtm   for( ; i < 10; i++)
24*0e84a0ecSrtm     pcs[i] = 0;
255ce9751cSrsc }
265ce9751cSrsc 
2721a88fd4Skaashoek void
28679a977cSrsc acquire(struct spinlock * lock)
2921a88fd4Skaashoek {
30*0e84a0ecSrtm   if(holding(lock))
310dd42537Srsc     panic("acquire");
320dd42537Srsc 
3365bd8e13Srsc 	if(cpus[cpu()].nlock++ == 0)
34b548df15Srtm 		cli();
3565bd8e13Srsc 	while(cmpxchg(0, 1, &lock->locked) == 1)
3665bd8e13Srsc 		;
3765bd8e13Srsc 	cpuid(0, 0, 0, 0, 0);	// memory barrier
38*0e84a0ecSrtm 	getcallerpcs(&lock, lock->pcs);
39*0e84a0ecSrtm 	lock->cpu = cpu() + 10;
4032630628Srtm         cpus[cpu()].lastacquire = lock;
4121a88fd4Skaashoek }
4221a88fd4Skaashoek 
4321a88fd4Skaashoek void
44679a977cSrsc release(struct spinlock * lock)
4521a88fd4Skaashoek {
460dd42537Srsc 	if(!holding(lock))
470dd42537Srsc 		panic("release");
480dd42537Srsc 
4932630628Srtm         cpus[cpu()].lastrelease = lock;
50*0e84a0ecSrtm         lock->pcs[0] = 0;
51*0e84a0ecSrtm         lock->cpu = 0xffffffff;
5265bd8e13Srsc 	cpuid(0, 0, 0, 0, 0);	// memory barrier
5365bd8e13Srsc 	lock->locked = 0;
54b74f4b57Srsc 	if(--cpus[cpu()].nlock == 0)
55b548df15Srtm 		sti();
5621a88fd4Skaashoek }
5746bbd72fSrtm 
580dd42537Srsc int
590dd42537Srsc holding(struct spinlock *lock)
600dd42537Srsc {
61*0e84a0ecSrtm 	return lock->locked && lock->cpu == cpu() + 10;
620dd42537Srsc }
63