shithub: drawcpu

Download patch

ref: be21af8515dcebab0ae2991e8e952af04e06baad
parent: 7ae756a098788e2787b604b2d757edd22dffe56b
author: halfwit <michaelmisch1985@gmail.com>
date: Wed Jan 28 17:45:51 EST 2026

Large updates to fix more broken things

--- a/include/lib.h
+++ b/include/lib.h
@@ -202,12 +202,20 @@
 	char	*muid;	/* last modifier name */
 } Dir;
 
+typedef 
+struct OWaitmsg
+{
+	char	pid[12];	/* of loved one */
+	char	time[3*12];	/* of loved one and descendants */
+	char	msg[64];	/* compatibility BUG */
+} OWaitmsg;
+
 typedef
 struct Waitmsg
 {
 	int pid;	/* of loved one */
 	ulong dur[3];	/* of loved one & descendants */
-	char	*msg;
+	char	msg[64];
 } Waitmsg;
 
 /*
--- a/include/user.h
+++ b/include/user.h
@@ -63,8 +63,6 @@
 extern	long	write(int, void*, long);
 extern	int	wstat(char*, uchar*, int);
 extern	void	werrstr(char* ,...);
-extern  Waitmsg* wait(void);
-extern  int await(char*, int);
 extern	Dir	*dirstat(char*);
 extern	Dir	*dirfstat(int);
 extern	int	dirwstat(char*, Dir*);
@@ -118,7 +116,6 @@
 extern	void	exits(char*);
 extern	char*	getenv(char*);
 
-extern  int await(char*, int);
 extern  int awaitnohang(char*, int);
 extern  int awaitfor(int, char*, int);
 
--- a/kern/Makefile
+++ b/kern/Makefile
@@ -46,7 +46,6 @@
 	time.$O\
 	qio.$O\
 	qlock.$O\
-	wait.$O\
 	waserror.$O\
 	vfp.$O\
 	$(OS).$O
--- a/kern/chan.c
+++ b/kern/chan.c
@@ -1436,7 +1436,7 @@
 		 * The channel staying behind is c, the one moving forward is cnew.
 		 */
 		m = nil;
-		cnew = nil;	/* is this assignment necessary? */
+		cnew = nil;
 		if(!waserror()){	/* try create */
 			if(!nomount && findmount(&cnew, &m, c->type, c->dev, c->qid))
 				cnew = createdir(cnew, m);
@@ -1472,7 +1472,8 @@
 
 
 		/* create failed */
-		cclose(cnew);
+		if(cnew)
+			cclose(cnew);
 		putmhead(m);
 		if(omode & OEXCL)
 			nexterror();
--- a/kern/dat.h
+++ b/kern/dat.h
@@ -440,6 +440,7 @@
 
 	ulong	pid;
 	ulong	procmode;
+	ulong	parentpid;
 
 	Pgrp	*pgrp;		/* Process group for namespace */
 	Fgrp	*fgrp;		/* File descriptor group */
@@ -448,7 +449,6 @@
 
 	QLock	debug;
 	Lock	rlock;		/* sync sleep/wakeup with postnote */
-	Lock    exl;        /* rfork, etc */
 	Rendez	*r;		/* rendezvous point slept on */
 	Rendez	rsleep;		/* place for syssleep/debug */
 	int	notepending;	/* note issued but not acted on */
@@ -491,9 +491,15 @@
 
 	Proc	*qnext;
 	Proc    *parent;
+	Lock	exl;		/* Lock count and waitq */
+	Waitq	*waitq;		/* Exited processes wait children */
+	int		nchild;		/* Number of living children */
+	int		nwait;		/* Number of uncollected wait records */
+	QLock	qwaitr;
+	Rendez	waitr;		/* Place to hang out in wait */
+
 	Proc    *child;
 	ulong	noteid;		/* Equivalent of note group */
-	int     nchild;
 	int     procctl;
 	
 	void	(*fn)(void*);
@@ -589,6 +595,12 @@
 	Qflow		= (1<<3),	/* producer flow controlled */
 	Qcoalesce	= (1<<4),	/* coallesce packets on read */
 	Qkick		= (1<<5),	/* always call the kick routine after qwrite */
+};
+
+struct Waitq
+{
+	Waitmsg	w;
+	Waitq	*next;
 };
 
 #define DEVDOTDOT -1
