xref: /xv6-public/spinlock.c (revision 65bd8e13)
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 
9*65bd8e13Srsc // Can't call cprintf from inside these routines,
10*65bd8e13Srsc // because cprintf uses them itself.
11*65bd8e13Srsc #define cprintf dont_use_cprintf
1221a88fd4Skaashoek 
1346bbd72fSrtm extern int use_console_lock;
148148b6eeSrtm 
15*65bd8e13Srsc int
16*65bd8e13Srsc getcallerpc(void *v)
17*65bd8e13Srsc {
185ce9751cSrsc 	return ((int*)v)[-1];
195ce9751cSrsc }
205ce9751cSrsc 
2121a88fd4Skaashoek void
2246bbd72fSrtm acquire1(struct spinlock * lock, struct proc *cp)
2321a88fd4Skaashoek {
24*65bd8e13Srsc 	if(cpus[cpu()].nlock++ == 0)
25b548df15Srtm 		cli();
26*65bd8e13Srsc 	while(cmpxchg(0, 1, &lock->locked) == 1)
27*65bd8e13Srsc 		;
28*65bd8e13Srsc 	cpuid(0, 0, 0, 0, 0);	// memory barrier
294e8f237bSrtm 	lock->locker_pc = getcallerpc(&lock);
3021a88fd4Skaashoek }
3121a88fd4Skaashoek 
3221a88fd4Skaashoek void
3346bbd72fSrtm release1(struct spinlock * lock, struct proc *cp)
3421a88fd4Skaashoek {
35*65bd8e13Srsc 	cpuid(0, 0, 0, 0, 0);	// memory barrier
36*65bd8e13Srsc 	lock->locked = 0;
37*65bd8e13Srsc 	if(--cpus[cpu()].nlock == 0)
38b548df15Srtm 		sti();
3921a88fd4Skaashoek }
4046bbd72fSrtm 
4146bbd72fSrtm void
4246bbd72fSrtm acquire(struct spinlock *lock)
4346bbd72fSrtm {
4446bbd72fSrtm 	acquire1(lock, curproc[cpu()]);
4546bbd72fSrtm }
4646bbd72fSrtm 
4746bbd72fSrtm void
4846bbd72fSrtm release(struct spinlock *lock)
4946bbd72fSrtm {
5046bbd72fSrtm 	release1(lock, curproc[cpu()]);
5121a88fd4Skaashoek }
52*65bd8e13Srsc 
53