From 8aa2a47a237023d338999967195fa76b21cd395e Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Sat, 20 Nov 1993 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1993-11-20 --- pc/devether.c | 44 +++++++++++++++++++++++++++++++++++++++ pc/ether8003.c | 5 ----- pc/ether8390.c | 39 +++++++++++++++++++++++++---------- port/devcons.c | 7 ++----- port/page.c | 56 +++++++++++++++++++++++++------------------------- port/portdat.h | 7 +++---- port/swap.c | 16 ++++++--------- 7 files changed, 111 insertions(+), 63 deletions(-) diff --git a/pc/devether.c b/pc/devether.c index 67b2cb891e4b26c7346aff7772e7ff8d74bebae8..72bdcabfa365cec85b0fd43d3957c6f97313d6a5 100644 --- a/pc/devether.c +++ b/pc/devether.c @@ -94,6 +94,46 @@ etherwstat(Chan *c, char *dp) netifwstat(ether[c->dev], c, dp); } +void +etherrloop(Ether *ctlr, Etherpkt *pkt, long len) +{ + ushort type; + Netfile *f, **fp, **ep; + + type = (pkt->type[0]<<8)|pkt->type[1]; + ep = &ctlr->f[Ntypes]; + for(fp = ctlr->f; fp < ep; fp++){ + f = *fp; + if(f && (f->type == type || f->type < 0)){ + switch(qproduce(f->in, pkt->d, len)){ + + case -1: + print("etherrloop overflow\n"); + break; + + case -2: + print("etherrloop memory\n"); + break; + } + } + } +} + +static int +etherwloop(Ether *ctlr, Etherpkt *pkt, long len) +{ + int s, different; + + different = memcmp(pkt->d, pkt->s, sizeof(pkt->s)); + if(different && memcmp(pkt->d, ctlr->bcast, sizeof(pkt->d))) + return 0; + + s = splhi(); + etherrloop(ctlr, pkt, len); + splx(s); + return !different; +} + long etherwrite(Chan *c, void *buf, long n, ulong offset) { @@ -107,6 +147,9 @@ etherwrite(Chan *c, void *buf, long n, ulong offset) if(NETTYPE(c->qid.path) != Ndataqid) return netifwrite(ctlr, c, buf, n); + if(etherwloop(ctlr, buf, n)) + return n; + qlock(&ctlr->tlock); if(waserror()){ qunlock(&ctlr->tlock); @@ -204,6 +247,7 @@ etherreset(void) ether[ctlrno] = ctlr; ctlr = 0; + break; } } if(ctlr) diff --git a/pc/ether8003.c b/pc/ether8003.c index 19bc824a1f62799cb645bb76ac4d2863769b48c2..ae899a15491b70bc3b1dd9662a5a6a20c59c2554 100644 --- a/pc/ether8003.c +++ b/pc/ether8003.c @@ -57,10 +57,6 @@ static int intrmap[] = { 9, 3, 5, 7, 10, 11, 15, 4, }; -static uchar debugea[6] = { - 0x00, 0x60, 0x8c, 0x00, 0x1a, 0x42, -}; - /* * Get configuration parameters, enable memory. * There are opportunities here for buckets of code. @@ -188,7 +184,6 @@ reset(Ether *ether) * ethernet address. */ dp8390reset(ether); -memmove(ether->ea, debugea, 6); dp8390setea(ether); return 0; diff --git a/pc/ether8390.c b/pc/ether8390.c index d020be67cd3ed252f6b48fa6202e25d52d19bbaf..4c61c290cd041de9c41cf5306492f76683fa5531 100644 --- a/pc/ether8390.c +++ b/pc/ether8390.c @@ -446,10 +446,7 @@ receive(Ether *ether) for(fp = ether->f; fp < ep; fp++) { f = *fp; if(f && (f->type == type || f->type < 0)) -{ -print("Q%d|", len); qproduce(f->in, ðer->rpkt, len); -} } } @@ -473,10 +470,11 @@ istxavail(void *arg) } static long -write(Ether *ether, void *buf, long n) +write(Ether *ether, void *buf, long len) { Dp8390 *dp8390; ulong port; + Etherpkt *pkt; dp8390 = ether->private; port = dp8390->dp8390; @@ -486,18 +484,38 @@ write(Ether *ether, void *buf, long n) print("dp8390: transmitter jammed\n"); return 0; } - ether->tlen = n; + ether->tlen = len; + /* + * If it's a shared-memory interface, copy the packet + * directly to the shared-memory area. Otherwise, copy + * it to a staging buffer so the I/O-port write can be + * done in one. + */ if(dp8390->ram) - memmove((void*)(ether->mem+dp8390->tstart*Dp8390BufSz), buf, n); + pkt = (Etherpkt*)(ether->mem+dp8390->tstart*Dp8390BufSz); else - dp8390write(dp8390, dp8390->tstart*Dp8390BufSz, buf, n); + pkt = ðer->tpkt; + memmove(pkt, buf, len); + + /* + * Give the packet a source address and make sure it + * is of minimum length. + */ + memmove(pkt->s, ether->ea, sizeof(ether->ea)); + if(len < ETHERMINTU){ + memset(pkt->d+len, 0, ETHERMINTU-len); + len = ETHERMINTU; + } + + if(dp8390->ram == 0) + dp8390write(dp8390, dp8390->tstart*Dp8390BufSz, pkt, len); - dp8390outb(port+Tbcr0, n & 0xFF); - dp8390outb(port+Tbcr1, (n>>8) & 0xFF); + dp8390outb(port+Tbcr0, len & 0xFF); + dp8390outb(port+Tbcr1, (len>>8) & 0xFF); dp8390outb(port+Cr, Page0|RDMAabort|Txp|Sta); - return n; + return len; } static void @@ -551,7 +569,6 @@ interrupt(Ether *ether) */ dp8390outb(port+Imr, 0x00); while(isr = dp8390inb(port+Isr)){ -print("I%2.2ux|", isr); if(isr & Ovw){ overflow(ether); diff --git a/port/devcons.c b/port/devcons.c index 18922b8cc0a784ee58e60f10dabfef5bd9474a14..3ca32fd97714fe26a83fd57da15dab2f63470cd1 100644 --- a/port/devcons.c +++ b/port/devcons.c @@ -654,11 +654,8 @@ consread(Chan *c, void *buf, long n, ulong offset) return n; case Qswap: - k = 0; - for(i = 0; i < NCOLOR; i++) - k += palloc.freecol[i]; - - sprint(tmp, "%d/%d memory %d/%d swap\n", palloc.user-k, + sprint(tmp, "%d/%d memory %d/%d swap\n", + palloc.user-palloc.freecount, palloc.user, conf.nswap-swapalloc.free, conf.nswap); return readstr(offset, buf, n, tmp); diff --git a/port/page.c b/port/page.c index 46380dc1bd6bfe48b4efa6da7b0b070d4456e461..94fa446cae143b8445f86a632a9ed0ca96c634a4 100644 --- a/port/page.c +++ b/port/page.c @@ -29,7 +29,7 @@ pageinit(void) p->next = p+1; p->pa = palloc.p0; p->color = color; - palloc.freecol[color]++; + palloc.freecount++; color = (color+1)%NCOLOR; palloc.p0 += BY2PG; palloc.np0--; @@ -40,7 +40,7 @@ pageinit(void) p->next = p+1; p->pa = palloc.p1; p->color = color; - palloc.freecol[color]++; + palloc.freecount++; color = (color+1)%NCOLOR; palloc.p1 += BY2PG; palloc.np1--; @@ -70,18 +70,17 @@ newpage(int clear, Segment **s, ulong va) KMap *k; int i, hw, dontalloc, color; -retry: - lock(&palloc); + lock(&palloc); +retry: color = getpgcolor(va); hw = swapalloc.highwater; for(;;) { - if(palloc.freecol[color] > hw/NCOLOR) + if(palloc.freecount > hw) break; - if(up->kp && palloc.freecol[color] > 0) + if(up->kp && palloc.freecount > 0) break; - palloc.wanted++; unlock(&palloc); dontalloc = 0; if(s && *s) { @@ -89,17 +88,17 @@ retry: *s = 0; dontalloc = 1; } - qlock(&palloc.pwait[color]); /* Hold memory requesters here */ + qlock(&palloc.pwait); /* Hold memory requesters here */ while(waserror()) /* Ignore interrupts */ ; kickpager(); - tsleep(&palloc.r[color], ispages, (void*)color, 1000); + tsleep(&palloc.r, ispages, 0, 1000); poperror(); - qunlock(&palloc.pwait[color]); + qunlock(&palloc.pwait); /* * If called from fault and we lost the segment from @@ -111,15 +110,18 @@ retry: return 0; lock(&palloc); - palloc.wanted--; } + /* First try for out colour */ for(p = palloc.head; p; p = p->next) if(p->color == color) break; - if(p == 0) - panic("newpage"); + if(p == 0) { + p = palloc.head; + memset(p->cachectl, PG_DATFLUSH, sizeof(p->cachectl)); + p->color = color; + } if(p->prev) p->prev->next = p->next; @@ -132,12 +134,15 @@ retry: palloc.tail = p->prev; - palloc.freecol[color]--; + palloc.freecount--; unlock(&palloc); lock(p); if(p->ref != 0) { /* lookpage has priority on steal */ unlock(p); + print("stolen\n"); + lock(&palloc); + palloc.freecount++; goto retry; } @@ -161,17 +166,13 @@ retry: int ispages(void *p) { - int color; - - color = (int)p; - return palloc.freecol[color] >= swapalloc.highwater/NCOLOR; + USED(p); + return palloc.freecount >= swapalloc.highwater; } void putpage(Page *p) { - Rendez *r; - if(onswap(p)) { putswap(p); return; @@ -209,10 +210,9 @@ putpage(Page *p) p->prev = 0; } - palloc.freecol[p->color]++; - r = &palloc.r[p->color]; - if(r->p != 0) - wakeup(r); + palloc.freecount++; + if(palloc.r.p != 0) + wakeup(&palloc.r); unlock(&palloc); unlock(p); @@ -225,13 +225,13 @@ auxpage() lock(&palloc); p = palloc.head; - if(palloc.freecol[p->color] < swapalloc.highwater/NCOLOR) { + if(palloc.freecount < swapalloc.highwater) { unlock(&palloc); return 0; } p->next->prev = 0; palloc.head = p->next; - palloc.freecol[p->color]--; + palloc.freecount--; unlock(&palloc); lock(p); @@ -259,7 +259,7 @@ duppage(Page *p) /* Always call with p locked */ lock(&palloc); /* No freelist cache when memory is very low */ - if(palloc.freecol[p->color] < swapalloc.highwater/NCOLOR) { + if(palloc.freecount < swapalloc.highwater) { unlock(&palloc); uncachepage(p); return; @@ -419,7 +419,7 @@ lookpage(Image *i, ulong daddr) else palloc.tail = f->prev; - palloc.freecol[f->color]--; + palloc.freecount--; } unlock(&palloc); diff --git a/port/portdat.h b/port/portdat.h index 32f2352eceec531d894f53ccb9c9d7e22084f879..d198f4201d59ea41c7cee43803c83673bc0f3b48 100644 --- a/port/portdat.h +++ b/port/portdat.h @@ -455,13 +455,12 @@ struct Palloc ulong np0, np1; /* number of pages in bank 0/1 */ Page *head; /* most recently used */ Page *tail; /* least recently used */ - ulong freecol[NCOLOR]; /* how many pages on free list now */ + ulong freecount; /* how many pages on free list now */ ulong user; /* how many user pages */ Page *hash[PGHSIZE]; Lock hashlock; - Rendez r[NCOLOR]; /* Sleep for free mem */ - QLock pwait[NCOLOR]; /* Queue of procs waiting for memory */ - int wanted; /* Do the wakeup at free */ + Rendez r; /* Sleep for free mem */ + QLock pwait; /* Queue of procs waiting for memory */ ulong cmembase; /* Key memory */ ulong cmemtop; }; diff --git a/port/swap.c b/port/swap.c index 18212ba2a46008c08347be997ba47f53f0c6fcb1..3dd2b669d7fc2739acb116fa850167d8f04e3848 100644 --- a/port/swap.c +++ b/port/swap.c @@ -118,7 +118,9 @@ loop: if(p->state == Dead || p->kp) continue; - /* don't swap out programs from devroot.c */ + /* don't swap out programs from devroot.c - they + * supply important system services + */ img = p->seg[SG_TEXT]->image; if(img && devchar[img->c->type] == '/') continue; @@ -155,9 +157,8 @@ loop: /* Emulate the old system if no swap channel */ print("no physical memory\n"); - tsleep(&swapalloc.r, return0, 0, 1000); - for(i = 0; i < NCOLOR; i++) - wakeup(&palloc.r[i]); + tsleep(&swapalloc.r, return0, 0, 5000); + wakeup(&palloc.r); } } goto loop; @@ -326,13 +327,8 @@ executeio(void) int needpages(void *p) { - int i; - USED(p); - for(i = 0; i < NCOLOR; i++) - if(palloc.freecol[i] < swapalloc.headroom/NCOLOR) - return 1; - return 0; + return palloc.freecount < swapalloc.headroom; } void