--- a/kern/devcons.c
+++ b/kern/devcons.c
@@ -198,10 +198,13 @@
 	char buf[PRINTSIZE];
 
 	kprintoq = nil;	/* don't try to write to /dev/kprint */
-
 	if(panicking++) hang();
 	splhi();
+#ifdef DTRACE
+	strcpy(buf, smprint("%s errstr: %s panic: ", up->arg, up->errstr));
+#else
 	strcpy(buf, smprint("%s panic: ", up->arg));
+#endif
 	va_start(arg, fmt);
 	n = vseprint(buf+strlen(buf), buf+sizeof(buf), fmt, arg) - buf;
 	va_end(arg);
--- a/kern/fns.h
+++ b/kern/fns.h
@@ -86,7 +86,7 @@
 void		ilock(Lock*);
 void		iunlock(Lock*);
 int 		incref(Ref*);
-void        invalid(u32int);
+void        invalid(u32int, char*);
 int	    	iprint(char*, ...);
 void		isdir(Chan*);
 int		    iseve(void);
@@ -144,6 +144,7 @@
 void		panic(char*, ...);
 Cmdbuf*		parsecmd(char *a, int n);
 void		pathclose(Path*);
+ulong		pwait(Waitmsg*);
 void		pexit(char*, int);
 char        *popnote(Ureg*);
 void		printinit(void);
@@ -166,6 +167,7 @@
 Block*		pullupqueue(Queue*, int);
 int         pushnote(Proc*, Note*);
 void		putmhead(Mhead*);
+void        putseg(Segment*);
 void		putstr(char*);
 void		putstrn(char*, int);
 Label*	    pwaserror(void);
--- a/kern/fpa.c
+++ b/kern/fpa.c
@@ -34,7 +34,7 @@
 	Rn = up->R + ((instr >> 16) & 15);
 	Fd = up->F + ((instr >> 12) & 7);
 	if(Rn == up->R + 15)
-		invalid(instr);
+		invalid(instr, "fpatransfer");
 	off = (instr & 255) * 4;
 	if(!(instr  & fU))
 		off = -off;
@@ -47,7 +47,7 @@
 	case fL: *Fd = *(float *) targ; break;
 	case fT0: *(double *) targ = *Fd; break;
 	case fT0 | fL: *Fd = *(double *) targ; break;
-	default: invalid(instr);
+	default: invalid(instr, "fpatransfer default");
 	}
 	segunlock(seg);
 	if(!(instr & fP))
@@ -104,7 +104,7 @@
 	case 0: *Fd = (float) res; break;
 	case 1: *Fd = (double) res; break;
 	case 2: *Fd = res; break;
-	default: invalid(instr);
+	default: invalid(instr, "fpaoperation");
 	}
 }
 
@@ -123,7 +123,7 @@
 		switch((instr >> 21) & 7) {
 		case 4: break;
 		case 5: op = - op; break;
-		default: invalid(instr);
+		default: invalid(instr, "fparegtransfer");
 		}
 		if(op2 < op)
 			up->CPSR = (up->CPSR & ~FLAGS) | flN;
@@ -136,12 +136,12 @@
 		return;
 	}
 	if(instr & (1<<3))
-		invalid(instr);
+		invalid(instr, "fparegtransfer");
 	switch((instr >> 20) & 15) {
 	case 0: *Fn = *(long *) Rd; break;
 	case 1: tmp = op; *Rd = tmp; break;
 	case 2: up->FPSR = *Rd; break;
 	case 3: *Rd = up->FPSR; break;
-	default: invalid(instr);
+	default: invalid(instr, "fparegtransfer");
 	}
 }
