ref: 044d3e74eb7be6c3c9bb9b7a39d04c731467d109
parent: 858893ff8ff8d3abd06742276bcb794f3422bab8
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Fri Dec 22 13:28:25 EST 2023
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.
--- a/sys/src/9/port/portdat.h
+++ b/sys/src/9/port/portdat.h
@@ -78,6 +78,7 @@
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 @@
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
--- a/sys/src/9/port/qlock.c
+++ b/sys/src/9/port/qlock.c
@@ -19,19 +19,23 @@
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 @@
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 @@
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 @@
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 @@
return 0;
}
q->locked = 1;
+ q->pc = getcallerpc(&q);
unlock(&q->use);
return 1;
}
@@ -126,6 +134,7 @@
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 @@
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 @@
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 @@
p->qnext = up;
q->tail = up;
up->qnext = nil;
+ up->qpc = pc;
up->state = QueueingW;
unlock(&q->use);
sched();
@@ -235,6 +248,7 @@
}
if(p->state == QueueingW){
/* start waiting writer */
+ q->wpc = p->qpc;
q->head = p->qnext;
if(q->head == nil)
q->tail = nil;