kernel: add pc field in QLock for debugging

Maintain a QLock.pc and RWLock.wpc field which is
the callerpc() of the last owner of the qlock/wlock.

The previous patch that set QLock.use.pc was
kind of nonsensical as it will get overridden
by the next attempt to acquire the qlock.
This commit is contained in:
cinap_lenrek 2023-12-22 18:28:25 +00:00
parent 858893ff8f
commit 044d3e74eb
2 changed files with 29 additions and 15 deletions

View file

@ -78,6 +78,7 @@ struct QLock
Lock use; /* to access Qlock structure */
Proc *head; /* next process waiting for object */
Proc *tail; /* last process waiting for object */
uintptr pc; /* pc of owner */
int locked; /* flag */
};
@ -93,9 +94,8 @@ struct RWlock
Proc *head; /* list of waiting processes */
Proc *tail;
uintptr wpc; /* pc of writer */
Proc *wproc; /* writing proc */
int readers; /* number of readers */
int writer; /* number of writers */
int readers; /* number of readers */
};
struct Alarms

View file

@ -19,19 +19,23 @@ void
eqlock(QLock *q)
{
Proc *p;
uintptr pc;
pc = getcallerpc(&q);
if(m->ilockdepth != 0)
print("eqlock: %#p: ilockdepth %d\n", getcallerpc(&q), m->ilockdepth);
print("eqlock: %#p: ilockdepth %d\n", pc, m->ilockdepth);
if(up != nil && up->nlocks)
print("eqlock: %#p: nlocks %d\n", getcallerpc(&q), up->nlocks);
print("eqlock: %#p: nlocks %d\n", pc, up->nlocks);
if(up != nil && up->eql != nil)
print("eqlock: %#p: eql %p\n", getcallerpc(&q), up->eql);
print("eqlock: %#p: eql %p\n", pc, up->eql);
if(q->use.key == 0x55555555)
panic("eqlock: q %#p, key 5*", q);
panic("eqlock: %#p: q %#p, key 5*", pc, q);
lock(&q->use);
rwstats.qlock++;
if(!q->locked) {
q->pc = pc;
q->locked = 1;
unlock(&q->use);
return;
@ -52,7 +56,7 @@ eqlock(QLock *q)
q->tail = up;
up->eql = q;
up->qnext = nil;
up->qpc = getcallerpc(&q);
up->qpc = pc;
up->state = Queueing;
unlock(&q->use);
sched();
@ -67,19 +71,22 @@ void
qlock(QLock *q)
{
Proc *p;
uintptr pc;
pc = getcallerpc(&q);
if(m->ilockdepth != 0)
print("qlock: %#p: ilockdepth %d\n", getcallerpc(&q), m->ilockdepth);
print("qlock: %#p: ilockdepth %d\n", pc, m->ilockdepth);
if(up != nil && up->nlocks)
print("qlock: %#p: nlocks %d\n", getcallerpc(&q), up->nlocks);
print("qlock: %#p: nlocks %d\n", pc, up->nlocks);
if(up != nil && up->eql != nil)
print("qlock: %#p: eql %p\n", getcallerpc(&q), up->eql);
print("qlock: %#p: eql %p\n", pc, up->eql);
if(q->use.key == 0x55555555)
panic("qlock: q %#p, key 5*", q);
panic("qlock: %#p: q %#p, key 5*", pc, q);
lock(&q->use);
rwstats.qlock++;
if(!q->locked) {
q->use.pc = getcallerpc(&q);
q->pc = pc;
q->locked = 1;
unlock(&q->use);
return;
@ -95,8 +102,8 @@ qlock(QLock *q)
q->tail = up;
up->eql = nil;
up->qnext = nil;
up->qpc = pc;
up->state = Queueing;
up->qpc = getcallerpc(&q);
unlock(&q->use);
sched();
}
@ -111,6 +118,7 @@ canqlock(QLock *q)
return 0;
}
q->locked = 1;
q->pc = getcallerpc(&q);
unlock(&q->use);
return 1;
}
@ -126,6 +134,7 @@ qunlock(QLock *q)
getcallerpc(&q));
p = q->head;
if(p != nil){
q->pc = p->qpc;
q->head = p->qnext;
if(q->head == nil)
q->tail = nil;
@ -184,6 +193,7 @@ runlock(RWlock *q)
q->head = p->qnext;
if(q->head == nil)
q->tail = nil;
q->wpc = p->qpc;
q->writer = 1;
unlock(&q->use);
ready(p);
@ -193,13 +203,15 @@ void
wlock(RWlock *q)
{
Proc *p;
uintptr pc;
pc = getcallerpc(&q);
lock(&q->use);
rwstats.wlock++;
if(q->readers == 0 && q->writer == 0){
/* noone waiting, go for it */
q->wpc = getcallerpc(&q);
q->wproc = up;
q->wpc = pc;
q->writer = 1;
unlock(&q->use);
return;
@ -216,6 +228,7 @@ wlock(RWlock *q)
p->qnext = up;
q->tail = up;
up->qnext = nil;
up->qpc = pc;
up->state = QueueingW;
unlock(&q->use);
sched();
@ -235,6 +248,7 @@ wunlock(RWlock *q)
}
if(p->state == QueueingW){
/* start waiting writer */
q->wpc = p->qpc;
q->head = p->qnext;
if(q->head == nil)
q->tail = nil;