From 4ee6b36c606b3c58911e8df6190af2808c46d026 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Fri, 18 Sep 1998 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1998-09-18 --- ip/il.c | 2 +- ip/tcp.c | 23 +++++++--- pc/ns16552.h | 4 +- pc/pcmciamodem.c | 1 + port/portdat.h | 1 + port/portfns.h | 2 + port/qio.c | 114 ++++++++++++++++++++++++++++++++++++++++++----- 7 files changed, 126 insertions(+), 21 deletions(-) diff --git a/ip/il.c b/ip/il.c index fce926fb014c52f106b0cafae70a06e942b32db1..162156d555138757a5194899c3394cdf85db7c62 100644 --- a/ip/il.c +++ b/ip/il.c @@ -884,7 +884,7 @@ ilpullup(Conv *s) bp = concatblock(bp); if(bp == 0) panic("ilpullup"); - qpass(s->rq, bp); + qpassnolim(s->rq, packblock(bp)); } qunlock(&ic->outo); } diff --git a/ip/tcp.c b/ip/tcp.c index 03ef95e88139bd6d1826ee9d137ab3d67d85f5f2..fbeee413247098dd4ab2f33f0166dc6076914ed1 100644 --- a/ip/tcp.c +++ b/ip/tcp.c @@ -20,7 +20,7 @@ enum TimerON = 1, TimerDONE = 2, MAX_TIME = (1<<20), /* Forever */ - TCP_ACK = 50, /* Timed ack sequence in ms */ + TCP_ACK = 200, /* Timed ack sequence in ms */ URG = 0x20, /* Data marked urgent */ ACK = 0x10, /* Acknowledge is valid */ @@ -1384,17 +1384,21 @@ tcpiput(Proto *tcp, uchar*, Block *bp) * receive queue */ if(bp) { - qpass(s->rq, bp); + qpassnolim(s->rq, packblock(bp)); bp = nil; } tcb->rcv.nxt += length; tcprcvwin(s); - if(tcb->acktimer.state != TimerON) - tcpgo(tpriv, &tcb->acktimer); - /* force an ack if there's a lot of unacked data */ - if(tcb->rcv.nxt-tcb->last_ack > (QMAX>>4)) + /* + * force an ack if we've got 2 segs + * and the user isn't backing up + */ + if(tcb->rcv.nxt - tcb->last_ack >= 2*tcb->mss && + qlen(s->rq) < 8*tcb->mss) tcb->flags |= FORCE; + else if(tcb->acktimer.state != TimerON) + tcpgo(tpriv, &tcb->acktimer); break; case Finwait2: @@ -1637,8 +1641,15 @@ tcpoutput(Conv *s) * expect acknowledges */ if(ssize != 0){ + /* round trip depenency */ x = backoff(tcb->backoff) * (tcb->mdev + (tcb->srtt>>LOGAGAIN) + MSPTICK) / MSPTICK; + + /* take into account delayed ack */ + if(sent <= 2*tcb->mss) + x += TCP_ACK/MSPTICK; + + /* sanity check */ if(x > (10000/MSPTICK)) x = 10000/MSPTICK; tcb->timer.start = x; diff --git a/pc/ns16552.h b/pc/ns16552.h index ec89332b0164b6235e90d72cb494473cac2296fa..5299f23a35ac44d69b49110ff6fe1a8e399e8b8b 100644 --- a/pc/ns16552.h +++ b/pc/ns16552.h @@ -129,7 +129,7 @@ ns16552install(void) if(sc->freq == 0) sc->freq = UartFREQ; sc->first = nuart; - intrenable(VectorPIC+sc->irq, mp008intr, sc, BUSUNKNOWN); + intrenable(sc->irq, mp008intr, sc, BUSUNKNOWN); port = sc->port; for(j=0; j < sc->size; j++){ sprint(name, "eia%d%2.2d", nscard, j); @@ -146,7 +146,7 @@ ns16552install(void) sc->freq = UartFREQ; sprint(name, "eia%d00", nscard); ns16552setup(sc->port, sc->freq, name); - intrenable(VectorPIC+sc->irq, ns16552intrx, (void*)(nuart-1), BUSUNKNOWN); + intrenable(sc->irq, ns16552intrx, (void*)(nuart-1), BUSUNKNOWN); } nscard++; } diff --git a/pc/pcmciamodem.c b/pc/pcmciamodem.c index ff90f65d861c4e8aaf829b920596e350c421eccc..e735c132f3b624ad313aaab5f0b6d7bbe64aa60f 100644 --- a/pc/pcmciamodem.c +++ b/pc/pcmciamodem.c @@ -21,6 +21,7 @@ enum { static char* modems[] = { "IBM 33.6 Data/Fax/Voice Modem", + "CM-56G", /* Xircom CreditCard Modem 56 - GlobalACCESS */ "KeepInTouch", 0, }; diff --git a/port/portdat.h b/port/portdat.h index 49072ae5981dde7469972fed6649bd41fa5f32e4..a6ab45a7926ab2a850a501372ad44e8a84dc4ba1 100644 --- a/port/portdat.h +++ b/port/portdat.h @@ -136,6 +136,7 @@ struct Block ulong flag; }; #define BLEN(s) ((s)->wp - (s)->rp) +#define BALLOC(s) ((s)->lim - (s)->base); struct Chan { diff --git a/port/portfns.h b/port/portfns.h index 1cbbef0824fba3688a77a3fedd0efe57a77d7a86..3f86bbd98219a03c923bd3d52e5440b0c1b39e57 100644 --- a/port/portfns.h +++ b/port/portfns.h @@ -170,6 +170,7 @@ int notify(Ureg*); int nrand(int); int okaddr(ulong, ulong, int); int openmode(ulong); +Block* packblock(Block*); Block* padblock(Block*, int); void pagechainhead(Page*); void pageinit(void); @@ -229,6 +230,7 @@ int qlen(Queue*); void qlock(QLock*); Queue* qopen(int, int, void (*)(void*), void*); int qpass(Queue*, Block*); +int qpassnolim(Queue*, Block*); int qproduce(Queue*, void*, int); long qread(Queue*, void*, int); void qreopen(Queue*); diff --git a/port/qio.c b/port/qio.c index 4b9709c62b3b6c82facd4e523796e904f71b5472..0a5207d334ae2f5c12cc5ef9a67ca56a2ae8ecca 100644 --- a/port/qio.c +++ b/port/qio.c @@ -94,6 +94,19 @@ checkb(Block *b, char *msg) } +void +checkqlen(Queue *q) +{ + int len; + Block *b; + + len = 0; + for(b = q->bfirst; b; b = b->next) + len += BALLOC(b); + if(len != q->len) + panic("checkqlen"); +} + void ixsummary(void) { @@ -517,7 +530,7 @@ qget(Queue *q) } q->bfirst = b->next; b->next = 0; - q->len -= BLEN(b); + q->len -= BALLOC(b); QDEBUG checkb(b, "qget"); /* if writer flow controlled, restart */ @@ -554,12 +567,12 @@ qdiscard(Queue *q, int len) if(n <= len - sofar){ q->bfirst = b->next; b->next = 0; + q->len -= BALLOC(b); freeb(b); } else { n = len - sofar; b->rp += n; } - q->len -= n; } /* if writer flow controlled, restart */ @@ -601,6 +614,7 @@ qconsume(Queue *q, void *vp, int len) if(n > 0) break; q->bfirst = b->next; + q->len -= BALLOC(b); freeb(b); }; @@ -611,7 +625,6 @@ qconsume(Queue *q, void *vp, int len) if((q->state & Qmsg) || len == n) q->bfirst = b->next; b->rp += len; - q->len -= len; /* if writer flow controlled, restart */ if((q->state & Qflow) && q->len < q->limit/2){ @@ -629,6 +642,7 @@ qconsume(Queue *q, void *vp, int len) /* discard the block if we're done with it */ if((q->state & Qmsg) || len == n){ b->next = 0; + q->len -= BALLOC(b); freeb(b); } return len; @@ -643,7 +657,7 @@ qpass(Queue *q, Block *b) dowakeup = 0; ilock(q); if(q->len >= q->limit){ - freeb(b); + freeblist(b); iunlock(q); return -1; } @@ -653,12 +667,12 @@ qpass(Queue *q, Block *b) q->blast->next = b; else q->bfirst = b; - len = BLEN(b); + len = BALLOC(b); QDEBUG checkb(b, "qpass"); while(b->next){ b = b->next; QDEBUG checkb(b, "qpass"); - len += BLEN(b); + len += BALLOC(b); } q->blast = b; q->len += len; @@ -670,6 +684,7 @@ qpass(Queue *q, Block *b) q->state &= ~Qstarve; dowakeup = 1; } +checkqlen(q); iunlock(q); if(dowakeup) @@ -678,6 +693,71 @@ qpass(Queue *q, Block *b) return len; } +int +qpassnolim(Queue *q, Block *b) +{ + int len, dowakeup; + + /* sync with qread */ + dowakeup = 0; + ilock(q); + + /* add buffer to queue */ + if(q->bfirst) + q->blast->next = b; + else + q->bfirst = b; + len = BALLOC(b); + QDEBUG checkb(b, "qpass"); + while(b->next){ + b = b->next; + QDEBUG checkb(b, "qpass"); + len += BALLOC(b); + } + q->blast = b; + q->len += len; + + if(q->len >= q->limit/2) + q->state |= Qflow; + + if(q->state & Qstarve){ + q->state &= ~Qstarve; + dowakeup = 1; + } +checkqlen(q); + iunlock(q); + + if(dowakeup) + wakeup(&q->rr); + + return len; +} + +/* + * if the allocated space is way out of line with the used + * space, reallocate to a smaller block + */ +Block* +packblock(Block *bp) +{ + int len, alen; + Block *nbp; + + len = alen = 0; + for(nbp = bp; nbp; nbp = bp->next){ + len += BLEN(bp); + alen += BALLOC(bp); + } + + if(alen >= (len<<2)){ + nbp = allocb(len); + nbp->next = bp; + return pullupblock(nbp, len); + } + + return bp; +} + int qproduce(Queue *q, void *vp, int len) { @@ -711,13 +791,14 @@ qproduce(Queue *q, void *vp, int len) q->bfirst = b; q->blast = b; /* b->next = 0; done by iallocb() */ - q->len += len; + q->len += BALLOC(b); QDEBUG checkb(b, "qproduce"); if(q->state & Qstarve){ q->state &= ~Qstarve; dowakeup = 1; } +checkqlen(q); iunlock(q); if(dowakeup) @@ -854,7 +935,7 @@ qbread(Queue *q, int len) q->bfirst = b->next; b->next = 0; n = BLEN(b); - q->len -= n; + q->len -= BALLOC(b); QDEBUG checkb(b, "qbread 1"); /* if writer flow controlled, restart */ @@ -880,11 +961,12 @@ qbread(Queue *q, int len) if(q->bfirst == 0) q->blast = b; q->bfirst = b; - q->len += n; + q->len += BALLOC(b); } nb->wp = nb->rp + len; } +checkqlen(q); iunlock(q); /* wakeup flow controlled writers */ @@ -975,7 +1057,7 @@ qbwrite(Queue *q, Block *b) q->bfirst = b; q->blast = b; b->next = 0; - q->len += n; + q->len += BALLOC(b); QDEBUG checkb(b, "qbwrite"); if(q->state & Qstarve){ @@ -983,6 +1065,7 @@ qbwrite(Queue *q, Block *b) dowakeup = 1; } +checkqlen(q); iunlock(q); if(dowakeup){ @@ -1063,13 +1146,14 @@ qiwrite(Queue *q, void *vp, int len) else q->bfirst = b; q->blast = b; - q->len += n; + q->len += BALLOC(b); if(q->state & Qstarve){ q->state &= ~Qstarve; dowakeup = 1; } +checkqlen(q); iunlock(q); if(dowakeup){ @@ -1167,7 +1251,13 @@ qreopen(Queue *q) int qlen(Queue *q) { - return q->len; + int len; + Block *b; + + len = 0; + for(b = q->bfirst; b; b= b->next) + len += BLEN(b); + return len; } /*