code: 9ferno

Download patch

ref: 47300e194a5276a5c9b91080944c2cb0ff4dd979
parent: 7191930290637622c1a4bb50a359809e62e4bf58
author: 9ferno <gophone2015@gmail.com>
date: Sat Oct 23 13:08:14 EDT 2021

inferno fine tuning to 9front taslock.c

--- a/os/port/taslock.c
+++ b/os/port/taslock.c
@@ -50,6 +50,7 @@
 		dumpaproc(p);
 }
 
+/* if looped to obtain a lock, return 1. Else, return 0 */
 int
 lock(Lock *l)
 {
@@ -61,7 +62,7 @@
 	lockstats.locks++;
 	if(up)
 		up->nlocks++;	/* prevent being scheded */
-	if(tas(&l->key) == 0){
+	if(tas(&l->key) == 0){ /* got the lock on the 1st attempt, done */
 		if(up)
 			up->lastlock = l;
 		l->pc = pc;
@@ -81,14 +82,17 @@
 		lockstats.inglare++;
 		i = 0;
 		while(l->key){
-			if(conf.nmach < 2 && up && up->edf && (up->edf->flags & Admitted)){
+			if(conf.nmach < 2 && up && up->state == Running && islo()
+				/* && up->edf && (up->edf->flags & Admitted)*/){
 				/*
 				 * Priority inversion, yield on a uniprocessor; on a
 				 * multiprocessor, the other processor will unlock
 				 */
-				print("inversion %#p pc %#p proc %lud held by pc %#p proc %lud\n",
+				print("inversion %#p pc %#p proc %zud held by pc %#p proc %zud\n",
 					l, pc, up != nil ? up->pid : 0, l->pc, l->p != nil ? ((Proc*)l->p)->pid : 0);
-				up->edf->d = todget(nil);	/* yield to process with lock */
+				/* up->edf->d = todget(nil);*/	/* yield to process with lock */
+				up->pc = pc;
+				sched();
 			}
 			if(i++ > 100000000){
 				i = 0;
@@ -98,8 +102,11 @@
 		if(up)
 			up->nlocks++;
 		if(tas(&l->key) == 0){
-			if(up)
+			if(up){
 				up->lastlock = l;
+				l->priority = up->priority;
+				up->priority = PriLock;
+			}
 			l->pc = pc;
 			l->p = up;
 			l->m = MACHP(m->machno);
@@ -126,6 +133,10 @@
 	x = splhi();
 	if(tas(&l->key) != 0){
 		lockstats.glare++;
+		if(conf.nmach < 2)
+			panic("ilock: no way out: pc 0x%zux:"
+					" lock 0x%p held by pc 0x%zux",
+					pc, l, l->pc);
 		/*
 		 * Cannot also check l->pc, l->m, or l->isilock here
 		 * because they might just not be set yet, or
@@ -160,14 +171,17 @@
 {
 	if(up)
 		up->nlocks++;
-	if(tas(&l->key)){
+	if(tas(&l->key) != 0){
 		if(up)
 			up->nlocks--;
 		return 0;
 	}
 
-	if(up)
+	if(up){
 		up->lastlock = l;
+		l->priority = up->priority;
+		up->priority = PriLock;
+	}
 	l->pc = getcallerpc(&l);
 	l->p = up;
 	l->m = MACHP(m->machno);
@@ -181,6 +195,7 @@
 void
 unlock(Lock *l)
 {
+	int pri;
 #ifdef LOCKCYCLES
 	l->lockcycles += lcycles();
 	cumlockcycles += l->lockcycles;
@@ -201,16 +216,22 @@
 		dumpaproc(l->p);
 		dumpaproc(up);
 	}
-	l->m = nil;
+	pri = l->priority;
+	l->m = l->p = nil;
+	l->pc = 0;
 	coherence();
 	l->key = 0;
 
-	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
-		 */
-		sched();
+	if(up){
+		up->priority = pri;
+		up->lastlock = nil;
+		if(--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
+			 */
+			sched();
+		}
 	}
 }
 
@@ -240,7 +261,8 @@
 		print("iunlock(%#p) while lo: pc %#p, held by %#p\n", l, getcallerpc(&l), l->pc);
 
 	sr = l->sr;
-	l->m = nil;
+	l->m = l->p = nil;
+	l->sr = l->pc = 0;
 	coherence();
 	l->key = 0;
 	m->ilockdepth--;