\ No newline at end of file
--- a/kern/posix.c
+++ b/kern/posix.c
@@ -138,7 +138,6 @@
 	if(pthread_setspecific(prdakey, p))
 		panic("cannot setspecific");
 	(*p->fn)(p->arg);
-	pexit("", 0);
 	return 0;
 }
 
--- a/kern/procinit.c
+++ b/kern/procinit.c
@@ -14,6 +14,7 @@
 	p->rgrp = newrgrp();
 	p->pgrp = newpgrp();
 	p->egrp = newegrp();
+	p->parentpid = 0;
 	p->kp = 1;
 	_setproc(p);
 
@@ -81,31 +82,173 @@
 	return (void*)p;
 }
 
+static int
+haswaitq(void *x)
+{
+	return ((Proc*)x)->waitq != nil;
+}
+
+static void
+freenotes(Proc *p)
+{
+	while(p->nnote > 0){
+		freenote(p->note[--p->nnote]);
+		up->note[p->nnote] = nil;
+	}
+}
+
+ulong
+pwait(Waitmsg *w)
+{
+	ulong cpid;
+	Waitq *wq;
+
+	if(!canqlock(&up->qwaitr))
+		error(Einuse);
+
+	if(waserror()) {
+		qunlock(&up->qwaitr);
+		nexterror();
+	}
+
+	lock(&up->exl);
+	while(up->waitq == nil) {
+		if(up->nchild == 0) {
+			unlock(&up->exl);
+			error(Enochild);
+		}
+		unlock(&up->exl);
+		sleep(&up->waitr, haswaitq, up);
+		lock(&up->exl);
+	}
+
+	wq = up->waitq;
+	up->waitq = wq->next;
+	up->nwait--;
+	unlock(&up->exl);
+
+	qunlock(&up->qwaitr);
+	poperror();
+
+	if(w != nil)
+		memmove(w, &wq->w, sizeof(Waitmsg));
+	cpid = wq->w.pid;
+	free(wq);
+	return cpid;
+}
+
 void
