From 4feb26d8c8fcc1fad3074c3f194fa8bc6eda4a1a Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Sat, 24 Nov 1990 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1990-11-24 --- gnot/dat.h | 6 +--- gnot/devmnt.c | 86 +++++++++++++++++++++++++++++++++++--------------- gnot/proc.c | 48 +--------------------------- gnot/sysproc.c | 15 --------- port/devmnt.c | 86 +++++++++++++++++++++++++++++++++++--------------- port/proc.c | 46 --------------------------- port/sysproc.c | 15 --------- power/dat.h | 6 +--- 8 files changed, 123 insertions(+), 185 deletions(-) diff --git a/gnot/dat.h b/gnot/dat.h index 997cc860ca94e4a6f152d7523fbf8f01db3033b6..acde038d801704b678ed4f6e9a0513a60882e1bc 100644 --- a/gnot/dat.h +++ b/gnot/dat.h @@ -325,10 +325,6 @@ struct Proc Seg seg[NSEG]; ulong bssend; /* initial top of bss seg */ 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 */ ulong waitmsg; @@ -361,7 +357,7 @@ struct MMUCache MMU mmu[NMMU]; }; -#define NERR 15 +#define NERR 20 #define NNOTE 5 #define NFD 100 struct User diff --git a/gnot/devmnt.c b/gnot/devmnt.c index 101194078f980ed3d07db23b2ec23204256f283f..b08e237c8f4571d8a5230ae83608d3619a1c76c0 100644 --- a/gnot/devmnt.c +++ b/gnot/devmnt.c @@ -49,7 +49,8 @@ struct Mnthdr { Mnthdr *next; /* in free list or writers list */ Mnthdr *prev; /* in writers list only */ - int writing; /* flag: in writers list */ + short active; + short flushing; /* a Tflush has been sent */ Fcall thdr; Fcall rhdr; Rendez r; @@ -122,6 +123,7 @@ loop: lock(&mnthdralloc); if(mh = mnthdralloc.free){ /* assign = */ mnthdralloc.free = mh->next; + mh->flushing = 0; unlock(&mnthdralloc); return mh; } @@ -138,6 +140,9 @@ loop: void mhfree(Mnthdr *mh) { + if(mh->flushing) + return; + mh->active = 0; lock(&mnthdralloc); mh->next = mnthdralloc.free; mnthdralloc.free = mh; @@ -601,22 +606,49 @@ mntwunlink(MntQ *q, Mnthdr *w) /* queue is locked and w is a writer */ if(q->writer) q->writer->prev = 0; } - w->writing = 0; } +/* + * m->q is unlocked. Send Tflush message to flush omh->tag. + * Cut off all errors. Caller will free omh + */ void -mnterrdequeue(MntQ *q, Mnthdr *mh) /* queue is unlocked */ +mntflush(Mnt *m, Mnthdr *omh) /* queue is unlocked */ +{ + Mnthdr *mh; + + if(omh->thdr.type == Tflush) + return; + + mh = mhalloc(); + if(waserror()){ + omh->flushing = 0; + mhfree(mh); + return; /* no more errors please */ + } + mh->thdr.type = Tflush; + mh->thdr.oldtag = omh->thdr.tag; + mntxmit(m, mh); + omh->flushing = 0; + mhfree(mh); + poperror(); +} + +void +mnterrdequeue(Mnt *m, Mnthdr *mh) /* queue is unlocked */ { Mnthdr *w; + MntQ *q; + mh->flushing = 1; + q = m->q; qlock(q); /* take self from queue if necessary */ if(q->reader == u->p){ /* advance a writer to reader */ w = q->writer; if(w){ + mntwunlink(q, w); q->reader = w->p; - q->writer = w->next; - q->writer->prev = 0; wakeup(&w->r); }else{ q->reader = 0; @@ -625,7 +657,7 @@ mnterrdequeue(MntQ *q, Mnthdr *mh) /* queue is unlocked */ }else mntwunlink(q, mh); qunlock(q); - + mntflush(m, mh); } int @@ -641,11 +673,11 @@ mntxmit(Mnt *m, Mnthdr *mh) Mntbuf *mbw, *t; Mnthdr *w, *ow; MntQ *q; - int qlocked, tag; + int qlocked, tag, written; mh->mbr = mballoc(); mbw = mballoc(); - if(waserror()){ + if(waserror()){ /* 1 */ mbfree(mh->mbr); mbfree(mbw); nexterror(); @@ -663,7 +695,7 @@ mntxmit(Mnt *m, Mnthdr *mh) goto Normal; incref(q); - if(waserror()){ + if(waserror()){ /* 2 */ mqfree(q); nexterror(); } @@ -677,7 +709,7 @@ mntxmit(Mnt *m, Mnthdr *mh) */ n = (*devtab[q->msg->type].read)(q->msg, mh->mbr->buf, BUFSIZE); mqfree(q); - poperror(); + poperror(); /* 2 */ if(convM2S(mh->mbr->buf, &mh->rhdr, n) == 0){ print("format error in mntxmit\n"); @@ -712,7 +744,7 @@ mntxmit(Mnt *m, Mnthdr *mh) memcpy(mh->thdr.data, mh->rhdr.data, mh->rhdr.count); mbfree(mh->mbr); mbfree(mbw); - poperror(); + poperror(); /* 1 */ return; Normal: @@ -720,13 +752,14 @@ mntxmit(Mnt *m, Mnthdr *mh) incref(q); qlock(q); qlocked = 1; - if(waserror()){ + if(waserror()){ /* 2 */ if(qlocked) qunlock(q); mqfree(q); nexterror(); } mh->readreply = 0; + mh->active = 1; if((*devtab[q->msg->type].write)(q->msg, mbw->buf, n) != n){ print("short write in mntxmit\n"); error(Eshortmsg); @@ -736,14 +769,15 @@ mntxmit(Mnt *m, Mnthdr *mh) Read: qunlock(q); qlocked = 0; - if(waserror()){ - mnterrdequeue(q, mh); + if(waserror()){ /* 3 */ + mnterrdequeue(m, mh); nexterror(); } n = (*devtab[q->msg->type].read)(q->msg, mh->mbr->buf, BUFSIZE); - poperror(); + poperror(); /* 3 */ if(convM2S(mh->mbr->buf, &mh->rhdr, n) == 0){ - mnterrdequeue(q, mh); + print("bad reply message\n"); + mnterrdequeue(m, mh); error(Ebadmsg); } /* @@ -755,13 +789,12 @@ mntxmit(Mnt *m, Mnthdr *mh) if(tag == mh->thdr.tag){ /* it's mine */ q->reader = 0; if(w = q->writer){ /* advance a writer to reader */ + mntwunlink(q, w); q->reader = w->p; - q->writer = w->next; - if(q->writer) - q->writer->prev = 0; w->readreply = 1; wakeup(&w->r); } + mh->active = 0; qunlock(q); qlocked = 0; goto Respond; @@ -774,10 +807,8 @@ mntxmit(Mnt *m, Mnthdr *mh) goto Read; } w = &mnthdralloc.arena[tag]; - if(!w->writing){ - print("reply not writing\n"); + if(w->flushing || !w->active) /* nothing to do; mntflush will clean up */ goto Read; - } t = mh->mbr; mh->mbr = w->mbr; w->mbr = t; @@ -791,14 +822,13 @@ mntxmit(Mnt *m, Mnthdr *mh) /* put self in queue */ mh->next = q->writer; mh->prev = 0; - mh->writing = 1; if(q->writer) q->writer->prev = mh; q->writer = mh; qunlock(q); qlocked = 0; if(waserror()){ /* interrupted sleep */ - mnterrdequeue(q, mh); + mnterrdequeue(m, mh); nexterror(); } sleep(&mh->r, mntreadreply, mh); @@ -807,6 +837,7 @@ mntxmit(Mnt *m, Mnthdr *mh) qlocked = 1; if(q->reader == u->p) /* i got promoted */ goto Read; + mh->active = 0; qunlock(q); qlocked = 0; goto Respond; @@ -814,11 +845,14 @@ mntxmit(Mnt *m, Mnthdr *mh) Respond: mqfree(q); - poperror(); + poperror(); /* 2 */ if(mh->rhdr.type == Rerror){ if(m->mntpt) errors(mh->rhdr.ename); error(Eshutdown); + }else if(mh->rhdr.type != mh->thdr.type+1){ + print("bad type %d not %d in mntxmit\n", mh->rhdr.type, mh->thdr.type+1); + error(Ebadmsg); } /* * Copy out on read @@ -830,7 +864,7 @@ mntxmit(Mnt *m, Mnthdr *mh) } mbfree(mh->mbr); mbfree(mbw); - poperror(); + poperror(); /* 1 */ } mntdump() diff --git a/gnot/proc.c b/gnot/proc.c index 4ce3775787b47b067f8194f7b33a332c181d179a..28508d25928f0865c7a1abf43cccee35283d0e9b 100644 --- a/gnot/proc.c +++ b/gnot/proc.c @@ -281,9 +281,6 @@ 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; @@ -350,7 +347,7 @@ sleep1(Rendez *r, int (*f)(void*), void *arg) */ p = u->p; if(r->p) - print("double sleep %d %d\n", r->p->pid, p->pid); + print("double sleep %lux %d %d\n", r, r->p->pid, p->pid); p->r = r; p->wokeup = 0; p->state = Wakeme; @@ -567,50 +564,7 @@ pexit(char *s, int freemem) 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(&c->debug); /* sched() can't do this */ diff --git a/gnot/sysproc.c b/gnot/sysproc.c index f2433b2a33d3a5fbef0cc1e891c58efe1bdc9ed9..df6fb6b55a2c3fecea42f9f5a5b50fb14a41affb 100644 --- a/gnot/sysproc.c +++ b/gnot/sysproc.c @@ -111,20 +111,6 @@ 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 */ @@ -133,7 +119,6 @@ sysfork(ulong *arg) restore(); return 0; } - p->pop = u->p; p->parent = u->p; p->parentpid = u->p->pid; p->pgrp = u->p->pgrp; diff --git a/port/devmnt.c b/port/devmnt.c index 101194078f980ed3d07db23b2ec23204256f283f..b08e237c8f4571d8a5230ae83608d3619a1c76c0 100644 --- a/port/devmnt.c +++ b/port/devmnt.c @@ -49,7 +49,8 @@ struct Mnthdr { Mnthdr *next; /* in free list or writers list */ Mnthdr *prev; /* in writers list only */ - int writing; /* flag: in writers list */ + short active; + short flushing; /* a Tflush has been sent */ Fcall thdr; Fcall rhdr; Rendez r; @@ -122,6 +123,7 @@ loop: lock(&mnthdralloc); if(mh = mnthdralloc.free){ /* assign = */ mnthdralloc.free = mh->next; + mh->flushing = 0; unlock(&mnthdralloc); return mh; } @@ -138,6 +140,9 @@ loop: void mhfree(Mnthdr *mh) { + if(mh->flushing) + return; + mh->active = 0; lock(&mnthdralloc); mh->next = mnthdralloc.free; mnthdralloc.free = mh; @@ -601,22 +606,49 @@ mntwunlink(MntQ *q, Mnthdr *w) /* queue is locked and w is a writer */ if(q->writer) q->writer->prev = 0; } - w->writing = 0; } +/* + * m->q is unlocked. Send Tflush message to flush omh->tag. + * Cut off all errors. Caller will free omh + */ void -mnterrdequeue(MntQ *q, Mnthdr *mh) /* queue is unlocked */ +mntflush(Mnt *m, Mnthdr *omh) /* queue is unlocked */ +{ + Mnthdr *mh; + + if(omh->thdr.type == Tflush) + return; + + mh = mhalloc(); + if(waserror()){ + omh->flushing = 0; + mhfree(mh); + return; /* no more errors please */ + } + mh->thdr.type = Tflush; + mh->thdr.oldtag = omh->thdr.tag; + mntxmit(m, mh); + omh->flushing = 0; + mhfree(mh); + poperror(); +} + +void +mnterrdequeue(Mnt *m, Mnthdr *mh) /* queue is unlocked */ { Mnthdr *w; + MntQ *q; + mh->flushing = 1; + q = m->q; qlock(q); /* take self from queue if necessary */ if(q->reader == u->p){ /* advance a writer to reader */ w = q->writer; if(w){ + mntwunlink(q, w); q->reader = w->p; - q->writer = w->next; - q->writer->prev = 0; wakeup(&w->r); }else{ q->reader = 0; @@ -625,7 +657,7 @@ mnterrdequeue(MntQ *q, Mnthdr *mh) /* queue is unlocked */ }else mntwunlink(q, mh); qunlock(q); - + mntflush(m, mh); } int @@ -641,11 +673,11 @@ mntxmit(Mnt *m, Mnthdr *mh) Mntbuf *mbw, *t; Mnthdr *w, *ow; MntQ *q; - int qlocked, tag; + int qlocked, tag, written; mh->mbr = mballoc(); mbw = mballoc(); - if(waserror()){ + if(waserror()){ /* 1 */ mbfree(mh->mbr); mbfree(mbw); nexterror(); @@ -663,7 +695,7 @@ mntxmit(Mnt *m, Mnthdr *mh) goto Normal; incref(q); - if(waserror()){ + if(waserror()){ /* 2 */ mqfree(q); nexterror(); } @@ -677,7 +709,7 @@ mntxmit(Mnt *m, Mnthdr *mh) */ n = (*devtab[q->msg->type].read)(q->msg, mh->mbr->buf, BUFSIZE); mqfree(q); - poperror(); + poperror(); /* 2 */ if(convM2S(mh->mbr->buf, &mh->rhdr, n) == 0){ print("format error in mntxmit\n"); @@ -712,7 +744,7 @@ mntxmit(Mnt *m, Mnthdr *mh) memcpy(mh->thdr.data, mh->rhdr.data, mh->rhdr.count); mbfree(mh->mbr); mbfree(mbw); - poperror(); + poperror(); /* 1 */ return; Normal: @@ -720,13 +752,14 @@ mntxmit(Mnt *m, Mnthdr *mh) incref(q); qlock(q); qlocked = 1; - if(waserror()){ + if(waserror()){ /* 2 */ if(qlocked) qunlock(q); mqfree(q); nexterror(); } mh->readreply = 0; + mh->active = 1; if((*devtab[q->msg->type].write)(q->msg, mbw->buf, n) != n){ print("short write in mntxmit\n"); error(Eshortmsg); @@ -736,14 +769,15 @@ mntxmit(Mnt *m, Mnthdr *mh) Read: qunlock(q); qlocked = 0; - if(waserror()){ - mnterrdequeue(q, mh); + if(waserror()){ /* 3 */ + mnterrdequeue(m, mh); nexterror(); } n = (*devtab[q->msg->type].read)(q->msg, mh->mbr->buf, BUFSIZE); - poperror(); + poperror(); /* 3 */ if(convM2S(mh->mbr->buf, &mh->rhdr, n) == 0){ - mnterrdequeue(q, mh); + print("bad reply message\n"); + mnterrdequeue(m, mh); error(Ebadmsg); } /* @@ -755,13 +789,12 @@ mntxmit(Mnt *m, Mnthdr *mh) if(tag == mh->thdr.tag){ /* it's mine */ q->reader = 0; if(w = q->writer){ /* advance a writer to reader */ + mntwunlink(q, w); q->reader = w->p; - q->writer = w->next; - if(q->writer) - q->writer->prev = 0; w->readreply = 1; wakeup(&w->r); } + mh->active = 0; qunlock(q); qlocked = 0; goto Respond; @@ -774,10 +807,8 @@ mntxmit(Mnt *m, Mnthdr *mh) goto Read; } w = &mnthdralloc.arena[tag]; - if(!w->writing){ - print("reply not writing\n"); + if(w->flushing || !w->active) /* nothing to do; mntflush will clean up */ goto Read; - } t = mh->mbr; mh->mbr = w->mbr; w->mbr = t; @@ -791,14 +822,13 @@ mntxmit(Mnt *m, Mnthdr *mh) /* put self in queue */ mh->next = q->writer; mh->prev = 0; - mh->writing = 1; if(q->writer) q->writer->prev = mh; q->writer = mh; qunlock(q); qlocked = 0; if(waserror()){ /* interrupted sleep */ - mnterrdequeue(q, mh); + mnterrdequeue(m, mh); nexterror(); } sleep(&mh->r, mntreadreply, mh); @@ -807,6 +837,7 @@ mntxmit(Mnt *m, Mnthdr *mh) qlocked = 1; if(q->reader == u->p) /* i got promoted */ goto Read; + mh->active = 0; qunlock(q); qlocked = 0; goto Respond; @@ -814,11 +845,14 @@ mntxmit(Mnt *m, Mnthdr *mh) Respond: mqfree(q); - poperror(); + poperror(); /* 2 */ if(mh->rhdr.type == Rerror){ if(m->mntpt) errors(mh->rhdr.ename); error(Eshutdown); + }else if(mh->rhdr.type != mh->thdr.type+1){ + print("bad type %d not %d in mntxmit\n", mh->rhdr.type, mh->thdr.type+1); + error(Ebadmsg); } /* * Copy out on read @@ -830,7 +864,7 @@ mntxmit(Mnt *m, Mnthdr *mh) } mbfree(mh->mbr); mbfree(mbw); - poperror(); + poperror(); /* 1 */ } mntdump() diff --git a/port/proc.c b/port/proc.c index fd0516e8d76cf45703b11c5125f6e3cc6026e687..c0eed779a045fcfa622a32e940282fc8e5ac4354 100644 --- a/port/proc.c +++ b/port/proc.c @@ -166,9 +166,6 @@ 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; @@ -477,50 +474,7 @@ pexit(char *s, int freemem) 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(&c->debug); /* sched() can't do this */ diff --git a/port/sysproc.c b/port/sysproc.c index b1db49b0f2a31655ba8160532160e810c63e71d6..2213524629cd442fb105936ffd6c223885974010 100644 --- a/port/sysproc.c +++ b/port/sysproc.c @@ -110,20 +110,6 @@ 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 */ @@ -135,7 +121,6 @@ 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 dae2f894f4928e1b1d8b7f23e7addc89ae418ae3..a9d0e6e4a8a00bcf2af7d36a0c50095d5c1ff3f7 100644 --- a/power/dat.h +++ b/power/dat.h @@ -316,10 +316,6 @@ 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 */ ulong waitmsg; @@ -339,7 +335,7 @@ struct Proc }; -#define NERR 15 +#define NERR 20 #define NFD 100 #define NNOTE 5 struct User