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.
This commit is contained in:
parent
76db435e3c
commit
91614f582f
|
@ -65,7 +65,7 @@ allocb(int size)
|
||||||
if(up == nil)
|
if(up == nil)
|
||||||
panic("allocb without up: %#p", getcallerpc(&size));
|
panic("allocb without up: %#p", getcallerpc(&size));
|
||||||
while((b = _allocb(size)) == nil){
|
while((b = _allocb(size)) == nil){
|
||||||
if(up->nlocks.ref || m->ilockdepth || !islo()){
|
if(up->nlocks || m->ilockdepth || !islo()){
|
||||||
xsummary();
|
xsummary();
|
||||||
mallocsummary();
|
mallocsummary();
|
||||||
panic("allocb: no memory for %d bytes", size);
|
panic("allocb: no memory for %d bytes", size);
|
||||||
|
|
|
@ -14,10 +14,10 @@ fault(uintptr addr, int read)
|
||||||
|
|
||||||
if(up == nil)
|
if(up == nil)
|
||||||
panic("fault: nil up");
|
panic("fault: nil up");
|
||||||
if(up->nlocks.ref){
|
if(up->nlocks){
|
||||||
Lock *l = up->lastlock;
|
Lock *l = up->lastlock;
|
||||||
print("fault: nlocks %ld, proc %lud %s, addr %#p, lock %#p, lpc %#p\n",
|
print("fault: nlocks %d, proc %lud %s, addr %#p, lock %#p, lpc %#p\n",
|
||||||
up->nlocks.ref, up->pid, up->text, addr, l, l ? l->pc : 0);
|
up->nlocks, up->pid, up->text, addr, l, l ? l->pc : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
pnd = up->notepending;
|
pnd = up->notepending;
|
||||||
|
|
|
@ -718,7 +718,7 @@ struct Proc
|
||||||
|
|
||||||
Mach *wired;
|
Mach *wired;
|
||||||
Mach *mp; /* machine this process last ran on */
|
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 delaysched;
|
||||||
ulong priority; /* priority level */
|
ulong priority; /* priority level */
|
||||||
ulong basepri; /* base priority level */
|
ulong basepri; /* base priority level */
|
||||||
|
|
|
@ -137,7 +137,7 @@ sched(void)
|
||||||
* in the middle of taslock when a process holds a lock
|
* in the middle of taslock when a process holds a lock
|
||||||
* but Lock.p has not yet been initialized.
|
* but Lock.p has not yet been initialized.
|
||||||
*/
|
*/
|
||||||
if(up->nlocks.ref)
|
if(up->nlocks)
|
||||||
if(up->state != Moribund)
|
if(up->state != Moribund)
|
||||||
if(up->delaysched < 20
|
if(up->delaysched < 20
|
||||||
|| palloc.Lock.p == up
|
|| palloc.Lock.p == up
|
||||||
|
@ -632,7 +632,7 @@ newproc(void)
|
||||||
p->syserrstr = p->errbuf1;
|
p->syserrstr = p->errbuf1;
|
||||||
p->errbuf0[0] = '\0';
|
p->errbuf0[0] = '\0';
|
||||||
p->errbuf1[0] = '\0';
|
p->errbuf1[0] = '\0';
|
||||||
p->nlocks.ref = 0;
|
p->nlocks = 0;
|
||||||
p->delaysched = 0;
|
p->delaysched = 0;
|
||||||
p->trace = 0;
|
p->trace = 0;
|
||||||
kstrdup(&p->user, "*nouser");
|
kstrdup(&p->user, "*nouser");
|
||||||
|
@ -742,9 +742,9 @@ sleep(Rendez *r, int (*f)(void*), void *arg)
|
||||||
|
|
||||||
s = splhi();
|
s = splhi();
|
||||||
|
|
||||||
if(up->nlocks.ref)
|
if(up->nlocks)
|
||||||
print("process %lud sleeps with %lud locks held, last lock %#p locked at pc %#p, sleep called from %#p\n",
|
print("process %lud sleeps with %d 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));
|
up->pid, up->nlocks, up->lastlock, up->lastlock->pc, getcallerpc(&r));
|
||||||
lock(r);
|
lock(r);
|
||||||
lock(&up->rlock);
|
lock(&up->rlock);
|
||||||
if(r->p){
|
if(r->p){
|
||||||
|
@ -1289,9 +1289,9 @@ dumpaproc(Proc *p)
|
||||||
s = p->psstate;
|
s = p->psstate;
|
||||||
if(s == 0)
|
if(s == 0)
|
||||||
s = statename[p->state];
|
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->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);
|
p->lastlock ? p->lastlock->pc : 0, p->priority);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,8 +22,8 @@ eqlock(QLock *q)
|
||||||
|
|
||||||
if(m->ilockdepth != 0)
|
if(m->ilockdepth != 0)
|
||||||
print("eqlock: %#p: ilockdepth %d\n", getcallerpc(&q), m->ilockdepth);
|
print("eqlock: %#p: ilockdepth %d\n", getcallerpc(&q), m->ilockdepth);
|
||||||
if(up != nil && up->nlocks.ref)
|
if(up != nil && up->nlocks)
|
||||||
print("eqlock: %#p: nlocks %lud\n", getcallerpc(&q), up->nlocks.ref);
|
print("eqlock: %#p: nlocks %d\n", getcallerpc(&q), up->nlocks);
|
||||||
if(up != nil && up->eql)
|
if(up != nil && up->eql)
|
||||||
print("eqlock: %#p: eql %p\n", getcallerpc(&q), up->eql);
|
print("eqlock: %#p: eql %p\n", getcallerpc(&q), up->eql);
|
||||||
if(q->use.key == 0x55555555)
|
if(q->use.key == 0x55555555)
|
||||||
|
@ -70,8 +70,8 @@ qlock(QLock *q)
|
||||||
|
|
||||||
if(m->ilockdepth != 0)
|
if(m->ilockdepth != 0)
|
||||||
print("qlock: %#p: ilockdepth %d\n", getcallerpc(&q), m->ilockdepth);
|
print("qlock: %#p: ilockdepth %d\n", getcallerpc(&q), m->ilockdepth);
|
||||||
if(up != nil && up->nlocks.ref)
|
if(up != nil && up->nlocks)
|
||||||
print("qlock: %#p: nlocks %lud\n", getcallerpc(&q), up->nlocks.ref);
|
print("qlock: %#p: nlocks %d\n", getcallerpc(&q), up->nlocks);
|
||||||
if(up != nil && up->eql)
|
if(up != nil && up->eql)
|
||||||
print("qlock: %#p: eql %p\n", getcallerpc(&q), up->eql);
|
print("qlock: %#p: eql %p\n", getcallerpc(&q), up->eql);
|
||||||
if(q->use.key == 0x55555555)
|
if(q->use.key == 0x55555555)
|
||||||
|
|
|
@ -10,8 +10,8 @@ long maxlockcycles;
|
||||||
long maxilockcycles;
|
long maxilockcycles;
|
||||||
long cumlockcycles;
|
long cumlockcycles;
|
||||||
long cumilockcycles;
|
long cumilockcycles;
|
||||||
ulong maxlockpc;
|
uintptr maxlockpc;
|
||||||
ulong maxilockpc;
|
uintptr maxilockpc;
|
||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
|
@ -20,23 +20,6 @@ struct
|
||||||
ulong inglare;
|
ulong inglare;
|
||||||
} lockstats;
|
} 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
|
static void
|
||||||
dumplockmem(char *tag, Lock *l)
|
dumplockmem(char *tag, Lock *l)
|
||||||
{
|
{
|
||||||
|
@ -73,12 +56,13 @@ lock(Lock *l)
|
||||||
|
|
||||||
lockstats.locks++;
|
lockstats.locks++;
|
||||||
if(up)
|
if(up)
|
||||||
inccnt(&up->nlocks); /* prevent being scheded */
|
up->nlocks++; /* prevent being scheded */
|
||||||
if(tas(&l->key) == 0){
|
if(tas(&l->key) == 0){
|
||||||
if(up)
|
if(up)
|
||||||
up->lastlock = l;
|
up->lastlock = l;
|
||||||
l->pc = pc;
|
l->pc = pc;
|
||||||
l->p = up;
|
l->p = up;
|
||||||
|
l->m = MACHP(m->machno);
|
||||||
l->isilock = 0;
|
l->isilock = 0;
|
||||||
#ifdef LOCKCYCLES
|
#ifdef LOCKCYCLES
|
||||||
l->lockcycles = -lcycles();
|
l->lockcycles = -lcycles();
|
||||||
|
@ -86,7 +70,7 @@ lock(Lock *l)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if(up)
|
if(up)
|
||||||
deccnt(&up->nlocks);
|
up->nlocks--;
|
||||||
|
|
||||||
lockstats.glare++;
|
lockstats.glare++;
|
||||||
for(;;){
|
for(;;){
|
||||||
|
@ -108,12 +92,13 @@ lock(Lock *l)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(up)
|
if(up)
|
||||||
inccnt(&up->nlocks);
|
up->nlocks++;
|
||||||
if(tas(&l->key) == 0){
|
if(tas(&l->key) == 0){
|
||||||
if(up)
|
if(up)
|
||||||
up->lastlock = l;
|
up->lastlock = l;
|
||||||
l->pc = pc;
|
l->pc = pc;
|
||||||
l->p = up;
|
l->p = up;
|
||||||
|
l->m = MACHP(m->machno);
|
||||||
l->isilock = 0;
|
l->isilock = 0;
|
||||||
#ifdef LOCKCYCLES
|
#ifdef LOCKCYCLES
|
||||||
l->lockcycles = -lcycles();
|
l->lockcycles = -lcycles();
|
||||||
|
@ -121,7 +106,7 @@ lock(Lock *l)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if(up)
|
if(up)
|
||||||
deccnt(&up->nlocks);
|
up->nlocks--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,8 +144,8 @@ acquire:
|
||||||
l->sr = x;
|
l->sr = x;
|
||||||
l->pc = pc;
|
l->pc = pc;
|
||||||
l->p = up;
|
l->p = up;
|
||||||
l->isilock = 1;
|
|
||||||
l->m = MACHP(m->machno);
|
l->m = MACHP(m->machno);
|
||||||
|
l->isilock = 1;
|
||||||
#ifdef LOCKCYCLES
|
#ifdef LOCKCYCLES
|
||||||
l->lockcycles = -lcycles();
|
l->lockcycles = -lcycles();
|
||||||
#endif
|
#endif
|
||||||
|
@ -170,10 +155,10 @@ int
|
||||||
canlock(Lock *l)
|
canlock(Lock *l)
|
||||||
{
|
{
|
||||||
if(up)
|
if(up)
|
||||||
inccnt(&up->nlocks);
|
up->nlocks++;
|
||||||
if(tas(&l->key)){
|
if(tas(&l->key)){
|
||||||
if(up)
|
if(up)
|
||||||
deccnt(&up->nlocks);
|
up->nlocks--;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -210,7 +195,7 @@ unlock(Lock *l)
|
||||||
l->key = 0;
|
l->key = 0;
|
||||||
coherence();
|
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
|
* Call sched if the need arose while locks were held
|
||||||
* But, don't do it from interrupt routines, hence the islo() test
|
* 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;
|
static int n;
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
Loading…
Reference in a new issue