-pexit(char *msg, int freemem)
+pexit(char *exitstr, int freemem)
 {
-	Proc *p = up;
+	Proc *p;
+	Waitq *wq;
+	Fgrp *fgrp;
+	Egrp *egrp;
+	Rgrp *rgrp;
+	Pgrp *pgrp;
+	Chan *dot;
+	Segment *s;
+	int i;
 
-	USED(freemem);
+	/* nil out all the resources under lock (free later) */
+	qlock(&up->debug);
+	fgrp = up->fgrp;
+	up->fgrp = nil;
+	egrp = up->egrp;
+	up->egrp = nil;
+	rgrp = up->rgrp;
+	up->rgrp = nil;
+	pgrp = up->pgrp;
+	up->pgrp = nil;
+	dot = up->dot;
+	up->dot = nil;
+	qunlock(&up->debug);
 
-	if(p->pgrp != nil){
-		closepgrp(p->pgrp);
-		p->pgrp = nil;
+	if(fgrp != nil)
+		closefgrp(fgrp);
+	if(egrp != nil)
+		closeegrp(egrp);
+	if(rgrp != nil)
+		closergrp(rgrp);
+	if(dot != nil)
+		cclose(dot);
+	if(pgrp != nil)
+		closepgrp(pgrp);
+
+	if(up->pid == 0){
+		if(exitstr == nil)
+			exitstr = "unknown";
+		panic("boot process died: %s", exitstr);
 	}
-	if(p->rgrp != nil){
-		closergrp(p->rgrp);
-		p->rgrp = nil;
+
+	p = up->parent;
+	if(p != nil && p->pid == up->parentpid && p->state != Broken){
+
+		wq = smalloc(sizeof(Waitq));
+		wq->w.pid = up->pid;
+		// TODO: Timers
+		wq->w.dur[0] = 1000;
+		wq->w.dur[1] = 1000;
+		wq->w.dur[2] = 1000;
+		if(exitstr != nil && exitstr[0])
+			snprint(wq->w.msg, sizeof(wq->w.msg), "%s %lud: %s", up->text, up->pid, exitstr);
+		else
+			snprint(wq->w.msg, 1, "%c", '0');
+		lock(&p->exl);
+		/*
+		 * Check that parent is still alive.
+		 */
+		if(p->pid == up->parentpid && p->state != Broken) {
+			p->nchild--;
+			//p->dur[TCUser] += 100;
+			//p->dur[TCSys] += 100;
+			/*
+			 * If there would be more than 128 wait records
+			 * processes for my parent, then don't leave a wait
+			 * record behind.  This helps prevent badly written
+			 * daemon processes from accumulating lots of wait
+			 * records.
+		 	 */
+			if(p->nwait < 128) {
+				wq->next = p->waitq;
+				p->waitq = wq;
+				p->nwait++;
+				wq = nil;
+				wakeup(&p->waitr);
+			}
+		}
+		unlock(&p->exl);
+		if(wq != nil)
+			free(wq);
 	}
-	if(p->fgrp != nil){
-		closefgrp(p->fgrp);
-		p->fgrp = nil;
+	qlock(&up->seglock);
+	for(i = 0; i < NSEG; i++){
+		s = up->seg[i];
+		if(s != nil){
+			up->seg[i] = nil;
+			putseg(s);
+		}
 	}
+	qunlock(&up->seglock);
 
-	if(freemem)
-		freesegs();
+	qlock(&up->debug);
 
-	cclose(p->dot);
-	cclose(p->slash);
-	free(p);
-	osexit(msg);
+	lock(&up->exl);		/* Prevent my children from leaving waits */
+	up->parent = nil;
+	up->nchild = up->nwait = 0;
+	wakeup(&up->waitr);
+	unlock(&up->exl);
+
+	while((wq = up->waitq) != nil){
+		up->waitq = wq->next;
+		free(wq);
+	}
+
+	freenotes(up);
+	freenote(up->lastnote);
+	up->lastnote = nil;
+	up->notified = 0;
+	qunlock(&up->debug);
+	osexit(exitstr);
+	panic("pexit");
 }
--- a/kern/seg.c
+++ b/kern/seg.c
@@ -13,12 +13,23 @@
 	for(i = 0; i < NSEG; i++){
 		s = up->seg[i];
 		rlock(&s->rw);
-		print("start %ul, end %ul, offset %ul", s->start, s->start + s->size, offset);
 		if(s->start <= offset && s->start + s->size >= offset)
 			return s;
 		runlock(&s->rw);
 	}
 	return nil;
+}
+
+void
+putseg(Segment *s)
+{
+	// Void data holds it all
+	if(s == nil)
+		return;
+
+	if(decref(&s->ref) != 0)
+		return;
+	free(s);
 }
 
 Segment *
--- a/kern/syscall.c
+++ b/kern/syscall.c
@@ -86,13 +86,13 @@
 	namet = copyifnec(name, -1, &copied);
 	fd = open(namet, flags);
 #ifdef DSYSCALL
-	print("sysopen: pid=%d, fd=%lux name=%s flags=%lux\n", up->pid, fd, namet, flags);
+	print("sysopen: pid=%d, fd=%ld name=%s flags=%lux\n", up->pid, fd, namet, flags);
 #endif
 	if(copied)
 		free(namet);
 	if(fd < 0) {
 		noteerr(0, 1);
-		up->R[0] = -1;
+		up->R[0] = fd;
 		return;
 	}
 	setcexec(fd, flags & OCEXEC);
@@ -112,7 +112,7 @@
 	namet = copyifnec(name, -1, &copied);
 	fd = create(namet, flags, perm);
 #ifdef DSYSCALL
-	print("syscreate: pid=%d, fd=%d name=%s\n", up->pid, fd, namet);
+	print("syscreate: pid=%d, fd=%ld name=%s\n", up->pid, fd, namet);
 #endif
 	if(copied)
 		free(namet);
@@ -132,7 +132,7 @@
 	
 	fd = arg(0);
 #ifdef DSYSCALL
-	print("sysclose: pid=%d, fd=%lux\n",up->pid, fd);
+	print("sysclose: pid=%d, fd=%ld\n",up->pid, fd);
 #endif
 	up->R[0] = noteerr(close(fd), 0);
 	if((fd & (1<<31)) == 0)
@@ -152,7 +152,7 @@
 	size = arg(2);
 	off = argv(3);
 #ifdef DSYSCALL
-	print("syspread: pid=%d, fd=%d size=0x%lux off=0x%lux\n", up->pid, fd, size, off);
+	print("syspread: pid=%d, fd=%ld size=0x%lux off=0x%lux\n", up->pid, fd, size, off);
 #endif
 	targ = bufifnec(buf, size, &buffered);
 	up->R[0] = noteerr(pread(fd, targ, size, off), size);
@@ -174,7 +174,7 @@
 	off = argv(3);
 	buft = copyifnec(buf, size, &copied);
 #ifdef DSYSCALL
-	print("syspwrite: pid=%d, fd=%ux buf=%s size=%lux off=%lux\n", up->pid, fd, buft, size, off);
+	print("syspwrite: pid=%d, fd=%ld buf=%s size=%lux off=%lux\n", up->pid, fd, buft, size, off);
 #endif
 	up->R[0] = noteerr(pwrite(fd, buft, size, off), size);
 	if(copied)
@@ -296,7 +296,7 @@
 	nedir = arg(2);
 	edirt = copyifnec(edir, nedir, &copied);
 #ifdef DSYSCALL
-	print("sysfwstat: pid=%d, fd=%d, edir=%us, nedir=%d, copied=%d\n", up->pid, fd, edirt, nedir, copied);
+	print("sysfwstat: pid=%d, fd=%ld, edir=%us, nedir=%d, copied=%d\n", up->pid, fd, edirt, nedir, copied);
 #endif
 	up->R[0] = noteerr(fwstat(fd, edirt, nedir), nedir);
 	if(copied)
@@ -317,7 +317,6 @@
 #endif
 		pexit(vaddrnol(arg(0), 0), 0);		
 	}
-
 }
 
 static void
