From 91614f582fb1504ae3be2d57c079f24b60d71613 Mon Sep 17 00:00:00 2001 From: cinap_lenrek Date: Thu, 5 Jun 2014 21:54:32 +0200 Subject: [PATCH] kernel: dont use atomic increment for Proc.nlocks, maintain Lock.m for lock(), use uintptr intstead of long for pc values change Proc.nlocks from Ref to int and just use normal increment and decrelemt as done in erik quanstros 9atom. It is not clear why we used atomic increment in the fist place as even if we get preempted by interrupt and scheduled before we write back the incremented value, it shouldnt be a problem and we'll just continue where we left off as our process is the only one that can write to it. Yoann Padioleau found that the Mach pointer Lock.m wasnt maintained consistently for lock() vs canlock() and ilock(). Fixed. Use uintptr instead of ulong for maxlockpc, maxilockpc and ilockpc debug variables. --- sys/src/9/port/allocb.c | 2 +- sys/src/9/port/fault.c | 6 +++--- sys/src/9/port/portdat.h | 2 +- sys/src/9/port/proc.c | 14 +++++++------- sys/src/9/port/qlock.c | 8 ++++---- sys/src/9/port/taslock.c | 41 +++++++++++++--------------------------- 6 files changed, 29 insertions(+), 44 deletions(-) diff --git a/sys/src/9/port/allocb.c b/sys/src/9/port/allocb.c index 60d538325..3466840f2 100644 --- a/sys/src/9/port/allocb.c +++ b/sys/src/9/port/allocb.c @@ -65,7 +65,7 @@ allocb(int size) if(up == nil) panic("allocb without up: %#p", getcallerpc(&size)); while((b = _allocb(size)) == nil){ - if(up->nlocks.ref || m->ilockdepth || !islo()){ + if(up->nlocks || m->ilockdepth || !islo()){ xsummary(); mallocsummary(); panic("allocb: no memory for %d bytes", size); diff --git a/sys/src/9/port/fault.c b/sys/src/9/port/fault.c index 3d4530401..fa836b641 100644 --- a/sys/src/9/port/fault.c +++ b/sys/src/9/port/fault.c @@ -14,10 +14,10 @@ fault(uintptr addr, int read) if(up == nil) panic("fault: nil up"); - if(up->nlocks.ref){ + if(up->nlocks){ Lock *l = up->lastlock; - print("fault: nlocks %ld, proc %lud %s, addr %#p, lock %#p, lpc %#p\n", - up->nlocks.ref, up->pid, up->text, addr, l, l ? l->pc : 0); + print("fault: nlocks %d, proc %lud %s, addr %#p, lock %#p, lpc %#p\n", + up->nlocks, up->pid, up->text, addr, l, l ? l->pc : 0); } pnd = up->notepending; diff --git a/sys/src/9/port/portdat.h b/sys/src/9/port/portdat.h index ee92c43c3..a3eecabc3 100644 --- a/sys/src/9/port/portdat.h +++ b/sys/src/9/port/portdat.h @@ -718,7 +718,7 @@ struct Proc 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 */ diff --git a/sys/src/9/port/proc.c b/sys/src/9/port/proc.c index 0d96ed5c3..b01ff6129 100644 --- a/sys/src/9/port/proc.c +++ b/sys/src/9/port/proc.c @@ -137,7 +137,7 @@ sched(void) * 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.Lock.p == up @@ -632,7 +632,7 @@ newproc(void) 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"); @@ -742,9 +742,9 @@ sleep(Rendez *r, int (*f)(void*), void *arg) s = splhi(); - if(up->nlocks.ref) - print("process %lud sleeps with %lud locks held, last lock %#p locked at pc %#p, 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 %d locks held, last lock %#p locked at pc %#p, sleep called from %#p\n", + up->pid, up->nlocks, up->lastlock, up->lastlock->pc, getcallerpc(&r)); lock(r); lock(&up->rlock); if(r->p){ @@ -1289,9 +1289,9 @@ dumpaproc(Proc *p) s = p->psstate; if(s == 0) s = statename[p->state]; - print("%3lud:%10s pc %#p dbgpc %#p %8s (%s) ut %ld st %ld bss %lux qpc %#p nl %lud nd %lud lpc %#p pri %lud\n", + print("%3lud:%10s pc %#p dbgpc %#p %8s (%s) ut %ld st %ld bss %lux qpc %#p nl %d 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->time[0], p->time[1], bss, p->qpc, p->nlocks, p->delaysched, p->lastlock ? p->lastlock->pc : 0, p->priority); } diff --git a/sys/src/9/port/qlock.c b/sys/src/9/port/qlock.c index 57982b217..0c064ae6f 100644 --- a/sys/src/9/port/qlock.c +++ b/sys/src/9/port/qlock.c @@ -22,8 +22,8 @@ eqlock(QLock *q) if(m->ilockdepth != 0) print("eqlock: %#p: ilockdepth %d\n", getcallerpc(&q), m->ilockdepth); - if(up != nil && up->nlocks.ref) - print("eqlock: %#p: nlocks %lud\n", getcallerpc(&q), up->nlocks.ref); + if(up != nil && up->nlocks) + print("eqlock: %#p: nlocks %d\n", getcallerpc(&q), up->nlocks); if(up != nil && up->eql) print("eqlock: %#p: eql %p\n", getcallerpc(&q), up->eql); if(q->use.key == 0x55555555) @@ -70,8 +70,8 @@ qlock(QLock *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 %d\n", getcallerpc(&q), up->nlocks); if(up != nil && up->eql) print("qlock: %#p: eql %p\n", getcallerpc(&q), up->eql); if(q->use.key == 0x55555555) diff --git a/sys/src/9/port/taslock.c b/sys/src/9/port/taslock.c index 641b84d16..730538ba7 100644 --- a/sys/src/9/port/taslock.c +++ b/sys/src/9/port/taslock.c @@ -10,8 +10,8 @@ long maxlockcycles; long maxilockcycles; long cumlockcycles; long cumilockcycles; -ulong maxlockpc; -ulong maxilockpc; +uintptr maxlockpc; +uintptr maxilockpc; struct { @@ -20,23 +20,6 @@ struct 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) { @@ -73,12 +56,13 @@ lock(Lock *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->m = MACHP(m->machno); l->isilock = 0; #ifdef LOCKCYCLES l->lockcycles = -lcycles(); @@ -86,7 +70,7 @@ lock(Lock *l) return 0; } if(up) - deccnt(&up->nlocks); + up->nlocks--; lockstats.glare++; for(;;){ @@ -108,12 +92,13 @@ lock(Lock *l) } } if(up) - inccnt(&up->nlocks); + up->nlocks++; if(tas(&l->key) == 0){ if(up) up->lastlock = l; l->pc = pc; l->p = up; + l->m = MACHP(m->machno); l->isilock = 0; #ifdef LOCKCYCLES l->lockcycles = -lcycles(); @@ -121,7 +106,7 @@ lock(Lock *l) return 1; } if(up) - deccnt(&up->nlocks); + up->nlocks--; } } @@ -159,8 +144,8 @@ acquire: l->sr = x; l->pc = pc; l->p = up; - l->isilock = 1; l->m = MACHP(m->machno); + l->isilock = 1; #ifdef LOCKCYCLES l->lockcycles = -lcycles(); #endif @@ -170,10 +155,10 @@ int canlock(Lock *l) { if(up) - inccnt(&up->nlocks); + up->nlocks++; if(tas(&l->key)){ if(up) - deccnt(&up->nlocks); + up->nlocks--; return 0; } @@ -210,7 +195,7 @@ unlock(Lock *l) 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 @@ -219,7 +204,7 @@ unlock(Lock *l) } } -ulong ilockpcs[0x100] = { [0xff] = 1 }; +uintptr ilockpcs[0x100] = { [0xff] = 1 }; static int n; void