shithub: riscv

Download patch

ref: 91614f582fb1504ae3be2d57c079f24b60d71613
parent: 76db435e3cf86e0a6eb750d789bc15b64027a379
author: cinap_lenrek <[email protected]>
date: Thu Jun 5 17:54:32 EDT 2014

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.

--- a/sys/src/9/port/allocb.c
+++ b/sys/src/9/port/allocb.c
@@ -65,7 +65,7 @@
 	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);
--- a/sys/src/9/port/fault.c
+++ b/sys/src/9/port/fault.c
@@ -14,10 +14,10 @@
 
 	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;
--- a/sys/src/9/port/portdat.h
+++ b/sys/src/9/port/portdat.h
@@ -718,7 +718,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 */
--- a/sys/src/9/port/proc.c
+++ b/sys/src/9/port/proc.c
@@ -137,7 +137,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.Lock.p == up
@@ -632,7 +632,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");
@@ -742,9 +742,9 @@
 
 	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 @@
 	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);
 }
 
--- a/sys/src/9/port/qlock.c
+++ b/sys/src/9/port/qlock.c
@@ -22,8 +22,8 @@
 
 	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 @@
 
 	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)
--- a/sys/src/9/port/taslock.c
+++ b/sys/src/9/port/taslock.c
@@ -10,8 +10,8 @@
 long maxilockcycles;
 long cumlockcycles;
 long cumilockcycles;
-ulong maxlockpc;
-ulong maxilockpc;
+uintptr maxlockpc;
+uintptr maxilockpc;
 
 struct
 {
@@ -21,23 +21,6 @@
 } 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;
@@ -73,12 +56,13 @@
 
 	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 @@
 		return 0;
 	}
 	if(up)
-		deccnt(&up->nlocks);
+		up->nlocks--;
 
 	lockstats.glare++;
 	for(;;){
@@ -108,12 +92,13 @@
 			}
 		}
 		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 @@
 			return 1;
 		}
 		if(up)
-			deccnt(&up->nlocks);
+			up->nlocks--;
 	}
 }
 
@@ -159,8 +144,8 @@
 	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 @@
 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 @@
 	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 @@
 	}
 }
 
-ulong ilockpcs[0x100] = { [0xff] = 1 };
+uintptr ilockpcs[0x100] = { [0xff] = 1 };
 static int n;
 
 void