From 638268bdde463182044b2a62a3aeec02b5ab597d Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Tue, 14 Aug 1990 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1990-08-14 --- gnot/chan.c | 2 +- gnot/dat.h | 2 ++ gnot/devcons.c | 69 +++++++++++++++++++++++++++++++++++--------------- gnot/devdk.c | 14 +++++++--- gnot/fault.c | 6 ++--- gnot/fns.h | 1 + gnot/mem.h | 10 +++++--- gnot/page.c | 67 ++++++++++++++++++------------------------------ gnot/screen.c | 3 +-- gnot/sturp.c | 4 +-- port/devbit.c | 14 ++++++++++ port/fault.c | 3 +-- port/page.c | 67 ++++++++++++++++++------------------------------ port/sturp.c | 5 ++-- 14 files changed, 140 insertions(+), 127 deletions(-) diff --git a/gnot/chan.c b/gnot/chan.c index 639223fe60e2b844e264cb43deebab12cf47ab96..dcaf98368bf6f06c8d8ab9ac410f9e49c4de36a8 100644 --- a/gnot/chan.c +++ b/gnot/chan.c @@ -447,7 +447,7 @@ namec(char *name, int amode, int omode, ulong perm) mntok = 0; if(!((ulong)name & KZERO)) validaddr((ulong)(name+1), 2, 0); - if(name[1]=='|' || ('A'<=name[1] && name[1]<='Z')) + if(name[1]=='|' || name[1]=='M') error(0, Enonexist); t = devno(name[1], 1); if(t == -1) diff --git a/gnot/dat.h b/gnot/dat.h index 42dab4ef894883bdef51085eef833deaaa14108a..9461f44c71096810549a4caf0123243dad2f2d64 100644 --- a/gnot/dat.h +++ b/gnot/dat.h @@ -80,6 +80,8 @@ struct Alarm }; #define CHDIR 0x80000000L +#define CHAPPEND 0x40000000L +#define CHEXCL 0x20000000L #define QPATH 0x0000FFFFL struct Chan { diff --git a/gnot/devcons.c b/gnot/devcons.c index 1a6c1f36f9322ca398367b8ec6680a05d9d64dd7..50b6d4e1ea066fca79fb033b8ebe58e3dc5177ba 100644 --- a/gnot/devcons.c +++ b/gnot/devcons.c @@ -17,7 +17,7 @@ static struct typedef struct IOQ IOQ; -#define NQ 1024 +#define NQ 2048 struct IOQ{ union{ Lock; @@ -100,8 +100,9 @@ putstrn(char *str, long n) } int -cangetc(IOQ *q) +cangetc(void *arg) { + IOQ *q = (IOQ *)arg; int n = q->in - q->out; if (n < 0) n += sizeof(q->buf); @@ -109,14 +110,16 @@ cangetc(IOQ *q) } int -canputc(IOQ *q) +canputc(void *arg) { + IOQ *q = (IOQ *)arg; return sizeof(q->buf)-cangetc(q)-1; } int -isbrkc(IOQ *q) +isbrkc(void *arg) { + IOQ *q = (IOQ *)arg; uchar *p; for(p=q->out; p!=q->in; ){ @@ -352,21 +355,25 @@ enum{ Qtime, Quser, Qklog, + Qmsec, + Qclock, }; Dirtab consdir[]={ - "cons", Qcons, 0, 0600, - "cputime", Qcputime, 72, 0600, - "null", Qnull, 0, 0600, - "pgrpid", Qpgrpid, 12, 0600, - "pid", Qpid, 12, 0600, - "ppid", Qppid, 12, 0600, - "rcons", Qrcons, 0, 0600, - "rs232", Qrs232, 0, 0600, - "rs232ctl", Qrs232ctl, 0, 0600, - "time", Qtime, 12, 0600, - "user", Quser, 0, 0600, - "klog", Qklog, 0, 0400, + "cons", Qcons, 0, 0600, + "cputime", Qcputime, 6*NUMSIZE, 0600, + "null", Qnull, 0, 0600, + "pgrpid", Qpgrpid, NUMSIZE, 0600, + "pid", Qpid, NUMSIZE, 0600, + "ppid", Qppid, NUMSIZE, 0600, + "rcons", Qrcons, 0, 0600, + "rs232", Qrs232, 0, 0600, + "rs232ctl", Qrs232ctl, 0, 0600, + "time", Qtime, NUMSIZE, 0600, + "user", Quser, 0, 0600, + "klog", Qklog, 0, 0400, + "msec", Qmsec, NUMSIZE, 0400, + "clock", Qclock, 2*NUMSIZE, 0400, }; #define NCONS (sizeof consdir/sizeof(Dirtab)) @@ -520,7 +527,7 @@ consread(Chan *c, void *buf, long n) nexterror(); } while(!cangetc(&lineq)){ - sleep(&kbdq.r, (int(*)(void*))isbrkc, &kbdq); + sleep(&kbdq.r, isbrkc, &kbdq); do{ lock(&lineq); ch = getc(&kbdq); @@ -567,12 +574,13 @@ consread(Chan *c, void *buf, long n) nexterror(); } while(!cangetc(&rs232iq)) - sleep(&rs232iq.r, (int(*)(void*))cangetc, &rs232iq); + sleep(&rs232iq.r, cangetc, &rs232iq); for(i=0; ioffset, buf, n, u->p->parentpid, NUMSIZE); case Qtime: - return readnum(c->offset, buf, n, boottime+TK2SEC(MACHP(0)->ticks), 12); + return readnum(c->offset, buf, n, boottime+TK2SEC(MACHP(0)->ticks), NUMSIZE); + + case Qmsec: + return readnum(c->offset, buf, n, TK2MS(MACHP(0)->ticks), NUMSIZE); + case Qclock: + k = c->offset; + if(k >= 2*NUMSIZE) + return 0; + if(k+n > 2*NUMSIZE) + n = 2*NUMSIZE - k; + readnum(0, tmp, NUMSIZE, MACHP(0)->ticks, NUMSIZE); + readnum(0, tmp+NUMSIZE, NUMSIZE, HZ, NUMSIZE); + memcpy(buf, tmp+k, n); + return n; case Quser: return readstr(c->offset, buf, n, u->p->pgrp->user); @@ -621,12 +642,13 @@ consread(Chan *c, void *buf, long n) nexterror(); } while(!cangetc(&klogq)) - sleep(&klogq.r, (int(*)(void*))cangetc, &klogq); + sleep(&klogq.r, cangetc, &klogq); for(i=0; i= 0) { while (putc(&rs232oq, *a) < 0) - sleep(&rs232oq.r, (int(*)(void*))canputc, &rs232oq); + sleep(&rs232oq.r, canputc, &rs232oq); a++; if(rs232oq.state == 0){ splhi(); @@ -678,6 +704,7 @@ conswrite(Chan *c, void *va, long n) spllo(); } } + poperror(); qunlock(&rs232oq); break; diff --git a/gnot/devdk.c b/gnot/devdk.c index bacd0cc2f866576bc36e86cc3ffe21e54f078b6c..9e98863a7d1b3e6458f8902d826b3b8219ab4b70 100644 --- a/gnot/devdk.c +++ b/gnot/devdk.c @@ -6,8 +6,9 @@ #include "io.h" #include "errno.h" -#define NOW (MACHP(0)->ticks) -#define DPRINT if(0) +#define DPRINT if(0) /*kprint*/ + +#define NOW (MACHP(0)->ticks) enum { /* @@ -477,6 +478,8 @@ dkmuxconfig(Dk *dp, Block *bp) dp->lines = 16; error(0, Ebadarg); } + DPRINT("dkmuxconfig: ncsc=%d, lines=%d, restart=%d, name=\"%s\"\n", + dp->ncsc, dp->lines, dp->restart, dp->name); /* * open a stream for the csc and push urp onto it @@ -495,7 +498,7 @@ dkmuxconfig(Dk *dp, Block *bp) /* * start a process to deal with it */ - sprint(buf, "csckproc%d", dp->ncsc); + sprint(buf, "csc.%s.%d", dp->name, dp->ncsc); kproc(buf, dkcsckproc, dp); poperror(); @@ -1316,8 +1319,11 @@ dkcsckproc(void *a) /* * tell datakit we've rebooted. It should close all channels. */ - if(dp->restart) + if(dp->restart) { + DPRINT("dkcsckproc: restart %s\n", dp->name); dkmesg(dp, T_ALIVE, D_RESTART, 0, 0); + } + DPRINT("dkcsckproc: closeall %s\n", dp->name); dkmesg(dp, T_CHG, D_CLOSEALL, 0, 0); /* diff --git a/gnot/fault.c b/gnot/fault.c index 0f1cffb263f0022b03a59836520ca421cca5b6e6..69d3ad7a5f2c420724a3a8899a7b1d970d1864b5 100644 --- a/gnot/fault.c +++ b/gnot/fault.c @@ -79,6 +79,7 @@ fault(Ureg *ur, FFrame *f) panic("prefetch pagefault"); }else panic("prefetch format"); + addr &= VAMASK; badvaddr = addr; addr &= ~(BY2PG-1); user = !(ur->sr&SUPER); @@ -99,7 +100,7 @@ fault(Ureg *ur, FFrame *f) } u->p->state = MMUing; dumpregs(ur); - panic("fault"); + panic("fault: 0x%lux", badvaddr); exit(); } s = &u->p->seg[SSEG]; @@ -108,15 +109,14 @@ fault(Ureg *ur, FFrame *f) /* grow stack */ o = s->o; n = o->npte; - lock(o); if(waserror()){ - unlock(o); pprint("can't allocate stack page\n"); goto cant; } growpte(o, (s->maxva-addr)>>PGSHIFT); poperror(); /* stacks grown down, sigh */ + lock(o); memcpy(o->pte+(o->npte-n), o->pte, n*sizeof(PTE)); memset(o->pte, 0, (o->npte-n)*sizeof(PTE)); unlock(o); diff --git a/gnot/fns.h b/gnot/fns.h index 22d3e8bbf508038dc5e9a2e584754c916323e43b..806888e8949b1dc773ec2767f6ed8fb14112e446 100644 --- a/gnot/fns.h +++ b/gnot/fns.h @@ -49,6 +49,7 @@ void flushcpucache(void); void flushmmu(void); void forkmod(Seg*, Seg*, Proc*); void freeb(Block*); +void freenextmod(PTE*); void freepage(Orig*); void freepte(Orig*); void freesegs(int); diff --git a/gnot/mem.h b/gnot/mem.h index 31856aa22c12832a599f3f177cfa9865c920de24..71c8c23fedda73f91652ecac1e2f6f5a28f52677 100644 --- a/gnot/mem.h +++ b/gnot/mem.h @@ -18,10 +18,11 @@ /* * Time */ -#define MS2HZ (1000/60) /* millisec per clock tick */ -#define TK2SEC(t) ((t)/60) /* ticks to seconds */ -#define TK2MS(t) (((t)*1000)/60) /* ticks to milliseconds */ -#define MS2TK(t) (((t)*60)/1000) /* milliseconds to ticks */ +#define HZ (60) /* clock frequency */ +#define MS2HZ (1000/HZ) /* millisec per clock tick */ +#define TK2SEC(t) ((t)/HZ) /* ticks to seconds */ +#define TK2MS(t) (((t)*1000)/HZ) /* ticks to milliseconds */ +#define MS2TK(t) (((t)*HZ)/1000) /* milliseconds to ticks */ /* * SR bits @@ -59,6 +60,7 @@ * MMU */ +#define VAMASK 0xCFFFFFFF /* clear balu bits in address */ #define KUSEG 0x00000000 #define KSEG 0x80000000 diff --git a/gnot/page.c b/gnot/page.c index 469d9db07098a682e4e81f038ab2163c84a2e6dc..6f95ce68f339d3a1fb222e5626f34b5f983a2363 100644 --- a/gnot/page.c +++ b/gnot/page.c @@ -311,16 +311,13 @@ loop: o->mqid = -1; o->mchan = 0; } - lock(o); if(u && u->p && waserror()){ - unlock(o); unlock(&origalloc); nexterror(); } growpte(o, npte); if(u && u->p) poperror(); - unlock(o); unlock(&origalloc); return o; } @@ -515,15 +512,8 @@ segaddr(Seg *s, ulong min, ulong max) * Grow */ /* BUG: check spill onto other segments */ - lock(o); - if(waserror()){ - unlock(o); - nexterror(); - } if(o->va+BY2PG*o->npte < max) growpte(o, (max-o->va)>>PGSHIFT); - unlock(o); - poperror(); s->maxva = max; return 1; } @@ -568,6 +558,10 @@ freepte(Orig *o) /* o is locked */ p->o = 0; } +/* + * o is locked. this will always do a grow; if n<=o->npte someone + * else got here first and we can just return. + */ void growpte(Orig *o, ulong n) { @@ -575,43 +569,30 @@ growpte(Orig *o, ulong n) ulong nfree; lock(&ptealloc); + lock(o); if(o->pte){ - if(o->npte == n){ -if(u && u->p) print("%s: ", u->p->text); - print("growpte pointless\n"); + if(o->npte >= n) goto Return; - } p = (PTEA*)(o->pte - 1); - if(o->npte > n){ - print("growpte shrink"); - goto Return; - nfree = o->npte - n; - p->n -= nfree; - o->npte -= nfree; - p += p->n; - p->o = 0; - p->n = nfree; + n++; + if(p+p->n == ptealloc.free){ + if(!compactpte(o, n - p->n)) + goto Trouble; + p = (PTEA*)(o->pte - 1); + ptealloc.free += n - p->n; }else{ - n++; - if(p+p->n == ptealloc.free){ - if(!compactpte(o, n - p->n)) - goto Trouble; - p = (PTEA*)(o->pte - 1); - ptealloc.free += n - p->n; - }else{ - if(!compactpte(o, n)) - goto Trouble; - p = ptealloc.free; - ptealloc.free += n; - memcpy(p+1, o->pte, o->npte*sizeof(PTE)); - p->o = o; - ((PTEA*)(o->pte-1))->o = 0; - o->pte = p+1; - } - memset(p+1+o->npte, 0, (n-(1+o->npte))*sizeof(PTE)); - p->n = n; - o->npte = n-1; + if(!compactpte(o, n)) + goto Trouble; + p = ptealloc.free; + ptealloc.free += n; + memcpy(p+1, o->pte, o->npte*sizeof(PTE)); + p->o = o; + ((PTEA*)(o->pte-1))->o = 0; + o->pte = p+1; } + memset(p+1+o->npte, 0, (n-(1+o->npte))*sizeof(PTE)); + p->n = n; + o->npte = n-1; goto Return; } n++; @@ -626,10 +607,12 @@ if(u && u->p) print("%s: ", u->p->text); o->npte = n-1; Return: unlock(&ptealloc); + unlock(o); return; Trouble: unlock(&ptealloc); + unlock(o); if(u && u->p) error(0, Enovmem); panic("growpte fails %d %lux %d\n", n, o->va, o->npte); diff --git a/gnot/screen.c b/gnot/screen.c index 570c298844e1c60b65d14f15c5409001d52d1247..1646cb6c5cc36d7aef4a5431df9398c0a4d9a085 100644 --- a/gnot/screen.c +++ b/gnot/screen.c @@ -65,8 +65,7 @@ screenputc(int c) bitblt(&screen, Pt(0, out.pos.y), &screen, Rect(0, out.pos.y, screen.r.max.x, out.pos.y+2*defont0.height), 0); }else if(c == '\t'){ - nx = out.pos.x + (8-(out.pos.x/out.bwid&7))*out.bwid; - out.pos.x = nx; + out.pos.x += (8-((out.pos.x-MINX)/out.bwid&7))*out.bwid; if(out.pos.x >= screen.r.max.x) screenputc('\n'); }else if(c == '\b'){ diff --git a/gnot/sturp.c b/gnot/sturp.c index 93b226aefe6b451fb6977f04517a7fcd91d53c4b..2d1e2b0f74082d66119984685c5127e9b85164c8 100644 --- a/gnot/sturp.c +++ b/gnot/sturp.c @@ -771,10 +771,8 @@ sendblock(Urp *up, int bn) * message 1, the BOT and the data */ bp = up->xb[bn]; - if(bp == 0){ - urpvomit("sendblock", up); + if(bp == 0) return; - } m = allocb(1); m->rptr = m->lim - 1; m->wptr = m->lim; diff --git a/port/devbit.c b/port/devbit.c index d43f9c123c35530077b1fbb3481c098353adde9f..ba04b8c6884ae4223483d71ea3fe157b567a2e20 100644 --- a/port/devbit.c +++ b/port/devbit.c @@ -973,11 +973,24 @@ bitfree(Bitmap *bp) bit.free = bp; } +QLock bitlock; + +Bitmap * +id2bit(int k) +{ + Bitmap *bp; + bp = &bit.map[k]; + if(k<0 || k>=conf.nbitmap || bp->ldepth < 0) + error(0, Ebadbitmap); + return bp; +} + void bitcompact(void) { ulong *p1, *p2; + qlock(&bitlock); p1 = p2 = bit.words; while(p2 < bit.wfree){ if(p2[1] == 0){ @@ -992,6 +1005,7 @@ bitcompact(void) p1 += 2 + p1[0]; } bit.wfree = p1; + qunlock(&bitlock); } void diff --git a/port/fault.c b/port/fault.c index 0e3be17e8c00a0867acde479cbefaf58b86387d9..9ae89c8ab25064c43eb9f3e02dc092aaa4453708 100644 --- a/port/fault.c +++ b/port/fault.c @@ -43,15 +43,14 @@ fault(Ureg *ur, int user, int code) /* grow stack */ o = s->o; n = o->npte; - lock(o); if(waserror()){ - unlock(o); pprint("can't allocate stack page\n"); goto cant; } growpte(o, (s->maxva-addr)>>PGSHIFT); poperror(); /* stacks grown down, sigh */ + lock(o); memcpy(o->pte+(o->npte-n), o->pte, n*sizeof(PTE)); memset(o->pte, 0, (o->npte-n)*sizeof(PTE)); unlock(o); diff --git a/port/page.c b/port/page.c index b8f270c6a3c70ae7ba79f64c4905b8aefb95553c..6a4828f6875615bab2b793a46d1f7b08e05fcd68 100644 --- a/port/page.c +++ b/port/page.c @@ -339,16 +339,13 @@ o->nmod = 0; o->mqid = -1; o->mchan = 0; } - lock(o); if(u && u->p && waserror()){ - unlock(o); unlock(&origalloc); nexterror(); } growpte(o, npte); if(u && u->p) poperror(); - unlock(o); unlock(&origalloc); return o; } @@ -547,15 +544,8 @@ segaddr(Seg *s, ulong min, ulong max) * Grow */ /* BUG: check spill onto other segments */ - lock(o); - if(waserror()){ - unlock(o); - nexterror(); - } if(o->va+BY2PG*o->npte < max) growpte(o, (max-o->va)>>PGSHIFT); - unlock(o); - poperror(); s->maxva = max; return 1; } @@ -601,6 +591,10 @@ freepte(Orig *o) /* o is locked */ p->o = 0; } +/* + * o is locked. this will always do a grow; if n<=o->npte someone + * else got here first and we can just return. + */ void growpte(Orig *o, ulong n) { @@ -608,43 +602,30 @@ growpte(Orig *o, ulong n) ulong nfree; lock(&ptealloc); + lock(o); if(o->pte){ - if(o->npte == n){ -if(u && u->p) print("%s: ", u->p->text); - print("growpte pointless\n"); + if(o->npte >= n) goto Return; - } p = (PTEA*)(o->pte - 1); - if(o->npte > n){ - print("growpte shrink"); - goto Return; - nfree = o->npte - n; - p->n -= nfree; - o->npte -= nfree; - p += p->n; - p->o = 0; - p->n = nfree; + n++; + if(p+p->n == ptealloc.free){ + if(!compactpte(o, n - p->n)) + goto Trouble; + p = (PTEA*)(o->pte - 1); + ptealloc.free += n - p->n; }else{ - n++; - if(p+p->n == ptealloc.free){ - if(!compactpte(o, n - p->n)) - goto Trouble; - p = (PTEA*)(o->pte - 1); - ptealloc.free += n - p->n; - }else{ - if(!compactpte(o, n)) - goto Trouble; - p = ptealloc.free; - ptealloc.free += n; - memcpy(p+1, o->pte, o->npte*sizeof(PTE)); - p->o = o; - ((PTEA*)(o->pte-1))->o = 0; - o->pte = p+1; - } - memset(p+1+o->npte, 0, (n-(1+o->npte))*sizeof(PTE)); - p->n = n; - o->npte = n-1; + if(!compactpte(o, n)) + goto Trouble; + p = ptealloc.free; + ptealloc.free += n; + memcpy(p+1, o->pte, o->npte*sizeof(PTE)); + p->o = o; + ((PTEA*)(o->pte-1))->o = 0; + o->pte = p+1; } + memset(p+1+o->npte, 0, (n-(1+o->npte))*sizeof(PTE)); + p->n = n; + o->npte = n-1; goto Return; } n++; @@ -659,10 +640,12 @@ if(u && u->p) print("%s: ", u->p->text); o->npte = n-1; Return: unlock(&ptealloc); + unlock(o); return; Trouble: unlock(&ptealloc); + unlock(o); if(u && u->p) error(0, Enovmem); panic("growpte fails %d %lux %d\n", n, o->va, o->npte); diff --git a/port/sturp.c b/port/sturp.c index 5902d1f4c176f22ee08ab14b7755504a1396f6dc..177172080edcc501bd123fae101177e904e23e79 100644 --- a/port/sturp.c +++ b/port/sturp.c @@ -771,10 +771,8 @@ sendblock(Urp *up, int bn) * message 1, the BOT and the data */ bp = up->xb[bn]; - if(bp == 0){ - urpvomit("sendblock", up); + if(bp == 0) return; - } m = allocb(1); m->rptr = m->lim - 1; m->wptr = m->lim; @@ -947,6 +945,7 @@ todo(void *arg) return (up->state&INITING) ? NOW>up->timer /* time to INIT1 */ : ((up->unacked!=up->next && NOW>up->timer) /* time to ENQ */ + || WINDOW(up)>0 && up->next!=up->nxb || (!QFULL(up->rq->next) && up->iseq!=(up->lastecho&7))); /* time to ECHO */ } static void