@@ -618,19 +617,25 @@
 static void
 _sysawait(void)
 {
-	u32int s, n;
-	void *st;
-	int buffered;
-	
-	s = arg(0);
+	u32int p, n;
+	Waitmsg w;
+	char *pt;
+	int copied;
+
+	p = arg(0);
 	n = arg(1);
-	st = bufifnec(s, n, &buffered);
+	pt = copyifnec(p, 1, &copied);
 #ifdef DSYSCALL
-	print("sysawait: pid=%d\n", up->pid);
+	print("sysawait: pid=%d, n=%ux, pt=%s\n", up->pid, n, pt);
 #endif
-	up->R[0] = noteerr(sysawait(st, n), 0);
-	if(buffered)
-		copyback(s, up->R[0], st);
+	pwait(&w);
+	up->R[0] = (uintptr)snprint(pt, n, "%d %lud %lud %lud %q",
+		w.pid,
+	 	1000, 1000, 1000,
+		//w.time[TUser], w.time[TSys], w.time[TReal],
+		w.msg);
+	if(copied)
+		free(pt);
 }
 
 static void
@@ -711,13 +716,13 @@
 		if(!anamet) 
 			anamet = "";
 #ifdef DSYSCALL
-		print("sysmount: pid=%d, fd=%d, afd=%d, aname=%s, oldt=%s\n", up->pid, fd, afd, anamet, oldt);
+		print("sysmount: pid=%d, fd=%ld, afd=%ld, aname=%s, oldt=%s\n", up->pid, fd, afd, anamet, oldt);
 #endif
 	} else {
 		anamet = nil;
 		copiedaname = 0;
 #ifdef DSYSCALL
-		print("sysmount: pid=%d, fd=%d, afd=%d, oldt=%s\n", fd, afd, up->pid, oldt);
+		print("sysmount: pid=%d, fd=%ld, afd=%ld, oldt=%s\n", fd, afd, up->pid, oldt);
 #endif
 	}
 	up->R[0] = noteerr(mount(fd, afd, oldt, flag, anamet), 0);
