From 8d1caad4ecb2d4975953932ce0b9cdc4755eac23 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Wed, 21 Mar 1990 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1990-03-21 --- gnot/chan.c | 30 ++++++++++------ gnot/clock.c | 3 +- gnot/devcons.c | 35 +++++++++++++++++-- gnot/devdk.c | 2 ++ gnot/devincon.c | 58 ++++++++++++++++-------------- gnot/fns.h | 4 +++ gnot/main.c | 10 +++--- gnot/pgrp.c | 3 +- gnot/proc.c | 7 ++++ gnot/screen.c | 14 +++++--- gnot/stream.c | 54 +++++++++++++++++----------- gnot/sturp.c | 85 +++++++++++++++++++++++++++++++++----------- gnot/trap.c | 1 + port/chan.c | 30 ++++++++++------ port/devcons.c | 5 +-- port/devdk.c | 2 ++ port/pgrp.c | 3 +- port/stream.c | 55 +++++++++++++++++------------ port/sturp.c | 93 +++++++++++++++++++++++++++++++++++-------------- port/sysfile.c | 2 +- power/devbit.c | 31 +++-------------- power/fns.h | 1 + power/main.c | 6 ++-- 23 files changed, 348 insertions(+), 186 deletions(-) diff --git a/gnot/chan.c b/gnot/chan.c index 1eacc10f0daa22f76b90e395e3ac3696864ffaf9..374bd4e1cb8c2b82f1ac78eca627093856bc8737 100644 --- a/gnot/chan.c +++ b/gnot/chan.c @@ -149,7 +149,7 @@ mount(Chan *new, Chan *old, int flag) Mtab *mt, *mz; Mount *mnt, *omnt, *nmnt, *pmnt; Pgrp *pg; - int isnew; + int islast; if(CHDIR & (old->qid^new->qid)) error(0, Emount); @@ -157,10 +157,15 @@ mount(Chan *new, Chan *old, int flag) error(0, Emount); mz = 0; - isnew = 0; + islast = 0; + mnt = 0; pg = u->p->pgrp; lock(pg); if(waserror()){ + if(mnt){ + mnt->c = 0; /* caller will close new */ + closemount(mnt); + } unlock(pg); nexterror(); } @@ -171,18 +176,18 @@ mount(Chan *new, Chan *old, int flag) for(i=0; inmtab; i++,mt++){ if(mt->c==0 && mz==0) mz = mt; - else if(eqchan(mt->c, old, CHDIR|QPATH)) + else if(eqchan(mt->c, old, CHDIR|QPATH)){ + mz = 0; goto Found; + } } - isnew = 1; if(mz == 0){ if(i == conf.nmtab) error(0, Enomount); mz = &pg->mtab[i]; - pg->nmtab++; + islast++; } mz->mnt = 0; - mz->c = old; mt = mz; Found: @@ -244,8 +249,12 @@ mount(Chan *new, Chan *old, int flag) } incref(new); - if(isnew) + if(mz){ + mz->c = old; incref(old); + } + if(islast) + pg->nmtab++; unlock(pg); poperror(); return mnt->mountid; @@ -286,7 +295,7 @@ domount(Chan *c) Found: lock(pg); if(!eqchan(mt->c, c, CHDIR|QPATH)){ /* table changed underfoot */ - print("domount: changed underfoot?\n"); + pprint("domount: changed underfoot?\n"); unlock(pg); return c; } @@ -333,7 +342,7 @@ walk(Chan *ac, char *name, int domnt) goto Notfound; } if(c->mountid != mnt->mountid){ - print("walk: changed underfoot?\n"); + pprint("walk: changed underfoot?\n"); unlock(pg); goto Notfound; } @@ -353,6 +362,7 @@ walk(Chan *ac, char *name, int domnt) if(!first) close(c); nc->mnt = mnt; + nc->mountid = mnt->mountid; c = nc; first = 0; goto Again; @@ -391,7 +401,7 @@ createdir(Chan *c) } mnt = c->mnt; if(c->mountid != mnt->mountid){ - print("createdir: changed underfoot?\n"); + pprint("createdir: changed underfoot?\n"); error(0, Enocreate); } do{ diff --git a/gnot/clock.c b/gnot/clock.c index 1b1456c4f0f321513bf145bbe259c68b7d614979..c7906d101c12aa75b875cc105b35ebd7fbaadba5 100644 --- a/gnot/clock.c +++ b/gnot/clock.c @@ -117,9 +117,10 @@ clock(Ureg *ur) } unlock(&m->alarmlock); } + kbdclock(); if((ur->sr&SPL(7)) == 0){ spllo(); if(p && p->state==Running) - sched(); + checksched(); } } diff --git a/gnot/devcons.c b/gnot/devcons.c index 9287da2cb75b87acec612a7a007ae8c9514debac..b09a8f747561721636b64fd2806f6937f82fde7c 100644 --- a/gnot/devcons.c +++ b/gnot/devcons.c @@ -30,9 +30,15 @@ struct IOQ{ Rendez r; }; -IOQ kbdq; /* qlock to getc; interrupt putc's */ IOQ lineq; /* lock to getc; interrupt putc's */ +struct{ + IOQ; /* qlock to getc; interrupt putc's */ + int c; + int repeat; + int count; +}kbdq; + void printinit(void) { @@ -142,17 +148,18 @@ pprint(char *fmt, ...) c = u->fd[2]; if(c==0 || (c->mode!=OWRITE && c->mode!=ORDWR)) - return; + return 0; n = sprint(buf, "%s %d: ", u->p->text, u->p->pid); n = donprint(buf+n, buf+sizeof(buf), fmt, (&fmt+1)) - buf; qlock(c); if(waserror()){ qunlock(c); - return; + return 0; } (*devtab[c->type].write)(c, buf, n); c->offset += n; qunlock(c); + poperror(); return n; } @@ -185,9 +192,15 @@ echo(int c) * Put character into read queue at interrupt time. * Always called splhi from proc 0. */ + void kbdchar(int c) { + if(kbdq.repeat == 1){ + kbdq.c = c; + kbdq.count = 0; + kbdq.repeat = 2; + } if(c == '\r') c = '\n'; echo(c); @@ -198,6 +211,22 @@ kbdchar(int c) wakeup(&kbdq.r); } +void +kbdrepeat(int rep) +{ + if(rep) + kbdq.repeat = 1; + else + kbdq.repeat = 0; +} + +void +kbdclock(void) +{ + if(kbdq.repeat==2 && (++kbdq.count&1)) + kbdchar(kbdq.c); +} + int consactive(void) { diff --git a/gnot/devdk.c b/gnot/devdk.c index f0db2a6c82e96b978e80f0bcc1505fd11e590be8..1596de189450dea05e4f4e24fae5c01c5ca15b3c 100644 --- a/gnot/devdk.c +++ b/gnot/devdk.c @@ -538,6 +538,8 @@ Dirtab dksubdir[]={ void dkreset(void) { + newqinfo(&dkmuxinfo); + newqinfo(&urpinfo); } /* diff --git a/gnot/devincon.c b/gnot/devincon.c index a07aa4c87a1e0820b2d45765293787d07238a9ce..e804e478f9390a3b81bbb9936a0e614494984f19 100644 --- a/gnot/devincon.c +++ b/gnot/devincon.c @@ -23,8 +23,9 @@ enum { Minstation= 2, /* lowest station # to poll */ Maxstation= 15, /* highest station # to poll */ Nincon= 1, /* number of incons */ - Nin= 16, /* Blocks in the input ring */ + Nin= 64, /* Blocks in the input ring */ Bsize= 128, /* size of an input ring block */ + Mfifo= 0xff /* a mask, must be 2^n-1, must be > Nin */ }; /* @@ -631,7 +632,7 @@ inconkproc(void *arg) } /* - * drop an input packet on the floor + * drop a single packet */ static void droppacket(Device *dev) @@ -639,16 +640,23 @@ droppacket(Device *dev) int i; int c; - screenputc('!'); - while(!(dev->status & RCV_EMPTY)){ - for(i = 0; i < 17; i++){ - c = dev->data_cntl; - if(c==0) - break; - } + for(i = 0; i < 17; i++){ + c = dev->data_cntl; + if(c==0) + break; } } +/* + * flush the input fifo + */ +static void +flushfifo(Device *dev) +{ + while(!(dev->status & RCV_EMPTY)) + droppacket(dev); +} + /* * advance the queue. if we've run out of staged input blocks, * drop the packet and return 0. otherwise return the next input @@ -657,19 +665,20 @@ droppacket(Device *dev) static Block * nextin(Incon *ip, unsigned int c) { - Block *bp = ip->inb[ip->wi]; + Block *bp; int next; - next = (ip->wi+1)%Nin; - if(next == ip->ri){ - bp->wptr = bp->base+3; - droppacket(ip->dev); - return 0; - } + bp = ip->inb[ip->wi]; bp->base[0] = ip->chan; bp->base[1] = ip->chan>>8; bp->base[2] = c; - ip->wi = next; + + next = (ip->wi+3)%Nin; + if(next == ip->ri){ + bp->wptr = bp->base+3; + return bp; + } + ip->wi = (ip->wi+1)%Nin; return ip->inb[ip->wi]; } @@ -690,8 +699,8 @@ rdpackets(Incon *ip) dev = ip->dev; bp = ip->inb[ip->wi]; if(bp==0){ - droppacket(ip->dev); - goto done; + flushfifo(ip->dev); + return; } p = bp->wptr; while(!(dev->status & RCV_EMPTY)){ @@ -699,12 +708,14 @@ rdpackets(Incon *ip) * get channel number */ c = (dev->data_cntl)>>8; + if(c == 0){ + droppacket(dev); + continue; + } if(ip->chan != c){ if(p - bp->rptr > 3){ bp->wptr = p; bp = nextin(ip, 0); - if(bp == 0) - goto done; p = bp->wptr; } ip->chan = c; @@ -725,8 +736,6 @@ rdpackets(Incon *ip) */ bp->wptr = p; bp = nextin(ip, c); - if(bp == 0) - goto done; p = bp->wptr; } else { /* end of packet */ @@ -741,14 +750,11 @@ rdpackets(Incon *ip) if(p + 16 > bp->lim){ bp->wptr = p; bp = nextin(ip, 0); - if(bp == 0) - goto done; p = bp->wptr; } } bp->wptr = p; -done: if(first != ip->wi)/**/ wakeup(&ip->kr); } diff --git a/gnot/fns.h b/gnot/fns.h index 756055d2c646728469bfae9cca1ece849c0dad03..62ab5f9dbf1aca37d1cd9a04ed536acfc9c503dc 100644 --- a/gnot/fns.h +++ b/gnot/fns.h @@ -8,6 +8,7 @@ int canqlock(QLock*); void chaninit(void); void chandevreset(void); void chandevinit(void); +void checksched(void); void clock(Ureg*); Chan *clone(Chan*, Chan*); void close(Chan*); @@ -58,6 +59,8 @@ int incref(Ref*); void insert(List**, List*, List*); void isdir(Chan*); void kbdchar(int); +void kbdrepeat(int); +void kbdclock(void); void kproc(char*, void(*)(void*), void*); void lock(Lock*); void lockinit(void); @@ -76,6 +79,7 @@ Orig *neworig(ulong, ulong, int, Chan*); Page *newpage(int, Orig*, ulong); Pgrp *newpgrp(void); Proc *newproc(void); +void newqinfo(Qinfo*); char *nextelem(char*, char*); void nullput(Queue*, Block*); int openmode(ulong); diff --git a/gnot/main.c b/gnot/main.c index 62bf54e6035a1a7d4b5c58d3226a2b30ad93ed91..48da1bb0a3a48c2e28eb4ab6950145038a034c2e 100644 --- a/gnot/main.c +++ b/gnot/main.c @@ -240,10 +240,10 @@ confinit(void) conf.nmod = 50; conf.nalarm = 1000; conf.norig = 50; - conf.nchan = 100; - conf.nenv = 50; - conf.nenvchar = 4000; - conf.npgenv = 100; + conf.nchan = 200; + conf.nenv = 100; + conf.nenvchar = 8000; + conf.npgenv = 200; conf.nmtab = 50; conf.nmount = 100; conf.nmntdev = 5; @@ -251,6 +251,6 @@ confinit(void) conf.nmnthdr = 10; conf.nstream = 64; conf.nqueue = 5 * conf.nstream; - conf.nblock = 16 * conf.nstream; + conf.nblock = 32 * conf.nstream; conf.nsrv = 32; } diff --git a/gnot/pgrp.c b/gnot/pgrp.c index 6da4efc58b0a99b7a891c7b1508130ca4ef81a21..fce3b79e8d35f40273a682e43fa4acc63437b1f2 100644 --- a/gnot/pgrp.c +++ b/gnot/pgrp.c @@ -122,7 +122,8 @@ closemount(Mount *m) { lock(m); if(m->ref == 1){ - close(m->c); + if(m->c) + close(m->c); if(m->next) closemount(m->next); unlock(m); diff --git a/gnot/proc.c b/gnot/proc.c index 64d7cc5d8664db854081a40f9b30eca157d3fef1..b428aaea3b7cbad3d9a1e35b5f7f775b00aa5e5f 100644 --- a/gnot/proc.c +++ b/gnot/proc.c @@ -117,6 +117,13 @@ ready(Proc *p) splx(s); } +void +checksched(void) /* just for efficiency; don't sched if no need */ +{ + if(runq.head) + sched(); +} + /* * Always called spllo */ diff --git a/gnot/screen.c b/gnot/screen.c index b03284017f4743d3f5752b1c4b3f007a15be29c6..8cff5d32f29febcb9a83a47bd567a552a706156c 100644 --- a/gnot/screen.c +++ b/gnot/screen.c @@ -161,11 +161,15 @@ duartintr(void) c = duart->data; if(status & (FRM_ERR|OVR_ERR|PAR_ERR)) duart->cmnd = RESET_ERR; - if(c == 0x7F) - c = 0xFF; /* VIEW key (bizarre) */ - if(c & 0x80) - c = keymap[c&0x7F]; - kbdchar(c); + if(status & PAR_ERR) /* control word: caps lock (0x4) or repeat (0x10) */ + kbdrepeat((c&0x10) == 0); + else{ + if(c == 0x7F) + c = 0xFF; /* VIEW key (bizarre) */ + if(c & 0x80) + c = keymap[c&0x7F]; + kbdchar(c); + } } /* * Is it 2? diff --git a/gnot/stream.c b/gnot/stream.c index 309c68cc221f75894935de32f8353171dcff32a7..628779ee77391424eaa0b424791adf21ad5aa492 100644 --- a/gnot/stream.c +++ b/gnot/stream.c @@ -7,6 +7,11 @@ #include "errno.h" #include "devtab.h" +enum { + Nclass=4, /* number of block classes */ + Nlds=32, /* max number of pushable line disciplines */ +}; + /* * process end line discipline */ @@ -15,21 +20,21 @@ Qinfo procinfo = { stputq, nullput, 0, 0, "process" }; /* * line disciplines that can be pushed - * - * WARNING: this table should be the result of configuration - */ -extern Qinfo noetherinfo; -extern Qinfo dkmuxinfo; -extern Qinfo urpinfo; -static Qinfo *lds[] = { - &dkmuxinfo, - &urpinfo, - 0 -}; + */ +static Qinfo *lds[Nlds+1]; -enum { - Nclass=4, -}; +void +newqinfo(Qinfo *qi) +{ + int i; + + for(i=0; ilast = bp; unlock(bcp); - wakeup(&bcp->r); + if(bcp->r.p) + wakeup(&bcp->r); } /* @@ -716,30 +721,37 @@ streamclose(Chan *c) void stputq(Queue *q, Block *bp) { - int i; + int delim; if(bp->type == M_HANGUP){ freeb(bp); q->flag |= QHUNGUP; q->other->flag |= QHUNGUP; wakeup(&q->other->r); + delim = 1; } else { + delim = 0; lock(q); if(q->first) q->last->next = bp; else q->first = bp; q->len += BLEN(bp); + delim = bp->flags & S_DELIM; while(bp->next) { bp = bp->next; q->len += BLEN(bp); + delim |= bp->flags & S_DELIM; } q->last = bp; - if(q->len >= Streamhi) + if(q->len >= Streamhi){ q->flag |= QHIWAT; + delim = 1; + } unlock(q); } - wakeup(&q->r); + if(delim) + wakeup(&q->r); } /* diff --git a/gnot/sturp.c b/gnot/sturp.c index 8064d1a53ca81a094c6d421135b81aaa91f53abd..708e1717abd53e4a75dc4d7dc3e02ff05efcc7db 100644 --- a/gnot/sturp.c +++ b/gnot/sturp.c @@ -39,12 +39,13 @@ struct Urp { Rendez r; /* process waiting for close */ /* input */ - + QLock ack; /* ack lock */ Queue *rq; /* input queue */ uchar iseq; /* last good input sequence number */ uchar lastecho; /* last echo/rej sent */ uchar trbuf[3]; /* trailer being collected */ short trx; /* # bytes in trailer being collected */ + int blocks; /* output */ @@ -110,6 +111,8 @@ static void sendblock(Urp*, int); static void rcvack(Urp*, int); static void flushinput(Urp*); static void sendctl(Urp*, int); +static void sendack(Urp*); +static void sendrej(Urp*); static void initoutput(Urp*, int); static void initinput(Urp*, int); static void urpkproc(void *arg); @@ -305,10 +308,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(q->next->len < Streamhi) sendctl(up, up->lastecho = ECHO+i); up->iseq = i; + qunlock(&up->ack); break; } } @@ -377,7 +382,8 @@ urpiput(Queue *q, Block *bp) case 0: break; case ENQ: - DPRINT("rENQ %uo %uo\n", up->lastecho, ACK+up->iseq); + DPRINT("rENQ %d %uo %uo\n", up->blocks, up->lastecho, ACK+up->iseq); + up->blocks = 0; urpstat.enqsr++; sendctl(up, up->lastecho); sendctl(up, ACK+up->iseq); @@ -440,25 +446,15 @@ urpiput(Queue *q, Block *bp) i = ctl & Nmask; if(up->trx != 3){ urpstat.rjtrs++; - flushinput(up); - DPRINT("sREJ1 %d\n", up->iseq); - if((up->lastecho&~7)==ECHO) - sendctl(up, up->lastecho = REJ+up->iseq);/**/ + sendrej(up); break; } else if(q->len != up->trbuf[1] + (up->trbuf[2]<<8)){ urpstat.rjpks++; - DPRINT("sREJ2 %d %d %d\n", up->iseq, q->len, - up->trbuf[1] + (up->trbuf[2]<<8)); - flushinput(up); - if((up->lastecho&~7)==ECHO) - sendctl(up, up->lastecho = REJ+up->iseq);/**/ + sendrej(up); break; } else if(i != ((up->iseq+1)&Nmask)) { urpstat.rjseq++; - flushinput(up); - DPRINT("sREJ3 %d %d\n", i, up->iseq); - if((up->lastecho&~7)==ECHO) - sendctl(up, up->lastecho = REJ+up->iseq);/**/ + sendrej(up); break; } @@ -480,11 +476,11 @@ urpiput(Queue *q, Block *bp) /* * acknowledge receipt */ - if(q->next->len < Streamhi){ - sendctl(up, up->lastecho = ECHO+i); - wakeup(&up->rq->r); - } + qlock(&up->ack); up->iseq = i; + if(q->next->len < Streamhi) + sendctl(up, up->lastecho = ECHO|i); + qunlock(&up->ack); break; } } @@ -635,6 +631,53 @@ sendctl(Urp *up, int ctl) PUTNEXT(up->wq, bp); } +/* + * send a reject + */ +static void +sendrej(Urp *up) +{ + flushinput(up); + qlock(&up->ack); + if((up->lastecho&~Nmask) == ECHO){ + DPRINT("REJ %d\n", up->iseq); + sendctl(up, up->lastecho = REJ|up->iseq); + } + qunlock(&up->ack); +} + +/* + * send an acknowledge + */ +static void +sendack(Urp *up) +{ + Block *bp; + + /* + * check the precondition for acking + */ + if(up->rq->next->len>=Streamhi || (up->lastecho&Nmask)==up->iseq) + return; + + if(!canqlock(&up->ack)) + return; + + /* + * check again now that we've locked + */ + if(up->rq->next->len>=Streamhi || (up->lastecho&Nmask)==up->iseq){ + qunlock(&up->ack); + return; + } + + /* + * send the ack + */ + sendctl(up, up->lastecho = ECHO|up->iseq); + qunlock(&up->ack); +} + /* * send a block. */ @@ -801,6 +844,7 @@ initinput(Urp *up, int window) /* * restart all sequence parameters */ + up->blocks = 0; up->trx = 0; up->iseq = 0; up->lastecho = ECHO+0; @@ -832,8 +876,7 @@ urpkproc(void *arg) if(up->state & HUNGUP) break; } - if((up->lastecho&Nmask)!=up->iseq && up->rq->next->lenlastecho = ECHO+up->iseq); + sendack(up); output(up); tsleep(&up->rq->r, todo, up, MSrexmit/2); } diff --git a/gnot/trap.c b/gnot/trap.c index 46c029f917714bf9b5613296615f3556ba159c70..27db2bfd7f9ad147b46cf87b719b1a5bd850670f 100644 --- a/gnot/trap.c +++ b/gnot/trap.c @@ -270,6 +270,7 @@ syscall(Ureg *aur) ret = -1; if(!waserror()) ret = (*systab[r0])((ulong*)(sp+BY2WD)); +else print("syscall %d err %d %d\n", r0, u->error.type, u->error.code); u->nerrlab = 0; u->p->insyscall = 0; if(r0 == NOTED) /* ugly hack */ diff --git a/port/chan.c b/port/chan.c index 1eacc10f0daa22f76b90e395e3ac3696864ffaf9..374bd4e1cb8c2b82f1ac78eca627093856bc8737 100644 --- a/port/chan.c +++ b/port/chan.c @@ -149,7 +149,7 @@ mount(Chan *new, Chan *old, int flag) Mtab *mt, *mz; Mount *mnt, *omnt, *nmnt, *pmnt; Pgrp *pg; - int isnew; + int islast; if(CHDIR & (old->qid^new->qid)) error(0, Emount); @@ -157,10 +157,15 @@ mount(Chan *new, Chan *old, int flag) error(0, Emount); mz = 0; - isnew = 0; + islast = 0; + mnt = 0; pg = u->p->pgrp; lock(pg); if(waserror()){ + if(mnt){ + mnt->c = 0; /* caller will close new */ + closemount(mnt); + } unlock(pg); nexterror(); } @@ -171,18 +176,18 @@ mount(Chan *new, Chan *old, int flag) for(i=0; inmtab; i++,mt++){ if(mt->c==0 && mz==0) mz = mt; - else if(eqchan(mt->c, old, CHDIR|QPATH)) + else if(eqchan(mt->c, old, CHDIR|QPATH)){ + mz = 0; goto Found; + } } - isnew = 1; if(mz == 0){ if(i == conf.nmtab) error(0, Enomount); mz = &pg->mtab[i]; - pg->nmtab++; + islast++; } mz->mnt = 0; - mz->c = old; mt = mz; Found: @@ -244,8 +249,12 @@ mount(Chan *new, Chan *old, int flag) } incref(new); - if(isnew) + if(mz){ + mz->c = old; incref(old); + } + if(islast) + pg->nmtab++; unlock(pg); poperror(); return mnt->mountid; @@ -286,7 +295,7 @@ domount(Chan *c) Found: lock(pg); if(!eqchan(mt->c, c, CHDIR|QPATH)){ /* table changed underfoot */ - print("domount: changed underfoot?\n"); + pprint("domount: changed underfoot?\n"); unlock(pg); return c; } @@ -333,7 +342,7 @@ walk(Chan *ac, char *name, int domnt) goto Notfound; } if(c->mountid != mnt->mountid){ - print("walk: changed underfoot?\n"); + pprint("walk: changed underfoot?\n"); unlock(pg); goto Notfound; } @@ -353,6 +362,7 @@ walk(Chan *ac, char *name, int domnt) if(!first) close(c); nc->mnt = mnt; + nc->mountid = mnt->mountid; c = nc; first = 0; goto Again; @@ -391,7 +401,7 @@ createdir(Chan *c) } mnt = c->mnt; if(c->mountid != mnt->mountid){ - print("createdir: changed underfoot?\n"); + pprint("createdir: changed underfoot?\n"); error(0, Enocreate); } do{ diff --git a/port/devcons.c b/port/devcons.c index 5a18808d0d703dfc21cc553a3083c349e32e3621..a7cd7b8ed19205ab352e93698f3c374bd3fd845b 100644 --- a/port/devcons.c +++ b/port/devcons.c @@ -180,17 +180,18 @@ pprint(char *fmt, ...) c = u->fd[2]; if(c==0 || (c->mode!=OWRITE && c->mode!=ORDWR)) - return; + return 0; n = sprint(buf, "%s %d: ", u->p->text, u->p->pid); n = donprint(buf+n, buf+sizeof(buf), fmt, (&fmt+1)) - buf; qlock(c); if(waserror()){ qunlock(c); - return; + return 0; } (*devtab[c->type].write)(c, buf, n); c->offset += n; qunlock(c); + poperror(); return n; } diff --git a/port/devdk.c b/port/devdk.c index f0db2a6c82e96b978e80f0bcc1505fd11e590be8..1596de189450dea05e4f4e24fae5c01c5ca15b3c 100644 --- a/port/devdk.c +++ b/port/devdk.c @@ -538,6 +538,8 @@ Dirtab dksubdir[]={ void dkreset(void) { + newqinfo(&dkmuxinfo); + newqinfo(&urpinfo); } /* diff --git a/port/pgrp.c b/port/pgrp.c index 6da4efc58b0a99b7a891c7b1508130ca4ef81a21..fce3b79e8d35f40273a682e43fa4acc63437b1f2 100644 --- a/port/pgrp.c +++ b/port/pgrp.c @@ -122,7 +122,8 @@ closemount(Mount *m) { lock(m); if(m->ref == 1){ - close(m->c); + if(m->c) + close(m->c); if(m->next) closemount(m->next); unlock(m); diff --git a/port/stream.c b/port/stream.c index 198aa4a51d3313fcc45b5a16fa320185a0c713fe..628779ee77391424eaa0b424791adf21ad5aa492 100644 --- a/port/stream.c +++ b/port/stream.c @@ -7,6 +7,11 @@ #include "errno.h" #include "devtab.h" +enum { + Nclass=4, /* number of block classes */ + Nlds=32, /* max number of pushable line disciplines */ +}; + /* * process end line discipline */ @@ -15,22 +20,21 @@ Qinfo procinfo = { stputq, nullput, 0, 0, "process" }; /* * line disciplines that can be pushed - * - * WARNING: this table should be the result of configuration - */ -extern Qinfo noetherinfo; -extern Qinfo dkmuxinfo; -extern Qinfo urpinfo; -static Qinfo *lds[] = { - &noetherinfo, - &dkmuxinfo, - &urpinfo, - 0 -}; + */ +static Qinfo *lds[Nlds+1]; -enum { - Nclass=4, -}; +void +newqinfo(Qinfo *qi) +{ + int i; + + for(i=0; ilast = bp; unlock(bcp); - wakeup(&bcp->r); + if(bcp->r.p) + wakeup(&bcp->r); } /* @@ -717,30 +721,37 @@ streamclose(Chan *c) void stputq(Queue *q, Block *bp) { - int i; + int delim; if(bp->type == M_HANGUP){ freeb(bp); q->flag |= QHUNGUP; q->other->flag |= QHUNGUP; wakeup(&q->other->r); + delim = 1; } else { + delim = 0; lock(q); if(q->first) q->last->next = bp; else q->first = bp; q->len += BLEN(bp); + delim = bp->flags & S_DELIM; while(bp->next) { bp = bp->next; q->len += BLEN(bp); + delim |= bp->flags & S_DELIM; } q->last = bp; - if(q->len >= Streamhi) + if(q->len >= Streamhi){ q->flag |= QHIWAT; + delim = 1; + } unlock(q); } - wakeup(&q->r); + if(delim) + wakeup(&q->r); } /* diff --git a/port/sturp.c b/port/sturp.c index 70382de704fd090fd8491fcc5cfa92535136af55..708e1717abd53e4a75dc4d7dc3e02ff05efcc7db 100644 --- a/port/sturp.c +++ b/port/sturp.c @@ -39,12 +39,13 @@ struct Urp { Rendez r; /* process waiting for close */ /* input */ - + QLock ack; /* ack lock */ Queue *rq; /* input queue */ uchar iseq; /* last good input sequence number */ uchar lastecho; /* last echo/rej sent */ uchar trbuf[3]; /* trailer being collected */ short trx; /* # bytes in trailer being collected */ + int blocks; /* output */ @@ -110,6 +111,8 @@ static void sendblock(Urp*, int); static void rcvack(Urp*, int); static void flushinput(Urp*); static void sendctl(Urp*, int); +static void sendack(Urp*); +static void sendrej(Urp*); static void initoutput(Urp*, int); static void initinput(Urp*, int); static void urpkproc(void *arg); @@ -123,8 +126,6 @@ urpopen(Queue *q, Stream *s) int i; char name[128]; - DPRINT("urpopen\n"); - /* * find a free urp structure */ @@ -200,13 +201,11 @@ urpclose(Queue *q) i = 7; rcvack(up, ECHO+i); qunlock(&up->xmit); - DPRINT("urpclose(%ux)\n", up); /* * kill off the kernel process */ wakeup(&up->rq->r); - DPRINT("urpclosed(%ux)\n", up); } /* @@ -309,10 +308,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(q->next->len < Streamhi) sendctl(up, up->lastecho = ECHO+i); up->iseq = i; + qunlock(&up->ack); break; } } @@ -381,7 +382,8 @@ urpiput(Queue *q, Block *bp) case 0: break; case ENQ: - print("rENQ %uo %uo\n", up->lastecho, ACK+up->iseq); + DPRINT("rENQ %d %uo %uo\n", up->blocks, up->lastecho, ACK+up->iseq); + up->blocks = 0; urpstat.enqsr++; sendctl(up, up->lastecho); sendctl(up, ACK+up->iseq); @@ -422,7 +424,7 @@ urpiput(Queue *q, Block *bp) case REJ+0: case REJ+1: case REJ+2: case REJ+3: case REJ+4: case REJ+5: case REJ+6: case REJ+7: - print("rREJ\n"); + DPRINT("rREJ\n"); rcvack(up, ctl); break; @@ -444,21 +446,15 @@ urpiput(Queue *q, Block *bp) i = ctl & Nmask; if(up->trx != 3){ urpstat.rjtrs++; - flushinput(up); - print("sREJ1 %d\n", up->iseq); - sendctl(up, up->lastecho = REJ+up->iseq); + sendrej(up); break; } else if(q->len != up->trbuf[1] + (up->trbuf[2]<<8)){ urpstat.rjpks++; - flushinput(up); - print("sREJ2 %d\n", up->iseq); - sendctl(up, up->lastecho = REJ+up->iseq); + sendrej(up); break; } else if(i != ((up->iseq+1)&Nmask)) { urpstat.rjseq++; - flushinput(up); - print("sREJ3 %d %d\n", i, up->iseq); - sendctl(up, up->lastecho = REJ+up->iseq); + sendrej(up); break; } @@ -480,12 +476,11 @@ urpiput(Queue *q, Block *bp) /* * acknowledge receipt */ - if(q->next->len < Streamhi){ - sendctl(up, ECHO+i); - up->lastecho = ECHO+i; - wakeup(&up->rq->r); - } + qlock(&up->ack); up->iseq = i; + if(q->next->len < Streamhi) + sendctl(up, up->lastecho = ECHO|i); + qunlock(&up->ack); break; } } @@ -510,7 +505,6 @@ urpctloput(Urp *up, Queue *q, Block *bp) outwin = strtoul(fields[0], 0, 0); } /* initinput(up, inwin); */ - DPRINT("initoutput %d\n", outwin); initoutput(up, outwin); freeb(bp); return; @@ -596,7 +590,7 @@ output(Urp *up) * if a retransmit time has elapsed since a transmit, send an ENQ */ if(up->unechoed != up->next && NOW > up->timer){ - print("sENQ\n"); + DPRINT("sENQ\n"); up->timer = NOW + MSrexmit; up->state &= ~REJECTING; sendctl(up, ENQ); @@ -637,6 +631,53 @@ sendctl(Urp *up, int ctl) PUTNEXT(up->wq, bp); } +/* + * send a reject + */ +static void +sendrej(Urp *up) +{ + flushinput(up); + qlock(&up->ack); + if((up->lastecho&~Nmask) == ECHO){ + DPRINT("REJ %d\n", up->iseq); + sendctl(up, up->lastecho = REJ|up->iseq); + } + qunlock(&up->ack); +} + +/* + * send an acknowledge + */ +static void +sendack(Urp *up) +{ + Block *bp; + + /* + * check the precondition for acking + */ + if(up->rq->next->len>=Streamhi || (up->lastecho&Nmask)==up->iseq) + return; + + if(!canqlock(&up->ack)) + return; + + /* + * check again now that we've locked + */ + if(up->rq->next->len>=Streamhi || (up->lastecho&Nmask)==up->iseq){ + qunlock(&up->ack); + return; + } + + /* + * send the ack + */ + sendctl(up, up->lastecho = ECHO|up->iseq); + qunlock(&up->ack); +} + /* * send a block. */ @@ -803,6 +844,7 @@ initinput(Urp *up, int window) /* * restart all sequence parameters */ + up->blocks = 0; up->trx = 0; up->iseq = 0; up->lastecho = ECHO+0; @@ -826,7 +868,6 @@ urpkproc(void *arg) Urp *up; up = (Urp *)arg; - DPRINT("urpkproc started\n"); for(;;){ if(up->state & (HUNGUP|CLOSING)){ @@ -835,12 +876,10 @@ urpkproc(void *arg) if(up->state & HUNGUP) break; } - if((up->lastecho&Nmask)!=up->iseq && up->rq->next->lenlastecho = ECHO+up->iseq); + sendack(up); output(up); tsleep(&up->rq->r, todo, up, MSrexmit/2); } - DPRINT("urpkproc exiting %ux\n", up); up->kstarted = 0; up->state = 0; } diff --git a/port/sysfile.c b/port/sysfile.c index f607a8852df8e24c591ad99a7e335c67adc86785..b0e2321397c2ec4eb4e90fe4d03bf9397bcab918 100644 --- a/port/sysfile.c +++ b/port/sysfile.c @@ -126,7 +126,7 @@ unionread(Chan *c, void *va, long n) mnt = c->mnt; lock(pg); if(c->mountid != mnt->mountid){ - print("unionread: changed underfoot?\n"); + pprint("unionread: changed underfoot?\n"); unlock(pg); return 0; } diff --git a/power/devbit.c b/power/devbit.c index f2dec8a8fdd189c038f52a3fd517b0e6a51b6c6a..f902dad264e88545293ac105279b21861978572e 100644 --- a/power/devbit.c +++ b/power/devbit.c @@ -26,21 +26,17 @@ enum WRITE, }; -long hold, wait, hang; - void bitsend(Bitmsg *bp, ulong cmd, void *addr, ulong count) { - do wait++; while(*BITADDR); + do; while(*BITADDR); bp->cmd = cmd; bp->addr = (ulong)addr; bp->count = count; -/* print("%d %lux %d ", cmd, addr, count); /**/ *BITADDR = bp; wbflush(); - do hold++; while(*BITHOLD); + do; while(*BITHOLD); *BITINTR = 0x20; -/* print("done\n"); /**/ } void @@ -153,21 +149,11 @@ bitread(Chan *c, void *buf, long n) docpy = 1; } qunlock(&bit); - do{ + do n = bp->rcount; - hang++; - }while(n == 0); + 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