split qlock out from lock, as it does not depend on lock's implementation. remove lapicinitaps. this code was wrong. Reference: /n/atom/patch/applied2013/fslockorg Date: Sat Sep 14 20:42:12 CES 2013 Signed-off-by: quanstro@quanstro.net --- /sys/src/fs/amd64/lapic.c Sat Sep 14 20:39:55 2013 +++ /sys/src/fs/amd64/lapic.c Sat Sep 14 20:39:56 2013 @@ -401,16 +401,6 @@ } void -lapicinitaps(void) -{ - lapicrput(Ichi, 0); - lapicrput(Iclo, DSallexc|TMlevel|Lassert|MTir); - microdelay(200); - lapicrput(Iclo, DSallexc|TMlevel|MTir); - delay(10); -} - -void lapicipi(int lapicno) { lapicrput(Ichi, lapicno<<24); --- /sys/src/fs/amd64/l64v.s Sat Sep 14 20:39:59 2013 +++ /sys/src/fs/amd64/l64v.s Sat Sep 14 20:40:00 2013 @@ -334,6 +334,12 @@ DECL AX RET +TEXT xaddb(SB), 1, $-4 + XORL AX, AX + INCL AX + LOCK; XADDB AX, (BP) + RET + /* * Label consists of a stack pointer and a programme counter */ --- /sys/src/fs/amd64/fns.h Sat Sep 14 20:40:02 2013 +++ /sys/src/fs/amd64/fns.h Sat Sep 14 20:40:03 2013 @@ -5,6 +5,9 @@ int ainc(int*); void apmmuinit(void); int archmmu(void); +#define BIOSSEG(a) KADDR(((uint)(a))<<4) +int cas32(void*, u32int, u32int); +int cas64(void*, u64int, u64int); void cgaputc(int); void cgaputs(char*, int); void cmd_e820(int, char**); @@ -40,6 +43,7 @@ int kbdgetc(void); void kbdinit(void); int kbdintr0(void); +void lfence(void); #define machcolor(m) -1 void mfence(void); void microdelay(int); @@ -87,7 +91,7 @@ void wave(int); void waveprint(char*, ...); void wrmsr(int, vlong); -#define BIOSSEG(a) KADDR(((uint)(a))<<4) +int xaddb(void *addr); #pragma varargck argpos waveprint 1 --- /sys/src/fs/amd64/lock.c Sat Sep 14 20:40:06 2013 +++ /sys/src/fs/amd64/lock.c Sat Sep 14 20:40:07 2013 @@ -1,4 +1,4 @@ - #include "all.h" +#include "all.h" #define deccnt(x) if(x) adec((int*)&x->nlock) #define inccnt(x) if(x) ainc((int*)&x->nlock) @@ -156,198 +156,4 @@ // if(u) // u->lastilock = 0; splx(sr); -} - -void -qlock(QLock *q) -{ - User *p; - int i; - - lock(q); - if(!q->locked){ - q->locked = 1; - unlock(q); - goto out; - } - if(u) { - for(i=0; ihas.q[i] == q) { - print("circular qlock by %d at %#p (other %#p, %#p\n", - u->pid, getcallerpc(&q), u->has.pc[i], q->pc); - dumpstack(u); - break; - } - } - p = q->tail; - if(p == 0) - q->head = u; - else - p->qnext = u; - q->tail = u; - u->qnext = 0; - u->state = Queueing; - u->has.want = q; - unlock(q); - sched(); - u->has.want = 0; - -out: - if(u) { - for(i=0; ihas.q[i] == 0) { - u->has.q[i] = q; - u->has.pc[i] = getcallerpc(&q); - return; - } - print("NHAS(%d) too small\n", NHAS); - } -} - -int -canqlock(QLock *q) -{ - int i; - - lock(q); - if(q->locked){ - unlock(q); - return 0; - } - q->locked = 1; - unlock(q); - - if(u){ - for(i=0; ihas.q[i] == 0) { - u->has.q[i] = q; - u->has.pc[i] = getcallerpc(&q); - return 1; - } - print("NHAS(%d) too small\n", NHAS); - } - return 1; -} - -void -qunlock(QLock *q) -{ - User *p; - int i; - - lock(q); - p = q->head; - if(p) { - q->head = p->qnext; - if(q->head == 0) - q->tail = 0; - unlock(q); - ready(p); - } else { - q->locked = 0; - unlock(q); - } - - if(u){ - for(i=0; ihas.q[i] == q) { - u->has.q[i] = 0; - return; - } - panic("qunlock: not there %#p, called from %#p\n", - q, getcallerpc(&q)); - } -} - -/* - * readers/writers lock - * allows 1 writer or many readers - */ -void -rlock(RWlock *l) -{ - QLock *q; - - qlock(&l->wr); /* wait here for writers and exclusion */ - - q = &l->rd; /* first reader in, qlock(&l->rd) */ - lock(q); - q->locked = 1; - l->nread++; - unlock(q); - - qunlock(&l->wr); - - if(u){ - int i; - int found; - - found = 0; - for(i=0; ihas.q[i] == q){ - print("circular rlock by %d at %#p (other %#p)\n", - u->pid, getcallerpc(&l), u->has.pc[i]); - dumpstack(u); - } - if(!found && u->has.q[i] == 0) { - u->has.q[i] = q; - u->has.pc[i] = getcallerpc(&l); - found = 1; - } - } - if(!found) - print("NHAS(%d) too small\n", NHAS); - } -} - -void -runlock(RWlock *l) -{ - QLock *q; - User *p; - int n; - - q = &l->rd; - lock(q); - n = l->nread - 1; - l->nread = n; - if(n == 0) { /* last reader out, qunlock(&l->rd) */ - p = q->head; - if(p) { - q->head = p->qnext; - if(q->head == 0) - q->tail = 0; - unlock(q); - ready(p); - goto accounting; - } - q->locked = 0; - } - unlock(q); - -accounting: - if(u){ - int i; - for(i=0; ihas.q[i] == q) { - u->has.q[i] = 0; - return; - } - panic("runlock: not there %#p, called from %#p\n", - q, getcallerpc(&l)); - } -} - -void -wlock(RWlock *l) -{ - qlock(&l->wr); /* wait here for writers and exclusion */ - qlock(&l->rd); /* wait here for last reader */ -} - -void -wunlock(RWlock *l) -{ - qunlock(&l->rd); - qunlock(&l->wr); } --- /sys/src/fs/amd64/qlock.c Thu Jan 1 00:00:00 1970 +++ /sys/src/fs/amd64/qlock.c Sat Sep 14 20:40:08 2013 @@ -0,0 +1,195 @@ +#include "all.h" + +void +qlock(QLock *q) +{ + User *p; + int i; + + lock(q); + if(!q->locked){ + q->locked = 1; + unlock(q); + goto out; + } + if(u) { + for(i=0; ihas.q[i] == q) { + print("circular qlock by %d at %#p (other %#p, %#p\n", + u->pid, getcallerpc(&q), u->has.pc[i], q->pc); + dumpstack(u); + break; + } + } + p = q->tail; + if(p == 0) + q->head = u; + else + p->qnext = u; + q->tail = u; + u->qnext = 0; + u->state = Queueing; + u->has.want = q; + unlock(q); + sched(); + u->has.want = 0; + +out: + if(u) { + for(i=0; ihas.q[i] == 0) { + u->has.q[i] = q; + u->has.pc[i] = getcallerpc(&q); + return; + } + print("NHAS(%d) too small\n", NHAS); + } +} + +int +canqlock(QLock *q) +{ + int i; + + lock(q); + if(q->locked){ + unlock(q); + return 0; + } + q->locked = 1; + unlock(q); + + if(u){ + for(i=0; ihas.q[i] == 0) { + u->has.q[i] = q; + u->has.pc[i] = getcallerpc(&q); + return 1; + } + print("NHAS(%d) too small\n", NHAS); + } + return 1; +} + +void +qunlock(QLock *q) +{ + User *p; + int i; + + lock(q); + p = q->head; + if(p) { + q->head = p->qnext; + if(q->head == 0) + q->tail = 0; + unlock(q); + ready(p); + } else { + q->locked = 0; + unlock(q); + } + + if(u){ + for(i=0; ihas.q[i] == q) { + u->has.q[i] = 0; + return; + } + panic("qunlock: not there %#p, called from %#p\n", + q, getcallerpc(&q)); + } +} + +/* + * readers/writers lock + * allows 1 writer or many readers + */ +void +rlock(RWlock *l) +{ + QLock *q; + + qlock(&l->wr); /* wait here for writers and exclusion */ + + q = &l->rd; /* first reader in, qlock(&l->rd) */ + lock(q); + q->locked = 1; + l->nread++; + unlock(q); + + qunlock(&l->wr); + + if(u){ + int i; + int found; + + found = 0; + for(i=0; ihas.q[i] == q){ + print("circular rlock by %d at %#p (other %#p)\n", + u->pid, getcallerpc(&l), u->has.pc[i]); + dumpstack(u); + } + if(!found && u->has.q[i] == 0) { + u->has.q[i] = q; + u->has.pc[i] = getcallerpc(&l); + found = 1; + } + } + if(!found) + print("NHAS(%d) too small\n", NHAS); + } +} + +void +runlock(RWlock *l) +{ + QLock *q; + User *p; + int n; + + q = &l->rd; + lock(q); + n = l->nread - 1; + l->nread = n; + if(n == 0) { /* last reader out, qunlock(&l->rd) */ + p = q->head; + if(p) { + q->head = p->qnext; + if(q->head == 0) + q->tail = 0; + unlock(q); + ready(p); + goto accounting; + } + q->locked = 0; + } + unlock(q); + +accounting: + if(u){ + int i; + for(i=0; ihas.q[i] == q) { + u->has.q[i] = 0; + return; + } + panic("runlock: not there %#p, called from %#p\n", + q, getcallerpc(&l)); + } +} + +void +wlock(RWlock *l) +{ + qlock(&l->wr); /* wait here for writers and exclusion */ + qlock(&l->rd); /* wait here for last reader */ +} + +void +wunlock(RWlock *l) +{ + qunlock(&l->rd); + qunlock(&l->wr); +} --- /sys/src/fs/ivey/mkfile Sat Sep 14 20:40:10 2013 +++ /sys/src/fs/ivey/mkfile Sat Sep 14 20:40:11 2013 @@ -71,12 +71,14 @@ ioapic.$O\ lapic.$O\ lock.$O\ +# tiklock.$O\ malloc.$O\ mmu.$O\ # mp.$O\ msi.$O\ nvr.$O\ pci.$O\ + qlock.$O\ sipi.$O\ squid.$O\ toy.$O\