@@ -825,11 +830,31 @@
 static void
 _sys_wait(void)
 {
-	Waitmsg *w;
+	ulong pid;
+	Waitmsg w;
+	u32int ow;
+	OWaitmsg *owt;
+	Segment *seg;
 
-	w = wait();
-	up->R[0] = w->pid;
-	free(w);
+	ow = arg(0);
+	print("SYSWAIT\n");
+	owt = vaddr(ow, 0, &seg);
+	if(owt == nil)
+		pid = pwait(nil);
+	else {
+		validaddr((uintptr)owt, sizeof(OWaitmsg), 1);
+		pid = pwait(&w);
+	}
+	if(owt != nil){
+		readnum(0, owt->pid, NUMSIZE, w.pid, NUMSIZE);
+		//readnum(0, owt->time+TUser*NUMSIZE, NUMSIZE, w.time[TUser], NUMSIZE);
+		//readnum(0, owt->time+TSys*NUMSIZE, NUMSIZE, w.time[TSys], NUMSIZE);
+		//readnum(0, owt->time+TReal*NUMSIZE, NUMSIZE, w.time[TReal], NUMSIZE);
+		strncpy(owt->msg, w.msg, sizeof(owt->msg)-1);
+		owt->msg[sizeof(owt->msg)-1] = '\0';
+	}
+	up->R[0] = pid;
+	segunlock(seg);
 }
 
 static void
--- a/kern/sysproc.c
+++ b/kern/sysproc.c
@@ -368,6 +368,7 @@
 	p->notified = 0;
 	p->notepending = 0;
 	p->lastnote = nil;
+	p->parentpid = up->pid;
 
 	if((flag & RFNOTEG) == 0)
 		p->noteid = up->noteid;
--- a/kern/wait.c
+++ /dev/null
@@ -1,49 +1,0 @@
-#include "u.h"
-#include "lib.h"
-#include "dat.h"
-#include "fns.h"
-#include "user.h"
-
-static Waitmsg*
-_wait(int n, char *buf)
-{
-	int l;
-	char *fld[5];
-	Waitmsg *w;
-
-	if(n <= 0)
-		return nil;
-	buf[n] = '\0';
-	if(tokenize(buf, fld, nelem(fld)) != nelem(fld)){
-		panic("couldn't parse wait message");
-		return nil;
-	}
-	l = strlen(fld[4])+1;
-	w = malloc(sizeof(Waitmsg)+l);
-	if(w == nil)
-		return nil;
-	w->pid = atoi(fld[0]);
-	w->dur[0] = atoi(fld[1]);
-	w->dur[1] = atoi(fld[2]);
-	w->dur[2] = atoi(fld[3]);
-	w->msg = (char*)&w[1];
-	memmove(w->msg, fld[4], l);
-	return w;
-}
-
-Waitmsg*
-syswait(void)
-{
-	char buf[256];
-	if(up->nchild <= 0)
-		return 0;
-	return _wait(await(buf, sizeof buf-1), buf);
-}
-
-int
-sysawait(char *p, int n)
-{
-	if(up->nchild <= 0)
-		return -1;
-	return osawait(up, p, n);
-}
--