shithub: drawterm

Download patch

ref: c0951f2a3182d8b70ffe579bfd9da24c2b86e232
parent: de6172c0abcbd9977dd1e39029248079f6f1e9c7
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Tue Apr 23 10:23:05 EDT 2024

kern: don't touch proc in wakeup() after procwakeup()

In case the Rendez structure is backed by dynamic
memory that might be freed after we ready the sleeping
process, we must not touch it (unlock(&r->lk)) after
procwakeup().

(Also remove unused copy of rendez.c).

--- a/kern/rendez.c
+++ /dev/null
@@ -1,89 +1,0 @@
-#include	"u.h"
-#include	"lib.h"
-#include	"dat.h"
-#include	"fns.h"
-#include	"error.h"
-
-void
-sleep(Rendez *r, int (*f)(void*), void *arg)
-{
-	int s;
-
-	s = splhi();
-
-	lock(&r->lk);
-	lock(&up->rlock);
-	if(r->p){
-		print("double sleep %lud %lud\n", r->p->pid, up->pid);
-	}
-
-	/*
-	 *  Wakeup only knows there may be something to do by testing
-	 *  r->p in order to get something to lock on.
-	 *  Flush that information out to memory in case the sleep is
-	 *  committed.
-	 */
-	r->p = up;
-
-	if((*f)(arg) || up->notepending){
-		/*
-		 *  if condition happened or a note is pending
-		 *  never mind
-		 */
-		r->p = nil;
-		unlock(&up->rlock);
-		unlock(&r->lk);
-	} else {
-		/*
-		 *  now we are committed to
-		 *  change state and call scheduler
-		 */
-		up->state = Wakeme;
-		up->r = r;
-
-		/* statistics */
-		/* m->cs++; */
-
-		unlock(&up->rlock);
-		unlock(&r->lk);
-
-		procsleep();
-	}
-
-	if(up->notepending) {
-		up->notepending = 0;
-		splx(s);
-		error(Eintr);
-	}
-
-	splx(s);
-}
-
-Proc*
-wakeup(Rendez *r)
-{
-	Proc *p;
-	int s;
-
-	s = splhi();
-
-	lock(&r->lk);
-	p = r->p;
-
-	if(p != nil){
-		lock(&p->rlock);
-		if(p->state != Wakeme || p->r != r)
-			panic("wakeup: state");
-		r->p = nil;
-		p->r = nil;
-		p->state = Running;
-		procwakeup(p);
-		unlock(&p->rlock);
-	}
-	unlock(&r->lk);
-
-	splx(s);
-
-	return p;
-}
-
--- a/kern/sleep.c
+++ b/kern/sleep.c
@@ -70,18 +70,19 @@
 	lock(&r->lk);
 	p = r->p;
 
-	if(p != nil){
+	if(p == nil)
+		unlock(&r->lk);
+	else {
 		lock(&p->rlock);
 		if(p->state != Wakeme || p->r != r)
 			panic("wakeup: state");
+		p->state = Running;
 		r->p = nil;
 		p->r = nil;
-		p->state = Running;
-		procwakeup(p);
 		unlock(&p->rlock);
+		unlock(&r->lk);
+		procwakeup(p);
 	}
-	unlock(&r->lk);
-
 	splx(s);
 
 	return p;