From 1e9f8fab0a15fa6ab54455d7c64b7391ebbd4af3 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Fri, 9 Mar 1990 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1990-03-09 --- port/devmnt.c | 50 +++++++++++++++++-------- port/devproc.c | 7 ++++ port/proc.c | 100 ++++++++++++++++++++++++++++++++++++------------- port/sysproc.c | 15 ++++++++ power/dat.h | 5 +++ power/devbit.c | 38 +++++++++++++++---- 6 files changed, 167 insertions(+), 48 deletions(-) diff --git a/port/devmnt.c b/port/devmnt.c index a899d915a57bdbb92993755dd46d69424e1d5c43..6fdc537c0b9bf4c8dc9860acfdc884665cc2bd84 100644 --- a/port/devmnt.c +++ b/port/devmnt.c @@ -553,7 +553,7 @@ mntxmit(Mnt *m, Mnthdr *mh) { ulong n; Mntbuf *mbr, *mbw; - Chan *mntpt; + Chan *mntpt, *msg; int isbit; mbr = mballoc(); @@ -564,23 +564,38 @@ mntxmit(Mnt *m, Mnthdr *mh) nexterror(); } n = convS2M(&mh->thdr, mbw->buf); - qlock(m); - if(m->msg == 0){ - qunlock(m); - error(0, Eshutdown); - } isbit = 0; if(devchar[m->msg->type] == 'b') isbit = 1; - if(!isbit) - qlock(m->msg); + /* + * Avoid qlock for bit, to maximize parallelism + */ + if(isbit){ + lock(&m->use); /* spin rather than sleep */ + if((msg = m->msg) == 0){ + unlock(&m->use); + error(0, Eshutdown); + } + incref(msg); + unlock(&m->use); + }else{ + qlock(m); + if((msg = m->msg) == 0){ + qunlock(m); + error(0, Eshutdown); + } + qlock(msg); + } if(waserror()){ - qunlock(m); - if(!isbit) - qunlock(m->msg); + if(isbit) + close(msg); + else{ + qunlock(m); + qunlock(msg); + } nexterror(); } - if((*devtab[m->msg->type].write)(m->msg, mbw->buf, n) != n){ + if((*devtab[msg->type].write)(msg, mbw->buf, n) != n){ pprint("short write in mntxmit\n"); error(0, Egreg); } @@ -588,10 +603,13 @@ mntxmit(Mnt *m, Mnthdr *mh) /* * Read response */ - n = (*devtab[m->msg->type].read)(m->msg, mbr->buf, BUFSIZE); - qunlock(m); - if(!isbit) - qunlock(m->msg); + n = (*devtab[msg->type].read)(msg, mbr->buf, BUFSIZE); + if(isbit) + close(msg); + else{ + qunlock(m); + qunlock(msg); + } poperror(); if(convM2S(mbr->buf, &mh->rhdr, n) == 0){ diff --git a/port/devproc.c b/port/devproc.c index d444aa1a92fa7fe2ae05081b5f823e8ed2097a60..5b6c56fad09f6b6e6cd3cd7671fdafd2adf33411 100644 --- a/port/devproc.c +++ b/port/devproc.c @@ -82,6 +82,7 @@ procreset(void) Chan* procattach(char *spec) { + Chan *c; return devattach('p', spec); } @@ -110,6 +111,11 @@ procopen(Chan *c, int omode) Orig *o; Chan *tc; + if(c->qid == CHDIR){ + if(omode != OREAD) + error(0, Eperm); + goto done; + } p = proctab(SLOT(c->qid)); if((p->pid&PIDMASK) != PID(c->qid)) Died: @@ -156,6 +162,7 @@ procopen(Chan *c, int omode) */ if(p->state != Dead) c->qid |= (p->pid&PIDMASK)<mode = omode; c->flag |= COPEN; c->offset = 0; diff --git a/port/proc.c b/port/proc.c index ff93da21165e52071fa2bb91210543f8336d4473..f0639ded6ae9cdb3a06627601af9b659864707b9 100644 --- a/port/proc.c +++ b/port/proc.c @@ -165,6 +165,9 @@ loop: unlock(&procalloc); p->mach = 0; p->qnext = 0; + p->kid = 0; + p->sib = 0; + p->pop = 0; p->nchild = 0; p->child = 0; p->exiting = 0; @@ -339,65 +342,66 @@ pexit(char *s, int freemem) { char status[64]; ulong mypid; - Proc *p; + Proc *p, *c, *k, *l; Waitmsg w; int n; - Chan *c; + Chan *ch; ulong *up, *ucp, *wp; - mypid = u->p->pid; + c = u->p; + mypid = c->pid; if(s) strcpy(status, s); else status[0] = 0; if(freemem){ freesegs(-1); - closepgrp(u->p->pgrp); + closepgrp(c->pgrp); close(u->dot); } for(n=0; n<=u->maxfd; n++) - if(c = u->fd[n]) /* assign = */ - close(c); + if(ch = u->fd[n]) /* assign = */ + close(ch); /* * Any of my children exiting? */ - while(u->p->nchild){ - lock(&u->p->wait.queue); - if(canlock(&u->p->wait.use)){ /* no child is exiting */ - u->p->exiting = 1; - unlock(&u->p->wait.use); - unlock(&u->p->wait.queue); + while(c->nchild){ + lock(&c->wait.queue); + if(canlock(&c->wait.use)){ /* no child is exiting */ + c->exiting = 1; + unlock(&c->wait.use); + unlock(&c->wait.queue); break; }else{ /* must wait for child */ - unlock(&u->p->wait.queue); + unlock(&c->wait.queue); pwait(0); } } - u->p->time[TReal] = MACHP(0)->ticks - u->p->time[TReal]; + c->time[TReal] = MACHP(0)->ticks - c->time[TReal]; /* * Tell my parent */ - p = u->p->parent; + p = c->parent; if(p == 0) goto out; qlock(&p->wait); lock(&p->wait.queue); - if(p->pid==u->p->parentpid && !p->exiting){ + if(p->pid==c->parentpid && !p->exiting){ w.pid = mypid; strcpy(w.msg, status); wp = &w.time[TUser]; - up = &u->p->time[TUser]; - ucp = &u->p->time[TCUser]; + up = &c->time[TUser]; + ucp = &c->time[TCUser]; *wp++ = (*up++ + *ucp++)*MS2HZ; *wp++ = (*up++ + *ucp )*MS2HZ; *wp = (*up )*MS2HZ; - p->child = u->p; + p->child = c; /* * Pass info through back door, to avoid huge Proc's */ - p->waitmsg = (Waitmsg*)(u->p->upage->pa|(((ulong)&w)&(BY2PG-1))|KZERO); - u->p->state = Exiting; + p->waitmsg = (Waitmsg*)(c->upage->pa|(((ulong)&w)&(BY2PG-1))|KZERO); + c->state = Exiting; if(p->state == Inwait) ready(p); unlock(&p->wait.queue); @@ -408,15 +412,61 @@ pexit(char *s, int freemem) } out: if(!freemem){ - u->p->state = Broken; + c->state = Broken; sched(); /* until someone lets us go */ freesegs(-1); - closepgrp(u->p->pgrp); + closepgrp(c->pgrp); close(u->dot); } + + /* + * Rearrange inheritance hierarchy + * 1. my children's pop is now my pop + */ + lock(&c->kidlock); + p = c->pop; + if(k = c->kid) /* assign = */ + do{ + k->pop = p; + k = k->sib; + }while(k != c->kid); + + /* + * 2. cut me from pop's tree + */ + if(p == 0) /* init process only; fix pops */ + goto done; + lock(&p->kidlock); + k = p->kid; + while(k->sib != c) + k = k->sib; + if(k == c) + p->kid = 0; + else{ + if(p->kid == c) + p->kid = c->sib; + k->sib = c->sib; + } + + /* + * 3. pass my children (pop's grandchildren) to pop + */ + if(k = c->kid){ /* assign = */ + if(p->kid == 0) + p->kid = k; + else{ + l = k->sib; + k->sib = p->kid->sib; + p->kid->sib = l; + } + } + unlock(&p->kidlock); + done: + unlock(&c->kidlock); + lock(&procalloc); /* sched() can't do this */ - lock(&u->p->debug); /* sched() can't do this */ - u->p->state = Moribund; + lock(&c->debug); /* sched() can't do this */ + c->state = Moribund; sched(); /* never returns */ } diff --git a/port/sysproc.c b/port/sysproc.c index d75c8cec6e8456ab2ed009a01e63ecb12ded3d9b..271f3e0daaff7c7242cb239e34bd93c06c1a3b49 100644 --- a/port/sysproc.c +++ b/port/sysproc.c @@ -104,6 +104,20 @@ sysfork(ulong *arg) for(n=0; n<=u->maxfd; n++) if(c = u->fd[n]) /* assign = */ incref(c); + /* + * Committed. Link into hierarchy + */ + lock(&p->kidlock); + lock(&u->p->kidlock); + if(u->p->kid == 0){ + p->sib = p; + u->p->kid = p; + }else{ + p->sib = u->p->kid->sib; + u->p->kid->sib = p; + } + unlock(&u->p->kidlock); + unlock(&p->kidlock); /* * Sched */ @@ -115,6 +129,7 @@ sysfork(ulong *arg) spllo(); return 0; } + p->pop = u->p; p->parent = u->p; p->parentpid = u->p->pid; p->pgrp = u->p->pgrp; diff --git a/power/dat.h b/power/dat.h index f169942a147b4d6592bff575dfd12ce9f07bb76c..0b8aeef2b3472c8f984ca3075ee9111d7794e75d 100644 --- a/power/dat.h +++ b/power/dat.h @@ -81,6 +81,7 @@ struct Bitmsg ulong cmd; ulong addr; ulong count; + ulong rcount; }; #define CHDIR 0x80000000L @@ -301,6 +302,10 @@ struct Proc Page *upage; /* BUG: should be unlinked from page list */ Seg seg[NSEG]; ulong pid; + Lock kidlock; /* access to kid and sib */ + Proc *pop; /* some ascendant */ + Proc *kid; /* some descendant */ + Proc *sib; /* non-ascendant relatives (circular list) */ int nchild; QLock wait; /* exiting children to be waited for */ Waitmsg *waitmsg; diff --git a/power/devbit.c b/power/devbit.c index a3c16b1079d4ccb8da4ab158d66081a60362dbed..f2dec8a8fdd189c038f52a3fd517b0e6a51b6c6a 100644 --- a/power/devbit.c +++ b/power/devbit.c @@ -16,6 +16,7 @@ static struct }bit; #define BITADDR ((Bitmsg**)(KZERO+0x7C)) +#define BITHOLD ((ulong*)(KZERO+0x78)) #define BITINTR ((char*)(UNCACHED|0x17c12001)) enum @@ -25,23 +26,27 @@ enum WRITE, }; +long hold, wait, hang; + void bitsend(Bitmsg *bp, ulong cmd, void *addr, ulong count) { + do wait++; while(*BITADDR); bp->cmd = cmd; bp->addr = (ulong)addr; bp->count = count; - if(*BITADDR) - panic("bitsend"); +/* print("%d %lux %d ", cmd, addr, count); /**/ *BITADDR = bp; wbflush(); + do hold++; while(*BITHOLD); *BITINTR = 0x20; - do; while(*BITADDR); +/* print("done\n"); /**/ } void bitreset(void) { + *BITHOLD = 0; *BITADDR = 0; qlock(&bit); qunlock(&bit); @@ -94,7 +99,6 @@ bitopen(Chan *c, int omode) qlock(&bit); if(bit.open){ qunlock(&bit); -print("multiple bit open\n"); error(0, Einuse); } bitsend(bp, RESET, 0, 0); @@ -135,6 +139,7 @@ bitread(Chan *c, void *buf, long n) int docpy; bp = &((User*)(u->p->upage->pa|KZERO))->bit; + bp->rcount = 0; switch(c->qid){ case 1: if(n > sizeof bit.buf) @@ -148,11 +153,21 @@ bitread(Chan *c, void *buf, long n) docpy = 1; } qunlock(&bit); - do - n = bp->count; - while(n == 0); + do{ + n = bp->rcount; + hang++; + }while(n == 0); if(docpy) memcpy(buf, bit.buf, n); +if(0 && n > 512){ + int i; + char *cp=buf; + for(i=9; i sizeof bit.buf) error(0, Egreg); +if(0 && n > 512){ + int i; + char *cp=buf; + for(i=15; i