From 36c043ee48e7c920c3aa367b10c4a55495bc7907 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Fri, 28 Sep 1990 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1990-09-28 --- gnot/dat.h | 15 -------- gnot/main.c | 1 - gnot/malloc.h | 15 ++++++++ gnot/mmu.c | 39 -------------------- gnot/proc.c | 1 - gnot/stream.c | 63 +++++++++++++++++-------------- gnot/sturp.c | 98 +++++++++++++++++++++++++++++++------------------ gnot/sysfile.c | 6 +-- gnot/sysproc.c | 2 - port/devcons.c | 37 ++++++++++++------- port/devkprof.c | 2 + port/pgrp.c | 1 + power/main.c | 1 - 13 files changed, 142 insertions(+), 139 deletions(-) create mode 100644 gnot/malloc.h diff --git a/gnot/dat.h b/gnot/dat.h index 579dfe2f0903ee91a847a971791a6060c514c2b5..cb556d62fe0877a857459347efbcf47ec2c301ea 100644 --- a/gnot/dat.h +++ b/gnot/dat.h @@ -339,20 +339,6 @@ struct Proc ulong pc; /* DEBUG only */ }; -struct MMU -{ - ulong va; - ulong pa; - int pid; -}; - -#define NMMU 16 -struct MMUCache -{ - ulong next; - MMU mmu[NMMU]; -}; - #define NERR 15 #define NNOTE 5 #define NFD 100 @@ -376,7 +362,6 @@ struct User short nnote; short notified; /* sysnoted is due */ int (*notify)(void*, char*); - MMUCache mc; void *ureg; }; diff --git a/gnot/main.c b/gnot/main.c index b33e1ba9444ed43ea825f818b268c4ae1215b2ce..4498ddafc7d7677942e30b622d10a7891e6a82af 100644 --- a/gnot/main.c +++ b/gnot/main.c @@ -155,7 +155,6 @@ userinit(void) k = kmap(p->upage); up = (User*)VA(k); up->p = p; - up->mc.next = 0; kunmap(k); /* diff --git a/gnot/malloc.h b/gnot/malloc.h new file mode 100644 index 0000000000000000000000000000000000000000..82d145d1af301580f5d152abcfb423b117978fea --- /dev/null +++ b/gnot/malloc.h @@ -0,0 +1,15 @@ +struct tbl_entry { + struct tbl_entry *next; /* free list */ + int *data; /* data */ +}; + +struct table { + int size; /* # entries */ + struct tbl_entry *entries; /* the entries */ + struct tbl_entry *free; /* the free list */ +}; + +void *tbl_alloc(struct table *, int); +void tbl_free(struct table *, void *); +int tbl_index(struct table *, void *); +void *tbl_data(struct table *, int); diff --git a/gnot/mmu.c b/gnot/mmu.c index 26630a90056dd7a8fa9dc4740ff14fab99f76062..329988e8c210d393904c101550c7e63f0226023b 100644 --- a/gnot/mmu.c +++ b/gnot/mmu.c @@ -12,17 +12,6 @@ struct KMap arena[4*1024*1024/BY2PG]; /* kernel mmu maps up to 4MB */ }kmapalloc; -void -putxmmu(ulong tlbvirt, ulong tlbphys, int pid) -{ - if(pid != u->p->pid) - panic("putxmmu %ld %ld\n", pid, u->p->pid); - if(tlbvirt&KZERO) - panic("putmmu"); - tlbphys |= VTAG(tlbvirt)<<24; - UMAP[(tlbvirt&0x003FE000L)>>2] = tlbphys; -} - /* * Called splhi, not in Running state */ @@ -39,18 +28,6 @@ mapstack(Proc *p) putkmmu(tlbvirt, tlbphys); flushmmu(); u = (User*)USERADDR; - - /* - * preload the MMU with the last (up to) NMMU user entries - * previously faulted into it for this process. - */ - if(u->mc.next >= NMMU){ - u->mc.next &= NMMU - 1; - for(i = u->mc.next; i < NMMU; i++) - putxmmu(u->mc.mmu[i].va, u->mc.mmu[i].pa, u->mc.mmu[i].pid); - } - for(i = 0; i < u->mc.next; i++) - putxmmu(u->mc.mmu[i].va, u->mc.mmu[i].pa, u->mc.mmu[i].pid); } void @@ -67,14 +44,6 @@ putmmu(ulong tlbvirt, ulong tlbphys) { if(tlbvirt&KZERO) panic("putmmu"); - if(u){ - MMU *mp; - mp = &(u->mc.mmu[u->mc.next&(NMMU-1)]); - mp->pa = tlbphys; - mp->va = tlbvirt; - mp->pid = u->p->pid; - u->mc.next++; - } tlbphys |= VTAG(tlbvirt)<<24; UMAP[(tlbvirt&0x003FE000L)>>2] = tlbphys; } @@ -87,14 +56,6 @@ flushmmu(void) *PARAM |= TLBFLUSH_; } -void -clearmmucache(void) -{ - if(u == 0) - panic("flushmmucache"); - u->mc.next = 0; -} - void kmapinit(void) { diff --git a/gnot/proc.c b/gnot/proc.c index e34209871a6f61894f1dd157295a92367d01e226..800806ea5ec08adcf33dec33ba27919a502bdc83 100644 --- a/gnot/proc.c +++ b/gnot/proc.c @@ -621,7 +621,6 @@ kproc(char *name, void (*func)(void *), void *arg) /* * Save time: only copy u-> data and useful stack */ - clearmmucache(); memcpy(up, u, sizeof(User)); n = USERADDR+BY2PG - (ulong)&lastvar; n = (n+32) & ~(BY2WD-1); /* be safe & word align */ diff --git a/gnot/stream.c b/gnot/stream.c index a457b7622d47246f1688b8cc2ecf50767fb36826..62c9881daa2911c7558684ea3a3cdee8d4f3177d 100644 --- a/gnot/stream.c +++ b/gnot/stream.c @@ -877,6 +877,28 @@ stringread(Chan *c, uchar *buf, long n, char *str) return n; } +/* + * return the stream id + */ +long +streamctlread(Chan *c, void *vbuf, long n) +{ + uchar *buf = vbuf; + char num[32]; + Stream *s; + + s = c->stream; + if(STREAMTYPE(c->qid) == Sctlqid){ + sprint(num, "%d", s->id); + return stringread(c, buf, n, num); + } else { + if(CHDIR & c->qid) + return devdirread(c, vbuf, n, 0, 0, streamgen); + else + panic("streamctlread"); + } +} + /* * return true if there is an output buffer available */ @@ -895,28 +917,16 @@ streamread(Chan *c, void *vbuf, long n) Block *bp; Stream *s; Queue *q; - long rv = 0; - int left, i, x; + int left, i; uchar *buf = vbuf; - char num[32]; - s = c->stream; - switch(STREAMTYPE(c->qid)){ - case Sdataqid: - break; - case Sctlqid: - sprint(num, "%d", s->id); - return stringread(c, buf, n, num); - default: - if(CHDIR & c->qid) - return devdirread(c, vbuf, n, 0, 0, streamgen); - else - panic("streamread"); - } + if(STREAMTYPE(c->qid) != Sdataqid) + return streamctlread(c, vbuf, n); /* * one reader at a time */ + s = c->stream; qlock(&s->rdlock); if(waserror()){ qunlock(&s->rdlock); @@ -974,10 +984,15 @@ streamread(Chan *c, void *vbuf, long n) * This routing is entrered with s->wrlock'ed and must unlock. */ static long -streamctlwrite(Stream *s, void *a, long n) +streamctlwrite(Chan *c, void *a, long n) { Qinfo *qi; Block *bp; + Stream *s; + + if(STREAMTYPE(c->qid) != Sctlqid) + panic("streamctlwrite %lux", c->qid); + s = c->stream; /* * package @@ -1040,15 +1055,8 @@ streamwrite(Chan *c, void *a, long n, int docopy) /* * decode the qid */ - switch(STREAMTYPE(c->qid)){ - case Sdataqid: - break; - case Sctlqid: - n = streamctlwrite(s, a, n); - goto out; - default: - panic("bad stream qid\n"); - } + if(STREAMTYPE(c->qid) != Sdataqid) + return streamctlwrite(c, a, n); /* * No writes allowed on hungup channels @@ -1057,7 +1065,7 @@ streamwrite(Chan *c, void *a, long n, int docopy) if(q->other->flag & QHUNGUP) error(0, Ehungup); - if((GLOBAL(a) && !docopy) || n==0){ + if(!docopy && GLOBAL(a)){ /* * `a' is global to the whole system, just create a * pointer to it and pass it on. @@ -1094,7 +1102,6 @@ streamwrite(Chan *c, void *a, long n, int docopy) } } } -out: return n; } diff --git a/gnot/sturp.c b/gnot/sturp.c index 4bc074231d351eb881177362895c678f56f318a4..f2195a5e2eec616f0d096d707ede19c6ee976f88 100644 --- a/gnot/sturp.c +++ b/gnot/sturp.c @@ -33,6 +33,7 @@ struct urpstat { } urpstat; struct Urp { + QLock; short state; /* flags */ Rendez r; /* process waiting for close */ @@ -51,11 +52,11 @@ struct Urp { int maxout; /* maximum outstanding unacked blocks */ int maxblock; /* max block size */ int next; /* next block to send */ - int tofree; /* first block to be freed (unacked is first not to) */ int unechoed; /* first unechoed block */ int unacked; /* first unacked block */ int nxb; /* next xb to use */ Block *xb[8]; /* the xmit window buffer */ + QLock xl[8]; ulong timer; /* timeout for xmit */ int rexmit; @@ -96,7 +97,6 @@ struct Urp { #define CLOSING 0x10 Urp *urp; -Lock urpalloc; /* * predeclared @@ -112,7 +112,7 @@ static void sendblock(Urp*, int); static void rcvack(Urp*, int); static void flushinput(Urp*); static void sendctl(Urp*, int); -static void sendack(Urp*, int); +static void sendack(Urp*); static void sendrej(Urp*); static void initoutput(Urp*, int); static void initinput(Urp*, int); @@ -139,14 +139,15 @@ urpopen(Queue *q, Stream *s) /* * find a free urp structure */ - lock(&urpalloc); - for(up = urp; up < &urp[conf.nurp]; up++) + for(up = urp; up < &urp[conf.nurp]; up++){ + qlock(up); if(up->state == 0) break; + qunlock(up); + } if(up == &urp[conf.nurp]){ q->ptr = 0; WR(q)->ptr = 0; - unlock(&urpalloc); error(0, Egreg); } @@ -154,7 +155,7 @@ urpopen(Queue *q, Stream *s) up->rq = q; up->wq = q->other; up->state = OPEN; - unlock(&urpalloc); + qunlock(up); initinput(up, 0); initoutput(up, 0); @@ -339,8 +340,12 @@ urpciput(Queue *q, Block *bp) case SEQ+0: case SEQ+1: case SEQ+2: case SEQ+3: case SEQ+4: case SEQ+5: case SEQ+6: case SEQ+7: + qlock(&up->ack); + i = ctl & Nmask; + if(!QFULL(q->next)) + sendctl(up, up->lastecho = ECHO+i); up->iseq = i; - sendack(up, ECHO); + qunlock(&up->ack); break; } } @@ -510,8 +515,11 @@ urpiput(Queue *q, Block *bp) /* * acknowledge receipt */ + qlock(&up->ack); up->iseq = i; - sendack(up, ECHO); + if(!QFULL(q->next)) + sendctl(up, up->lastecho = ECHO|i); + qunlock(&up->ack); break; } } @@ -591,7 +599,8 @@ output(Urp *up) int n; int i; - qlock(&up->xmit); + if(!canqlock(&up->xmit)) + return; if(waserror()){ print("urp output error\n"); @@ -655,18 +664,6 @@ output(Urp *up) goto out; } - /* - * free any blocks that can be freed - */ - while(up->tofree != up->unacked){ - if(up->xb[up->tofree] == 0) - urpvomit("output2", up); - else - freeb(up->xb[up->tofree]); - up->xb[up->tofree] = 0; - up->tofree = NEXT(up->tofree); - } - /* * if there's a window open, push some blocks out * @@ -674,8 +671,16 @@ output(Urp *up) * blocks. */ while(WINDOW(up)>0 && up->next!=up->nxb){ - sendblock(up, up->next); + i = up->next; + qlock(&up->xl[i]); + if(waserror()){ + qunlock(&up->xl[i]); + nexterror(); + } + sendblock(up, i); + qunlock(&up->xl[i]); up->next = NEXT(up->next); + poperror(); } out: qunlock(&up->xmit); @@ -708,10 +713,9 @@ static void sendrej(Urp *up) { Queue *q = up->wq; - flushinput(up); qlock(&up->ack); - if(!QFULL(up->rq->next) && (up->lastecho&~Nmask)==ECHO){ + if((up->lastecho&~Nmask) == ECHO){ DPRINT("REJ %d\n", up->iseq); sendctl(up, up->lastecho = REJ|up->iseq); } @@ -722,13 +726,31 @@ sendrej(Urp *up) * send an acknowledge */ static void -sendack(Urp *up, int type) +sendack(Urp *up) { Block *bp; - qlock(&up->ack); - if(!QFULL(up->rq->next) && (up->lastecho&Nmask)!=up->iseq) - sendctl(up, up->lastecho = type|up->iseq); + /* + * check the precondition for acking + */ + if(QFULL(up->rq->next) || (up->lastecho&Nmask)==up->iseq) + return; + + if(!canqlock(&up->ack)) + return; + + /* + * check again now that we've locked + */ + if(QFULL(up->rq->next) || (up->lastecho&Nmask)==up->iseq){ + qunlock(&up->ack); + return; + } + + /* + * send the ack + */ + sendctl(up, up->lastecho = ECHO|up->iseq); qunlock(&up->ack); } @@ -792,8 +814,16 @@ rcvack(Urp *up, int msg) * release any acknowledged blocks */ if(IN(seqno, up->unacked, up->next)){ - for(; up->unacked != next; up->unacked = NEXT(up->unacked)) + for(; up->unacked != next; up->unacked = NEXT(up->unacked)){ i = up->unacked; + qlock(&up->xl[i]); + if(up->xb[i]) + freeb(up->xb[i]); + else + urpvomit("rcvack", up); + up->xb[i] = 0; + qunlock(&up->xl[i]); + } } switch(msg & 0370){ @@ -849,7 +879,6 @@ initoutput(Urp *up, int window) { int i; - qlock(&up->xmit); /* * set output window */ @@ -862,7 +891,6 @@ initoutput(Urp *up, int window) /* * set sequence varialbles */ - up->tofree = 1; up->unechoed = 1; up->unacked = 1; up->next = 1; @@ -873,9 +901,11 @@ initoutput(Urp *up, int window) * free any outstanding blocks */ for(i = 0; i < 8; i++){ + qlock(&up->xl[i]); if(up->xb[i]) freeb(up->xb[i]); up->xb[i] = 0; + qunlock(&up->xl[i]); } /* @@ -883,7 +913,6 @@ initoutput(Urp *up, int window) */ up->state |= INITING; up->timer = NOW + MSrexmit; - qunlock(&up->xmit); sendctl(up, INIT1); } @@ -916,7 +945,6 @@ todo(void *arg) return (up->state&INITING) ? NOW>up->timer /* time to INIT1 */ : ((up->unacked!=up->next && NOW>up->timer) /* time to ENQ */ - || up->tofree != up->unacked || WINDOW(up)>0 && up->next!=up->nxb || (!QFULL(up->rq->next) && up->iseq!=(up->lastecho&7))); /* time to ECHO */ } @@ -938,7 +966,7 @@ urpkproc(void *arg) if(up->state & HUNGUP) break; if(!QFULL(up->rq->next)) - sendack(up, ECHO); + sendack(up); output(up); sleep(&up->rq->r, todo, up); } diff --git a/gnot/sysfile.c b/gnot/sysfile.c index 25d4d64c4891ebe921e8572d48c4e7540e9dceac..231b7ea5600a596318e6a0663d32feefb5b3a909 100644 --- a/gnot/sysfile.c +++ b/gnot/sysfile.c @@ -31,12 +31,12 @@ fdtochan(int fd, int mode) if(fd<0 || NFD<=fd || (c=u->fd[fd])==0) error(0, Ebadfd); - if(mode<0 || c->mode == 2) + if(mode<0 || c->mode==ORDWR) return c; - if((mode&16) && c->mode==0) + if((mode&OTRUNC) && c->mode==OREAD) err: error(0, Ebadusefd); - if((mode&~16) != c->mode) + if((mode&~OTRUNC) != c->mode) goto err; return c; } diff --git a/gnot/sysproc.c b/gnot/sysproc.c index bad416d4d1ce678a93902582e4cb0c6ed3332d69..6c76c2bca961311f8bc90c24fbea7f2eb18428d7 100644 --- a/gnot/sysproc.c +++ b/gnot/sysproc.c @@ -41,7 +41,6 @@ sysfork(ulong *arg) /* * Save time: only copy u-> data and useful stack */ - clearmmucache(); memcpy((void*)upa, u, sizeof(User)); n = USERADDR+BY2PG - (ulong)&lastvar; n = (n+32) & ~(BY2WD-1); /* be safe & word align */ @@ -362,7 +361,6 @@ sysexec(ulong *arg) unlock(o); flushmmu(); - clearmmucache(); ((Ureg*)UREGADDR)->pc = exec.entry; sp = (ulong*)(USTKTOP - ssize); *--sp = nargs; diff --git a/port/devcons.c b/port/devcons.c index 2e0f6391a5df0239eca7f9f45ecd8724693e768c..ff2efdde14274287f3e4c57dd55e5727a495a64e 100644 --- a/port/devcons.c +++ b/port/devcons.c @@ -36,6 +36,18 @@ struct IOQ{ IOQ kbdq; /* qlock to getc; interrupt putc's */ IOQ lineq; /* lock to getc; interrupt putc's */ +#define SYSLOGMAGIC 0x23456789 +#define SYSLOG ((Syslog *)(UNCACHED | KZERO | 0x1B00)) +typedef struct Syslog Syslog; +struct Syslog +{ + ulong magic; + char *start; + char *next; + char buf[2*BY2PG - 3*BY2WD]; +}; + + void printinit(void) { @@ -55,6 +67,7 @@ printinit(void) unlock(&lineq); duartinit(); + sysloginit(); /* must be at the end of printinit */ } /* @@ -164,12 +177,15 @@ panic(char *fmt, ...) { char buf[PRINTSIZE]; int n; + Syslog *s; strcpy(buf, "panic: "); n = doprint(buf+7, buf+sizeof(buf), fmt, (&fmt+1)) - buf; buf[n] = '\n'; putstrn(buf, n+1); dumpstack(); + s = SYSLOG; + print("start/next is %lux/%lux\n", s->start, s->next); exit(); } @@ -598,30 +614,23 @@ consuserstr(Error *e, char *buf) /* * kernel based system log, passed between crashes */ -#define SYSLOGMAGIC 0x23456789 -#define SYSLOG ((Syslog *)(UNCACHED | KZERO | 0x1B00)) -typedef struct Syslog Syslog; -struct Syslog -{ - ulong magic; - char *start; - char *next; - char buf[BY2PG - 3*BY2WD]; -}; - void sysloginit(void) { Syslog *s; - char *p; + char *start, *next; s = SYSLOG; - if(s->magic!=SYSLOGMAGIC || s->next>=&s->buf[sizeof(s->buf)] - || s->start>=&s->buf[sizeof(s->buf)] || s->nextbuf){ + next = s->next; + start = s->start; + if(s->magic!=SYSLOGMAGIC || next>=&s->buf[sizeof(s->buf)] + || start>=&s->buf[sizeof(s->buf)] || nextbuf){ s->start = s->buf; s->next = s->buf; s->magic = SYSLOGMAGIC; } + print("start/next is %lux/%lux was %lux/%lux\n", s->start, s->next, + start, next); } void diff --git a/port/devkprof.c b/port/devkprof.c index bf76eef63e35439700dc55daedf1104445641d84..fe531eae292c5666f1014db79faf53f90d6dd190 100644 --- a/port/devkprof.c +++ b/port/devkprof.c @@ -157,6 +157,8 @@ kprofwrite(Chan *c, char *a, long n) void kproftimer(ulong pc) { + extern ulong splpc; + timerbuf[0]++; if(KTZERO<=pc && pcnext; m->ref = 1; + m->next = 0; m->mountid = ++mountalloc.mountid; unlock(&mountalloc); return m; diff --git a/power/main.c b/power/main.c index de8510a21a073b10a5749feb7adc367e7a4a230d..587e9ef370160b4175f16c0b314e7e777093f3f2 100644 --- a/power/main.c +++ b/power/main.c @@ -47,7 +47,6 @@ main(void) active.machs = 1; confinit(); arginit(); - sysloginit(); lockinit(); printinit(); tlbinit();