From 585e2325b33c067dabe84f9940a8d5e4aa4968f7 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Tue, 9 Mar 1993 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1993-03-09 --- port/devproc.c | 35 +++++++++++++++++++++++++++++++++-- port/portdat.h | 1 + port/portfns.h | 1 + port/proc.c | 13 ++++++++++++- 4 files changed, 47 insertions(+), 3 deletions(-) diff --git a/port/devproc.c b/port/devproc.c index 464736a76b32d24e4f9357dc43190bc13250a2ff..ed22d0fab2ac4b48655a984ff71cdcc8d80422c3 100644 --- a/port/devproc.c +++ b/port/devproc.c @@ -18,6 +18,7 @@ enum{ Qsegment, Qstatus, Qtext, + Qwait, }; #define STATSIZE (2*NAMELEN+12+7*12) @@ -31,6 +32,7 @@ Dirtab procdir[] = "segment", {Qsegment}, 0, 0444, "status", {Qstatus}, STATSIZE, 0444, "text", {Qtext}, 0, 0000, + "wait", {Qwait}, 0, 0400, }; /* Segment type from portdat.h */ @@ -157,8 +159,6 @@ procopen(Chan *c, int omode) switch(QID(c->qid)){ case Qtext: - if(omode != OREAD) - error(Eperm); tc = proctext(c, p); tc->offset = 0; return tc; @@ -169,6 +169,7 @@ procopen(Chan *c, int omode) case Qsegment: case Qproc: case Qstatus: + case Qwait: break; case Qnotepg: @@ -243,6 +244,7 @@ procread(Chan *c, void *va, long n, ulong offset) long l; User *up; Segment *sg; + Waitq *wq; if(c->qid.path & CHDIR) return devdirread(c, a, n, 0, 0, procgen); @@ -383,6 +385,35 @@ procread(Chan *c, void *va, long n, ulong offset) exhausted("segments"); memmove(a, &statbuf[offset], n); return n; + + case Qwait: + if(n < sizeof(Waitmsg)) + error(Etoosmall); + + if(!canqlock(&p->qwaitr)) + error(Einuse); + + if(waserror()) { + qunlock(&p->qwaitr); + nexterror(); + } + + lock(&p->exl); + while(p->waitq == 0) { + unlock(&p->exl); + sleep(&p->waitr, haswaitq, p); + lock(&p->exl); + } + wq = p->waitq; + p->waitq = wq->next; + p->nwait--; + unlock(&p->exl); + + qunlock(&p->qwaitr); + poperror(); + memmove(a, &wq->w, sizeof(Waitmsg)); + free(wq); + return sizeof(Waitmsg); } error(Egreg); return 0; /* not reached */ diff --git a/port/portdat.h b/port/portdat.h index d4f714f58b410f811f399eab8d5ec175a474a992..24242c8af9e4373713b345ac354b1cedcea8c7cf 100644 --- a/port/portdat.h +++ b/port/portdat.h @@ -576,6 +576,7 @@ struct Proc 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 *parent; diff --git a/port/portfns.h b/port/portfns.h index bd723dd897321fabf8d97964f21885397eb4eeeb..782dff32e3b20d66782945d523d4c907c22765c9 100644 --- a/port/portfns.h +++ b/port/portfns.h @@ -83,6 +83,7 @@ Block* getq(Queue*); int gets(IOQ*, void*, int); void gotolabel(Label*); Block* grabq(Queue*); +int haswaitq(void*); int hwcursmove(int, int); int hwcursset(uchar*, uchar*, int, int); long ibrk(ulong, int); diff --git a/port/proc.c b/port/proc.c index 6cbbcadd465fc3963c88f6bb6508e49a8fde6fe4..eb08a3e88b87d09d1a8fb8ad85f40576b20f00f1 100644 --- a/port/proc.c +++ b/port/proc.c @@ -590,7 +590,7 @@ pexit(char *exitstr, int freemem) p->waitq = wq; p->nwait++; unlock(&p->exl); - + wakeup(&p->waitr); } else { @@ -652,6 +652,14 @@ pwait(Waitmsg *w) p = u->p; + if(!canqlock(&p->qwaitr)) + error(Einuse); + + if(waserror()) { + qunlock(&p->qwaitr); + nexterror(); + } + lock(&p->exl); if(p->nchild == 0 && p->waitq == 0) { unlock(&p->exl); @@ -667,6 +675,9 @@ pwait(Waitmsg *w) p->nwait--; unlock(&p->exl); + qunlock(&p->qwaitr); + poperror(); + if(w) memmove(w, &wq->w, sizeof(Waitmsg)); cpid = atoi(wq->w.pid);