incorporate some changes to taslock from /sys/src/nix. there's further work to be done here, but implementing mcs locks seems a better idea. Reference: /n/atom/patch/applied/9tascleanup Date: Thu Jun 5 20:21:00 CES 2014 Signed-off-by: quanstro@quanstro.net --- /sys/src/9/port/qlock.c Thu Jun 5 20:20:07 2014 +++ /sys/src/9/port/qlock.c Thu Jun 5 20:20:08 2014 @@ -22,8 +22,8 @@ panic("qlock: %#p: postdawn up nil", getcallerpc(&q)); if(m->ilockdepth != 0) print("qlock: %#p: ilockdepth %d\n", getcallerpc(&q), m->ilockdepth); - if(up != nil && up->nlocks.ref) - print("qlock: %#p: nlocks %lud\n", getcallerpc(&q), up->nlocks.ref); + if(up != nil && up->nlocks) + print("qlock: %#p: nlocks %ud\n", getcallerpc(&q), up->nlocks); if(q < KADDR(4096)) print("qlock: nil qlock %#p\n", getcallerpc(&q)); --- /sys/src/9/port/portdat.h Thu Jun 5 20:20:10 2014 +++ /sys/src/9/port/portdat.h Thu Jun 5 20:20:11 2014 @@ -724,7 +724,7 @@ Mach *wired; Mach *mp; /* machine this process last ran on */ - Ref nlocks; /* number of locks held by proc */ + int nlocks; /* number of locks held by proc */ ulong delaysched; ulong priority; /* priority level */ ulong basepri; /* base priority level */ --- /sys/src/9/port/taslock.c Thu Jun 5 20:20:13 2014 +++ /sys/src/9/port/taslock.c Thu Jun 5 20:20:14 2014 @@ -12,8 +12,8 @@ long maxilockcycles; long cumlockcycles; long cumilockcycles; -ulong maxlockpc; -ulong maxilockpc; +uintptr maxlockpc; +uintptr maxilockpc; struct { @@ -22,43 +22,13 @@ ulong inglare; } lockstats; -static void -inccnt(Ref *r) -{ - _xinc(&r->ref); -} - -static int -deccnt(Ref *r) -{ - int x; - - x = _xdec(&r->ref); - if(x < 0) - panic("deccnt pc=%#p", getcallerpc(&r)); - return x; -} - -static void -dumplockmem(char *tag, Lock *l) -{ - uchar *cp; - int i; - - iprint("%s: ", tag); - cp = (uchar*)l; - for(i = 0; i < 64; i++) - iprint("%2.2ux ", cp[i]); - iprint("\n"); -} - void -lockloop(Lock *l, ulong pc) +lockloop(Lock *l, uintptr pc) { Proc *p; p = l->p; - print("lock %#p loop key %#lux pc %#lux held by pc %#lux proc %lud\n", + print("lock %#p loop key %#p pc %#p held by pc %#p proc %lud\n", l, l->key, pc, l->pc, p ? p->pid : 0); dumpaproc(up); if(p != nil) @@ -69,27 +39,26 @@ lock(Lock *l) { int i; - ulong pc; + uintptr pc; pc = getcallerpc(&l); lockstats.locks++; if(up) - inccnt(&up->nlocks); /* prevent being scheded */ + up->nlocks++; /* prevent being scheded */ if(tas(&l->key) == 0){ if(up) up->lastlock = l; l->pc = pc; l->p = up; l->isilock = 0; - l->m = MACHP(m->machno); #ifdef LOCKCYCLES l->lockcycles = -lcycles(); #endif return 0; } if(up) - deccnt(&up->nlocks); + up->nlocks--; lockstats.glare++; for(;;){ @@ -101,7 +70,7 @@ * Priority inversion, yield on a uniprocessor; on a * multiprocessor, the other processor will unlock */ - print("inversion %#p pc %#lux proc %lud held by pc %#lux proc %lud\n", + print("inversion %#p pc %#p proc %lud held by pc %#p proc %lud\n", l, pc, up ? up->pid : 0, l->pc, l->p ? l->p->pid : 0); up->edf->d = todget(nil); /* yield to process with lock */ } @@ -111,21 +80,20 @@ } } if(up) - inccnt(&up->nlocks); + up->nlocks++; if(tas(&l->key) == 0){ if(up) up->lastlock = l; l->pc = pc; l->p = up; l->isilock = 0; - l->m = MACHP(m->machno); #ifdef LOCKCYCLES l->lockcycles = -lcycles(); #endif return 1; } if(up) - deccnt(&up->nlocks); + up->nlocks--; } } @@ -133,7 +101,7 @@ ilock(Lock *l) { ulong x; - ulong pc; + uintptr pc; pc = getcallerpc(&l); if(l == nil) @@ -176,10 +144,10 @@ canlock(Lock *l) { if(up) - inccnt(&up->nlocks); + up->nlocks++; if(tas(&l->key)){ if(up) - deccnt(&up->nlocks); + up->nlocks--; return 0; } @@ -209,14 +177,14 @@ if(l->key == 0) print("unlock: not locked: pc %#p\n", getcallerpc(&l)); if(l->isilock) - print("unlock of ilock: pc %lux, held by %lux\n", getcallerpc(&l), l->pc); + print("unlock of ilock: pc %#p, held by %#p\n", getcallerpc(&l), l->pc); if(l->p != up) - print("unlock: up changed: pc %#p, acquired at pc %lux, lock p %#p, unlock up %#p\n", getcallerpc(&l), l->pc, l->p, up); + print("unlock: up changed: pc %#p, acquired at pc %#p, lock p %#p, unlock up %#p\n", getcallerpc(&l), l->pc, l->p, up); l->m = nil; l->key = 0; coherence(); - if(up && deccnt(&up->nlocks) == 0 && up->delaysched && islo()){ + if(up && --up->nlocks == 0 && up->delaysched && islo()){ /* * Call sched if the need arose while locks were held * But, don't do it from interrupt routines, hence the islo() test @@ -226,7 +194,7 @@ } #ifdef LOCKCYCLES -ulong ilockpcs[0x100] = { [0xff] = 1 }; +uintptr ilockpcs[0x100] = { [0xff] = 1 }; static int n; #endif @@ -248,9 +216,13 @@ if(l->key == 0) print("iunlock: not locked: pc %#p\n", getcallerpc(&l)); if(!l->isilock) - print("iunlock of lock: pc %#p, held by %#lux\n", getcallerpc(&l), l->pc); + print("iunlock of lock: pc %#p, held by %#p\n", getcallerpc(&l), l->pc); if(islo()) - print("iunlock while lo: pc %#p, held by %#lux\n", getcallerpc(&l), l->pc); + print("iunlock while lo: pc %#p, held by %#p\n", getcallerpc(&l), l->pc); + if(l->m != MACHP(m->machno)){ + iprint("iunlock by mach%d, locked by mach%d: pc %#p, held by %#p\n", + m->machno, l->m->machno, getcallerpc(&l), l->pc); + } sr = l->sr; l->m = nil; @@ -260,4 +232,24 @@ if(up) up->lastilock = nil; splx(sr); +} + +int +ownlock(Lock *l) +{ + return l->m == MACHP(m->machno); +} + +uintptr +lockgetpc(Lock *l) +{ + if(l != nil) + return l->pc; + return 0; +} + +void +locksetpc(Lock *l, uintptr pc) +{ + l->pc = pc; } --- /sys/src/9/port/devcons.c Thu Jun 5 20:20:16 2014 +++ /sys/src/9/port/devcons.c Thu Jun 5 20:20:18 2014 @@ -263,7 +263,7 @@ for(i=0; i<1000; i++){ if(canlock(l)) return 1; - if(l->m == MACHP(m->machno)) + if(ownlock(l)) return 0; microdelay(100); } --- /sys/src/9/port/proc.c Thu Jun 5 20:20:20 2014 +++ /sys/src/9/port/proc.c Thu Jun 5 20:20:22 2014 @@ -111,11 +111,11 @@ Proc *p; if(m->ilockdepth) - panic("cpu%d: ilockdepth %d, last lock %#p at %#p, sched called from %#p", + panic("mach%d: ilockdepth %d, last lock %#p at %#p, sched called from %#p", m->machno, m->ilockdepth, - up? up->lastilock: nil, - (up && up->lastilock)? up->lastilock->pc: 0, + up != nil? up->lastilock: nil, + (up != nil && up->lastilock != nil)? lockgetpc(up->lastilock): (uintptr)0, getcallerpc(&p+2)); if(up){ /* @@ -132,7 +132,7 @@ * in the middle of taslock when a process holds a lock * but Lock.p has not yet been initialized. */ - if(up->nlocks.ref) + if(up->nlocks) if(up->state != Moribund) if(up->delaysched < 20 || palloc.avail[PGSHIFT].Lock.p == up @@ -598,7 +598,7 @@ procalloc.free = p->qnext; unlock(&procalloc); - while(p->mach != nil || p->nlocks.ref != 0) + while(p->mach != nil || p->nlocks != 0) {} p->state = Scheding; @@ -630,7 +630,7 @@ p->syserrstr = p->errbuf1; p->errbuf0[0] = '\0'; p->errbuf1[0] = '\0'; - p->nlocks.ref = 0; + p->nlocks = 0; p->delaysched = 0; p->trace = 0; kstrdup(&p->user, "*nouser"); @@ -743,9 +743,9 @@ s = splhi(); - if(up->nlocks.ref) - print("process %lud sleeps with %lud locks held, last lock %#p locked at pc %#lux, sleep called from %#p\n", - up->pid, up->nlocks.ref, up->lastlock, up->lastlock->pc, getcallerpc(&r)); + if(up->nlocks) + print("process %lud sleeps with %ud locks held, last lock %#p locked at pc %#p, sleep called from %#p\n", + up->pid, up->nlocks, up->lastlock, lockgetpc(up->lastlock), getcallerpc(&r)); lock(r); lock(&up->rlock); if(r->p){ @@ -1256,9 +1256,9 @@ s = p->psstate; if(s == 0) s = statename[p->state]; - print("%3lud:%10s pc %8lux dbgpc %8lux %8s (%s) ut %ld st %ld bss %lux qpc %lux nl %lud nd %lud lpc %lux pri %lud\n", + print("%3lud:%10s pc %#p dbgpc %#p %8s (%s) ut %ld st %ld bss %lux qpc %#p nl %ud nd %lud lpc %#p pri %lud\n", p->pid, p->text, p->pc, dbgpc(p), s, statename[p->state], - p->time[0], p->time[1], bss, p->qpc, p->nlocks.ref, p->delaysched, p->lastlock ? p->lastlock->pc : 0, p->priority); + p->time[0], p->time[1], bss, p->qpc, p->nlocks, p->delaysched, lockgetpc(p->lastlock), p->priority); } void --- /sys/src/9/port/syscallfmt.c Thu Jun 5 20:20:24 2014 +++ /sys/src/9/port/syscallfmt.c Thu Jun 5 20:20:25 2014 @@ -71,7 +71,7 @@ fmtprint(&fmt, "%s ", sysctab[syscallno]? sysctab[syscallno]: "huh?"); - fmtprint(&fmt, "%ulx ", pc); + fmtprint(&fmt, "%p ", pc); if(up->syscalltrace != nil) free(up->syscalltrace); --- /sys/src/9/port/devroot.c Thu Jun 5 20:20:26 2014 +++ /sys/src/9/port/devroot.c Thu Jun 5 20:20:27 2014 @@ -77,7 +77,7 @@ * add a root file */ void -addbootfile(char *name, uchar *contents, ulong len) +addbootfile(char *name, uchar *contents, usize len) { addlist(&bootlist, name, contents, len, 0555); } @@ -220,13 +220,6 @@ return 0; if(offset+n > d->length) n = d->length - offset; -#ifdef asdf -print("[%d] kaddr %.8ulx base %.8ulx offset %ld (%.8ulx), n %d %.8ulx %.8ulx %.8ulx\n", - t, buf, data, offset, offset, n, - ((ulong*)(data+offset))[0], - ((ulong*)(data+offset))[1], - ((ulong*)(data+offset))[2]); -#endif asdf memmove(buf, data+offset, n); return n; }