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);
-}
--
⑨