From 0f159a0b4666fa40f2a4a9827aabb1528a24d92e Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Fri, 19 Jun 1992 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1992-06-19 --- port/alloc.c | 248 +++++++++++++++++++++++++++++++++++-------- port/chan.c | 7 +- port/dev.c | 2 - port/devarp.c | 2 +- port/devcons.c | 3 + port/devip.c | 1 - port/devmnt.c | 1 - port/devpipe.c | 1 - port/devproc.c | 5 - port/fcall.c | 2 +- port/malloc.c | 85 --------------- port/net.c | 2 - port/page.c | 274 ++++++++++-------------------------------------- port/pgrp.c | 224 ++++++--------------------------------- port/portdat.h | 9 +- port/portfns.h | 12 ++- port/proc.c | 5 +- port/segment.c | 61 +++-------- port/stfcall.c | 2 - port/stream.c | 180 ++++--------------------------- port/swap.c | 2 +- port/sysfile.c | 1 - port/tcpinput.c | 40 +------ ss/dat.h | 2 +- ss/fns.h | 2 + ss/main.c | 10 +- ss/mmu.c | 18 +++- 27 files changed, 375 insertions(+), 826 deletions(-) delete mode 100644 port/malloc.c diff --git a/port/alloc.c b/port/alloc.c index 69fbe90c9d0f0b2c44fec9cd95eb2a3b18a53f0e..48a04ec14c689c33285eda3bf80d93c6cae0ab6d 100644 --- a/port/alloc.c +++ b/port/alloc.c @@ -3,18 +3,25 @@ #include "mem.h" #include "dat.h" #include "fns.h" -#define nil ((void*)0) -#define datoff ((int)&((Xhdr*)0)->data) + +#define nil ((void*)0) +#define datoff ((ulong)&((Xhdr*)0)->data) +#define bdatoff ((ulong)&((Bucket*)0)->data) enum { - Nhole = 128, - Magic = 0xDeadBabe, + Maxpow = 16, + Nhole = 128, + Magichole = 0xDeadBabe, + Magic2n = 0xBadC0c0a, }; typedef struct Hole Hole; typedef struct Xalloc Xalloc; typedef struct Xhdr Xhdr; +typedef struct Bucket Bucket; +typedef struct Arena Arena; + struct Hole { ulong addr; @@ -38,62 +45,95 @@ struct Xalloc Hole *table; }; -Xalloc xlists; +struct Bucket +{ + int size; + int magic; + Bucket *next; + char data[1]; +}; + +struct Arena +{ + Lock; + Bucket *btab[Maxpow]; +}; + +static Arena arena; +static Xalloc xlists; + +void* +ialloc(ulong size, int align) +{ + ulong p; + + if(align) { + size += BY2PG; + p = (ulong)xalloc(size); + p += BY2PG; + p &= ~(BY2PG-1); + return (void*)p; + } + + return xalloc(size); +} + +void* +iallocspan(ulong size, int quanta, ulong span) +{ + return ialloc(size, quanta); +} void xinit(void) { + ulong ktop; Hole *h, *eh; + int up, np0, np1; eh = &xlists.hole[Nhole-1]; for(h = xlists.hole; h < eh; h++) h->link = h+1; - xlists.flist = h; -} + xlists.flist = xlists.hole; -void -xhole(ulong addr, ulong size) -{ - Hole *h, **l; + ktop = PGROUND((ulong)end); + ktop = PADDR(ktop); + conf.npage0 -= ktop/BY2PG; + conf.base0 += ktop; - lock(&xlists); - l = &xlists.table; - for(h = *l; h; h = h->link) { - if(h->top == addr) { - h->size += size; - h->top = h->addr+h->size; - unlock(&xlists); - return; - } - if(h->addr > addr) - break; - l = &h->link; - } + up = conf.upages; + np1 = up; + if(np1 > conf.npage1) + np1 = conf.npage1; - if(xlists.flist == nil) { - print("xfree: no free holes, leaked %d bytes\n", size); - unlock(&xlists); - return; - } + palloc.p1 = conf.base1; + conf.base1 += np1*BY2PG; + conf.npage1 -= np1; + xhole(conf.base1, conf.npage1*BY2PG); + up -= np1; - h = xlists.flist; - xlists.flist = h->link; - h->addr = addr; - h->top = addr+size; - h->size = size; - h->link = *l; - *l = h; - unlock(&xlists); + np0 = up; + if(np0 > conf.npage0) + np0 = conf.npage0; + + palloc.p0 = conf.base0; + conf.base0 += np0*BY2PG; + conf.npage0 -= np0; + xhole(conf.base0, conf.npage0*BY2PG); + + palloc.np0 = np0; + palloc.np1 = np1; } void* xalloc(ulong size) { - Hole *h, **l; Xhdr *p; + Hole *h, **l; - size += sizeof(Xhdr); + size += BY2WD + sizeof(Xhdr); + size &= ~(BY2WD-1); lock(&xlists); l = &xlists.table; @@ -107,7 +147,9 @@ xalloc(ulong size) h->link = xlists.flist; xlists.flist = h; } - p->magix = Magic; + p = KADDR(p); + memset(p, 0, size); + p->magix = Magichole; p->size = size; unlock(&xlists); return p->data; @@ -124,10 +166,64 @@ xfree(void *p) Xhdr *x; x = (Xhdr*)((ulong)p - datoff); - if(x->magix != Magic) + if(x->magix != Magichole) panic("xfree"); - xhole((ulong)x, x->size); + xhole(PADDR(x), x->size); +} + +void +xhole(ulong addr, ulong size) +{ + ulong top; + Hole *h, *c, **l; + + if(size == 0) + return; + + top = addr + size; + lock(&xlists); + l = &xlists.table; + for(h = *l; h; h = h->link) { + if(h->top == addr) { + h->size += size; + h->top = h->addr+h->size; + c = h->link; + if(c && h->top == c->addr) { + h->top += c->size; + h->size += c->size; + h->link = c->link; + c->link = xlists.flist; + xlists.flist = c; + } + unlock(&xlists); + return; + } + if(h->addr > addr) + break; + l = &h->link; + } + if(h && top == h->addr) { + h->addr -= size; + h->size += size; + unlock(&xlists); + return; + } + + if(xlists.flist == nil) { + unlock(&xlists); + print("xfree: no free holes, leaked %d bytes\n", size); + return; + } + + h = xlists.flist; + xlists.flist = h->link; + h->addr = addr; + h->top = top; + h->size = size; + h->link = *l; + *l = h; + unlock(&xlists); } void @@ -143,8 +239,74 @@ xsummary(void) print("%d holes free\n", i); i = 0; for(h = xlists.table; h; h = h->link) { - print("%lux %lux %d\n", h->addr, h->top, h->size); + print("%.8lux %.8lux %d\n", h->addr, h->top, h->size); i += h->size; } print("%d bytes free\n", i); } + +void* +malloc(ulong size) +{ + int pow; + Bucket *bp; + + for(pow = 1; pow < Maxpow; pow++) + if(size <= (1<next; + unlock(&arena); + + if(bp->magic != 0) + panic("malloc"); + + bp->magic = Magic2n; + + memset(bp->data, 0, size); + return bp->data; + } + unlock(&arena); + size = sizeof(Bucket)+(1<size = pow; + bp->magic = Magic2n; + return bp->data; +} + +void* +smalloc(ulong size) +{ + void *p; + + p = malloc(size); + if(p == nil) + panic("smalloc should sleep"); + return p; +} + +void +free(void *ptr) +{ + Bucket *bp, **l; + + bp = (Bucket*)((ulong)ptr - bdatoff); + if(bp->magic != Magic2n) + panic("free"); + + bp->magic = 0; + lock(&arena); + l = &arena.btab[bp->size]; + bp->next = *l; + *l = bp; + unlock(&arena); +} diff --git a/port/chan.c b/port/chan.c index a640c50188a11978ea5e8236ebb25cdd8a5da269..b65d3ac93bb77144ac7a9f34a09273e333bafef7 100644 --- a/port/chan.c +++ b/port/chan.c @@ -91,7 +91,6 @@ newchan(void) c->mnt = 0; c->stream = 0; c->aux = 0; - c->mntindex = 0; c->mchan = 0; c->mqid = (Qid){0, 0}; return c; @@ -178,7 +177,7 @@ mount(Chan *new, Chan *old, int flag) } if(m == 0) { - m = newmnthead(); + m = smalloc(sizeof(Mhead)); m->from = old; incref(old); m->hash = *l; @@ -238,7 +237,7 @@ unmount(Chan *mnt, Chan *mounted) wunlock(&pg->ns); mountfree(m->mount); close(m->from); - mntheadfree(m); + free(m); return; } @@ -252,7 +251,7 @@ unmount(Chan *mnt, Chan *mounted) *l = m->hash; wunlock(&pg->ns); close(m->from); - mntheadfree(m); + free(m); return; } wunlock(&pg->ns); diff --git a/port/dev.c b/port/dev.c index 8e5c24977e68f08e11db965762d0304baacbd163..fc55c6fd7ea1a0cb52d9033a6fa7b044f39fc664 100644 --- a/port/dev.c +++ b/port/dev.c @@ -7,8 +7,6 @@ #define DEVTAB #include "devtab.h" -#include "fcall.h" - extern ulong kerndate; int diff --git a/port/devarp.c b/port/devarp.c index 152fdbdeadaa4cf6d3d68dba6a71e901909b3c34..d9e70b4e3338f8b6ec1dc7784cc68fe905df0427 100644 --- a/port/devarp.c +++ b/port/devarp.c @@ -332,7 +332,7 @@ arpoput(Queue *q, Block *bp) /* if ip broadcast, use ether bcast address */ addr = nhgetl(eh->dst); - if(addr == Myip[Mybcast] || addr == Myip[Mynet] + if(Myip[Myself] == 0 || addr == Myip[Mybcast] || addr == Myip[Mynet] || ((addr & Mymask) == Myip[Mynet+1] && (addr & ~Mynetmask) == ~Mynetmask)){ memset(eh->d, 0xff, sizeof(eh->d)); PUTNEXT(q, bp); diff --git a/port/devcons.c b/port/devcons.c index 2ecbc27cc2817f236c1d2a0990807baa7329d84a..44d207c172981a0276cbc057ffe82592a64a9969 100644 --- a/port/devcons.c +++ b/port/devcons.c @@ -228,6 +228,9 @@ echo(Rune r, char *buf, int n) switch(r){ case 0x14: break; /* pass it on */ + case 'x': + xsummary(); + break; case 'd': consdebug(); return; diff --git a/port/devip.c b/port/devip.c index 62df1310a8d6f1c185e542fc2d297308c1811e37..f1230dbb8a9fe25092bb95187943d69069cf5137 100644 --- a/port/devip.c +++ b/port/devip.c @@ -93,7 +93,6 @@ ipreset(void) } initfrag(conf.frag); - tcpinit(); } void diff --git a/port/devmnt.c b/port/devmnt.c index f770895af74c5bc9a9e4a1d9a3a27826545ee009..3f3a4a731a28aa548e8029ad8864adea39159587 100644 --- a/port/devmnt.c +++ b/port/devmnt.c @@ -5,7 +5,6 @@ #include "fns.h" #include "../port/error.h" #include "devtab.h" -#include "fcall.h" typedef struct Mntrpc Mntrpc; typedef struct Mnt Mnt; diff --git a/port/devpipe.c b/port/devpipe.c index ff2d0820a4f6a872ee34628cf57c8f0fa380faf6..67d55f655949f936ecc25ce83e27005d69fcde58 100644 --- a/port/devpipe.c +++ b/port/devpipe.c @@ -6,7 +6,6 @@ #include "../port/error.h" #include "devtab.h" -#include "fcall.h" typedef struct Pipe Pipe; diff --git a/port/devproc.c b/port/devproc.c index 0bd30078edbdacd1822ab2bd4aaec54d565b4e32..025d29d6e04437607d66effa37bbc9e3e6983008 100644 --- a/port/devproc.c +++ b/port/devproc.c @@ -4,7 +4,6 @@ #include "dat.h" #include "fns.h" #include "../port/error.h" -#include "fcall.h" #include "ureg.h" #include "devtab.h" @@ -264,10 +263,6 @@ procread(Chan *c, void *va, long n, ulong offset) } if(offset >= KZERO) { - /* prevent users reading authentication crypt keys */ - if(offset >= pgrpalloc.cryptbase) - if(offset < pgrpalloc.crypttop) - error(Eperm); /* validate physical kernel addresses */ if(offset < KZERO+conf.npage0*BY2PG){ if(offset+n > KZERO+conf.npage0*BY2PG) diff --git a/port/fcall.c b/port/fcall.c index 21e7804d112d0fd6ed16bc34bf6cab3a1c2b4efa..2dc632e9c9b83e565cf1eff1f3b60d78ec28015b 100644 --- a/port/fcall.c +++ b/port/fcall.c @@ -1,6 +1,6 @@ #include #include -#include +#include "fcall.h" #define CHAR(x) *p++ = f->x #define SHORT(x) p[0] = f->x; p[1] = f->x>>8; p += 2 diff --git a/port/malloc.c b/port/malloc.c deleted file mode 100644 index 71f86f57e6e4a7ddff024de8d72148055c4fc079..0000000000000000000000000000000000000000 --- a/port/malloc.c +++ /dev/null @@ -1,85 +0,0 @@ -#include -#include - -enum -{ - MAGIC = 0xDEADBABE, - MAXPOW = 20 -}; - -typedef struct Bucket Bucket; -struct Bucket -{ - int size; - int magic; - Bucket *next; - char data[1]; -}; - -typedef struct Arena Arena; -struct Arena -{ - Lock; - Bucket *btab[MAXPOW]; -}; -static Arena arena; -#define datoff ((int)&((Bucket*)0)->data) - -void* -malloc(uint size) -{ - int pow; - Bucket *bp; - - size += sizeof(Bucket); - - for(pow = 1; pow < MAXPOW; pow++) - if(size <= (1<next; - arena.unlock(); - - if(bp->magic != 0) - panic("malloc"); - - bp->magic = MAGIC; - - memset(bp->data, 0, size); - return bp->data; - } - unlock(&arena); - - size = sizeof(Bucket)+(1<data, 0, size); - return bp->data; -} - -void -free(void *ptr) -{ - Bucket *bp, **l; - - /* Find the start of the structure */ - bp = (Bucket*)((uint)ptr - datoff); - - if(bp->magic != MAGIC) - panic("free"); - - bp->magic = 0; - lock(&arena); - l = &arena.btab[bp->size]; - bp->next = *l; - *l = bp; - unlock(&arena); -} diff --git a/port/net.c b/port/net.c index 194fd987618cd1c3ec5060f5011206de89ad128f..393e50d48b4a2b3504551d146b25daf79d82196c 100644 --- a/port/net.c +++ b/port/net.c @@ -5,8 +5,6 @@ #include "fns.h" #include "../port/error.h" -#include "fcall.h" - enum { Qlisten= 1, diff --git a/port/page.c b/port/page.c index e87c9b8995f90d7574b346d164f43adbc39a7d95..0c2230e07c53ed49a29ea9e0ec36a54cce163a12 100644 --- a/port/page.c +++ b/port/page.c @@ -8,8 +8,6 @@ #define PGHFUN(x, y) (((ulong)x^(ulong)y)%PGHSIZE) #define pghash(s) palloc.hash[PGHFUN(s->image, p->daddr)] -struct Palloc palloc; - struct Ptealloc { Lock; @@ -17,240 +15,55 @@ struct Ptealloc int pages; }ptealloclk; -ulong hiaddr; -static Lock pglock; - -/* Multiplex a hardware lock for per page manipulations */ -void -lockpage(Page *p) -{ - int s; - - for(;;) { - if(p->lock == 0) { - s = splhi(); - lock(&pglock); - if(p->lock == 0) { - p->lock = 1; - unlock(&pglock); - splx(s); - return; - } - unlock(&pglock); - splx(s); - } - sched(); - } -} - -void -unlockpage(Page *p) -{ - p->lock = 0; -} - -typedef struct Region Region; -struct Region -{ - ulong start; - ulong end; -}; - -enum -{ - Nregion= 10, -}; -Region region[Nregion]; - - -void -addsplit(Region *r, ulong start, ulong end) -{ - int len; - Region *rr, *eregion; - - len = end - start; - eregion = ®ion[Nregion]; - - /* first look for an unused one */ - for(rr = region; rr < eregion; rr++){ - if(rr == r) - continue; - if(rr->end - rr->start == 0){ - rr->start = start; - rr->end = end; - return; - } - } - - /* then look for a smaller one */ - for(rr = region; rr < eregion; rr++){ - if(rr == r) - continue; - if(rr->end - rr->start < len){ - rr->start = start; - rr->end = end; - return; - } - } -} - -/* - * Called to allocate permanent data structures, before calling pageinit(). - * We assume all of text+data+bss is in the first memory bank. - * - * alignment is in number of bytes. It pertains both to the start and - * end of the allocated memory. - * - * If crevasse is specified, no allocation can span an address that is - * a multiple of crevasse. - */ -void* -iallocspan(ulong n, int align, ulong crevasse) -{ - int m; - ulong p; - Region *r; - int ledge; - - if(palloc.active && n!=0) - print("ialloc bad\n"); - - if(palloc.addr0 == 0){ - r = ®ion[Nregion-2]; - r->start = (((ulong)end)&~KZERO) + conf.base0; - r->end = conf.base0 + (conf.npage0<start = conf.base1; - r->end = conf.base1 + (conf.npage1<start; - if(align){ - m = p % align; - if(m) - p += align - m; - } - - /* check for crossing a crevasse */ - if(crevasse){ - ledge = p / crevasse; - if(ledge != ((p+n-1) / crevasse)) - p = ((p+n-1) / crevasse) * crevasse; - } - - /* see if it fits */ - if(p + n > r->end) - continue; - - /* split the region */ - if(p != r->start) - addsplit(r, r->start, p); - r->start = p + n; - break; - } - if(r == ®ion[Nregion]) - panic("out of memory"); - - /* - * remember high water marks - */ - if(palloc.addr0 < r->start && r->start <= conf.base0+(conf.npage0<start; - else if(palloc.addr1 < r->start && r->start <= conf.base1+(conf.npage1<start; - - /* - * zero it - */ - memset((void*)(p|KZERO), 0, n); - return (void*)(p|KZERO); -} - -/* - * allocate with possible page alignment - */ -void* -ialloc(ulong n, int align) -{ - return iallocspan(n, align ? BY2PG : 0, 0); -} +static Lock pglock; +struct Palloc palloc; void pageinit(void) { - ulong np, addr, lim; - ulong i, vmem, pmem, hw, hr; Page *p; + ulong np, hw, hr, vmem, pmem; + + np = palloc.np0+palloc.np1; + palloc.head = xalloc(np*sizeof(Page)); + if(palloc.head == 0) + panic("pageinit"); - /* - * calculate an upper bound to the number of pages structures - * we'll need (np). - */ - np = (conf.npage0<>PGSHIFT; - - /* - * allocate Page structs (no more ialloc's allowed after this). - * np is useless after this ialloc since we've just eaten up - * some pages for the Page structures. - */ - palloc.head = ialloc(np*sizeof(Page), 0); - palloc.active = 1; - - /* - * for each page in each bank, point a page structure to - * the page and chain it into the free list - */ p = palloc.head; - addr = palloc.addr0 = PGROUND(palloc.addr0); - lim = conf.base0 + (conf.npage0<next = p+1; + while(palloc.np0 > 0) { p->prev = p-1; - p->pa = addr; + p->next = p+1; + p->pa = palloc.p0; + palloc.p0 += BY2PG; + palloc.np0--; p++; } - addr = palloc.addr1 = PGROUND(palloc.addr1); - lim = conf.base1 + (conf.npage1<next = p+1; + while(palloc.np1 > 0) { p->prev = p-1; - p->pa = addr; + p->next = p+1; + p->pa = palloc.p1; + palloc.p1 += BY2PG; + palloc.np1--; p++; } palloc.tail = p - 1; palloc.head->prev = 0; palloc.tail->next = 0; - palloc.user = palloc.freecount = p - palloc.head; + palloc.user = p - palloc.head; + palloc.freecount = palloc.user; pmem = palloc.user*BY2PG/1024; - vmem = pmem + ((conf.nswap)*BY2PG)/1024; + vmem = pmem + (conf.nswap*BY2PG)/1024; /* Pageing numbers */ swapalloc.highwater = (palloc.freecount*5)/100; swapalloc.headroom = swapalloc.highwater + (swapalloc.highwater/4); - hw = (swapalloc.highwater*BY2PG)/1024; - hr = (swapalloc.headroom*BY2PG)/1024; + + hw = swapalloc.highwater*BY2PG; + hr = swapalloc.headroom*BY2PG; - print("%lud free pages, %dK bytes, swap %dK bytes, highwater %dK, headroom %dK\n", - palloc.user, pmem, vmem, hw, hr); + print("%lud free pages, %dK bytes, swap %dK, highwater %dK, headroom %dK\n", + palloc.user, pmem, vmem, hw/1024, hr/1024); } Page* @@ -260,13 +73,11 @@ newpage(int clear, Segment **s, ulong va) KMap *k; int i; - if(palloc.active == 0) - print("newpage inactive\n"); - lock(&palloc); /* The kp test is a poor guard against the pager deadlocking */ - while((palloc.freecount < swapalloc.highwater && u->p->kp == 0)||palloc.freecount == 0) { + while((palloc.freecount < swapalloc.highwater && u->p->kp == 0) || + palloc.freecount == 0) { palloc.wanted++; unlock(&palloc); if(s && *s) { @@ -605,3 +416,32 @@ freepte(Segment *s, Pte *p) ptealloclk.free = p; unlock(&ptealloclk); } + +/* Multiplex a hardware lock for per page manipulations */ +void +lockpage(Page *p) +{ + int s; + + for(;;) { + if(p->lock == 0) { + s = splhi(); + lock(&pglock); + if(p->lock == 0) { + p->lock = 1; + unlock(&pglock); + splx(s); + return; + } + unlock(&pglock); + splx(s); + } + sched(); + } +} + +void +unlockpage(Page *p) +{ + p->lock = 0; +} diff --git a/port/pgrp.c b/port/pgrp.c index eb7f90f0aec0d49fc9185f29de8db434a14cb94d..435e2f0c6734a37e841bb8a87da26d4107077127 100644 --- a/port/pgrp.c +++ b/port/pgrp.c @@ -5,73 +5,8 @@ #include "fns.h" #include "../port/error.h" -Pgrps pgrpalloc; - -struct -{ - Lock; - Egrp *free; -}egrpalloc; - -struct -{ - Lock; - Fgrp *free; -}fgrpalloc; - -struct{ - Lock; - Mount *free; - Mhead *mhfree; - ulong mountid; -}mountalloc; - -void -grpinit(void) -{ - int i; - Pgrp *p; - Egrp *e, *ee; - Fgrp *f, *fe; - Mount *m, *em; - Mhead *hm, *hem; - Crypt *cr; - - i = conf.npgrp*sizeof(Crypt); - cr = ialloc(i, 0); - pgrpalloc.cryptbase = (ulong)cr; - pgrpalloc.crypttop = (ulong)cr + i; - pgrpalloc.arena = ialloc(conf.npgrp*sizeof(Pgrp), 0); - pgrpalloc.free = pgrpalloc.arena; - - p = pgrpalloc.free; - for(i=0; iindex = i; - p->next = p+1; - p->crypt = cr++; - } - p[-1].next = 0; - - egrpalloc.free = ialloc(conf.npgrp*sizeof(Egrp), 0); - ee = &egrpalloc.free[conf.npgrp]; - for(e = egrpalloc.free; e < ee; e++) { - e->next = e+1; - e->etab = ialloc(conf.npgenv*sizeof(Env), 0); - } - e[-1].next = 0; - - fgrpalloc.free = ialloc(conf.nproc*sizeof(Fgrp), 0); - fe = &fgrpalloc.free[conf.nproc-1]; - for(f = fgrpalloc.free; f < fe; f++) - f->next = f+1; - f->next = 0; -} - -Pgrp* -pgrptab(int i) -{ - return &pgrpalloc.arena[i]; -} +static Ref pgrpid; +static Ref mountid; void pgrpnote(ulong noteid, char *a, long n, int flag) @@ -109,22 +44,12 @@ newpgrp(void) { Pgrp *p; - for(;;) { - lock(&pgrpalloc); - if(p = pgrpalloc.free){ - pgrpalloc.free = p->next; - p->ref = 1; - p->pgrpid = ++pgrpalloc.pgrpid; - memset(p->crypt, 0, sizeof *p->crypt); - memset(p->rendhash, 0, sizeof(p->rendhash)); - memset(p->mnthash, 0, sizeof(p->mnthash)); - unlock(&pgrpalloc); - return p; - } - unlock(&pgrpalloc); - resrcwait("no pgrps"); - } - return 0; /* not reached */ + p = smalloc(sizeof(Pgrp)+sizeof(Crypt)); + p->ref = 1; + /* This needs to have its own arena for protection */ + p->crypt = (Crypt*)((uchar*)p+sizeof(Pgrp)); + p->pgrpid = incref(&pgrpid); + return p; } Egrp* @@ -132,19 +57,12 @@ newegrp(void) { Egrp *e; - for(;;) { - lock(&egrpalloc); - if(e = egrpalloc.free) { - egrpalloc.free = e->next; - e->ref = 1; - e->nenv = 0; - unlock(&egrpalloc); - return e; - } - unlock(&egrpalloc); - resrcwait("no envgrps"); - } - return 0; /* not reached */ + e = smalloc(sizeof(Egrp)+sizeof(Env)*conf.npgenv); + + /* This is a sleazy hack to make malloc work .. devenv need rewriting. */ + e->etab = (Env*)((uchar*)e+sizeof(Egrp)); + e->ref = 1; + return e; } Fgrp* @@ -152,20 +70,9 @@ newfgrp(void) { Fgrp *f; - for(;;) { - lock(&fgrpalloc); - if(f = fgrpalloc.free) { - fgrpalloc.free = f->next; - f->ref = 1; - f->maxfd = 0; - memset(f->fd, 0, sizeof(f->fd)); - unlock(&fgrpalloc); - return f; - } - unlock(&fgrpalloc); - resrcwait("no filegrps"); - } - return 0; /* not reached */ + f = smalloc(sizeof(Fgrp)); + f->ref = 1; + return f; } Fgrp* @@ -221,15 +128,11 @@ closepgrp(Pgrp *p) close(f->from); mountfree(f->mount); next = f->hash; - mntheadfree(f); + free(f); } } - - lock(&pgrpalloc); - p->next = pgrpalloc.free; - pgrpalloc.free = p; qunlock(&p->debug); - unlock(&pgrpalloc); + free(p); } } @@ -243,10 +146,8 @@ closeegrp(Egrp *eg) e = eg->etab; for(i=0; inenv; i++, e++) envpgclose(e); - lock(&egrpalloc); - eg->next = egrpalloc.free; - egrpalloc.free = eg; - unlock(&egrpalloc); + + free(eg); } } @@ -261,10 +162,7 @@ closefgrp(Fgrp *f) if(c = f->fd[i]) close(c); - lock(&fgrpalloc); - f->next = fgrpalloc.free; - fgrpalloc.free = f; - unlock(&fgrpalloc); + free(f); } } @@ -274,31 +172,12 @@ newmount(Mhead *mh, Chan *to) { Mount *m, *f, *e; - for(;;) { - lock(&mountalloc); - if(m = mountalloc.free){ /* assign = */ - mountalloc.free = m->next; - m->mountid = ++mountalloc.mountid; - unlock(&mountalloc); - m->next = 0; - m->head = mh; - m->to = to; - incref(to); - return m; - } - unlock(&mountalloc); - - m = (Mount*)VA(kmap(newpage(0, 0, 0))); - e = &m[(BY2PG/sizeof(Mount))-1]; - for(f = m; f < e; f++) - f->next = f+1; - - lock(&mountalloc); - e->next = mountalloc.free; - mountalloc.free = m; - unlock(&mountalloc); - } - return 0; /* not reached */ + m = smalloc(sizeof(Mount)); + m->to = to; + m->head = mh; + incref(to); + m->mountid = incref(&mountid); + return m; } void @@ -331,7 +210,7 @@ pgrpcpy(Pgrp *to, Pgrp *from) for(h = from->mnthash; h < e; h++) { l = tom++; for(f = *h; f; f = f->hash) { - mh = newmnthead(); + mh = smalloc(sizeof(Mhead)); mh->from = f->from; incref(mh->from); *l = mh; @@ -347,44 +226,6 @@ pgrpcpy(Pgrp *to, Pgrp *from) runlock(&from->ns); } -Mhead * -newmnthead(void) -{ - Mhead *mh, *f, *e; - - for(;;) { - lock(&mountalloc); - if(mh = mountalloc.mhfree) { /* Assign '=' */ - mountalloc.mhfree = mh->hash; - unlock(&mountalloc); - mh->hash = 0; - mh->mount = 0; - return mh; - } - unlock(&mountalloc); - - mh = (Mhead*)VA(kmap(newpage(0, 0, 0))); - e = &mh[(BY2PG/sizeof(Mhead))-1]; - for(f = mh; f < e; f++) - f->hash = f+1; - - lock(&mountalloc); - e->hash = mountalloc.mhfree; - mountalloc.mhfree = mh; - unlock(&mountalloc); - } - return 0; /* not reached */ -} - -void -mntheadfree(Mhead *mh) -{ - lock(&mountalloc); - mh->hash = mountalloc.mhfree; - mountalloc.mhfree = mh; - unlock(&mountalloc); -} - void mountfree(Mount *m) { @@ -392,9 +233,8 @@ mountfree(Mount *m) for(f = m; f->next; f = f->next) close(f->to); + close(f->to); - lock(&mountalloc); - f->next = mountalloc.free; - mountalloc.free = m; - unlock(&mountalloc); + + free(f); } diff --git a/port/portdat.h b/port/portdat.h index 41eb669e3ee876c31fea2aa235bd113425ad07d7..44b4b39fc63e7b768711c8bcb22033470b6ac54b 100644 --- a/port/portdat.h +++ b/port/portdat.h @@ -38,6 +38,8 @@ typedef struct Talarm Talarm; typedef struct Waitq Waitq; typedef int Devgen(Chan*, Dirtab*, int, int, Dir*); +#include "fcall.h" + struct List { void *next; @@ -394,7 +396,6 @@ struct Pgrp struct Egrp { Ref; - Egrp *next; int nenv; /* highest active env table entry, +1 */ QLock ev; /* for all of etab */ Env *etab; @@ -404,7 +405,6 @@ struct Egrp struct Fgrp { Ref; - Fgrp *next; Chan *fd[NFD]; int maxfd; /* highest fd in use */ }; @@ -413,9 +413,8 @@ struct Fgrp struct Palloc { Lock; - ulong addr0; /* next available ialloc addr in bank 0 */ - ulong addr1; /* next available ialloc addr in bank 1 */ - int active; + ulong p0, p1; /* base of pages in bank 0/1 */ + ulong np0, np1; /* number of pages in bank 0/1 */ Page *head; /* most recently used */ Page *tail; /* least recently used */ ulong freecount; /* how many pages on free list now */ diff --git a/port/portfns.h b/port/portfns.h index 4f42a542cfead5f67773007580dcd24981c01333..69fb0b475927abf7dfe3f61c1743f8d5c28b2913 100644 --- a/port/portfns.h +++ b/port/portfns.h @@ -84,7 +84,6 @@ Block* getq(Queue*); int gets(IOQ*, void*, int); void gotolabel(Label*); Block* grabq(Queue*); -void grpinit(void); int hwcursmove(int, int); int hwcursset(uchar*, uchar*, int, int); void* ialloc(ulong, int); @@ -232,7 +231,6 @@ long streamwrite(Chan*, void*, long, int); long stringread(void*, long, char*, ulong); void swapinit(void); long syscall(Ureg*); -void tcpinit(void); void tsleep(Rendez*, int (*)(void*), void*, int); void uncachepage(Page*); long unionread(Chan*, void*, long); @@ -248,8 +246,14 @@ void rlock(RWlock*); void runlock(RWlock*); void wlock(RWlock*); void wunlock(RWlock*); -Mhead* newmnthead(void); void mountfree(Mount*); -void mntheadfree(Mhead*); void unmount(Chan*, Chan*); void urpfillstats(Chan*, char*, int); +void xinit(void); +void *xalloc(ulong); +void xfree(void*); +void xhole(ulong, ulong); +void xsummary(void); +void *malloc(ulong); +void *smalloc(ulong); +void free(void*); diff --git a/port/proc.c b/port/proc.c index 71ec0dd10cb3e2ee5f8728e55ac62fe78ff51f13..ca1f45f62c5fba105c76aaa9763875ce9e5f14f1 100644 --- a/port/proc.c +++ b/port/proc.c @@ -62,7 +62,8 @@ schedinit(void) /* never returns */ u = 0; if(p->state == Running) ready(p); - else if(p->state == Moribund) { + else + if(p->state == Moribund) { p->pid = 0; /* * Holding locks from pexit: @@ -244,7 +245,7 @@ procinit0(void) /* bad planning - clashes with devproc.c */ Proc *p; int i; - procalloc.free = ialloc(conf.nproc*sizeof(Proc), 0); + procalloc.free = xalloc(conf.nproc*sizeof(Proc)); procalloc.arena = procalloc.free; p = procalloc.free; diff --git a/port/segment.c b/port/segment.c index c3caadb8e9f2c6b81ec6611b12db192e93c22ab4..6d6fdfd0ac7c16374f6ff14b069ebd79962152e6 100644 --- a/port/segment.c +++ b/port/segment.c @@ -22,12 +22,6 @@ struct Imagealloc Image *hash[IHASHSIZE]; }imagealloc; -struct segalloc -{ - Lock; - Segment *free; -}segalloc; - static QLock ireclaim; void @@ -36,14 +30,7 @@ initseg(void) Segment *s, *se; Image *i, *ie; - segalloc.free = ialloc(conf.nseg*sizeof(Segment), 0); - imagealloc.free = ialloc(conf.nimage*sizeof(Image), 0); - - se = &segalloc.free[conf.nseg-1]; - for(s = segalloc.free; s < se; s++) - s->next = s+1; - s->next = 0; - + imagealloc.free = xalloc(conf.nimage*sizeof(Image)); ie = &imagealloc.free[conf.nimage-1]; for(i = imagealloc.free; i < ie; i++) i->next = i+1; @@ -58,32 +45,13 @@ newseg(int type, ulong base, ulong size) if(size > (SEGMAPSIZE*PTEPERTAB)) error(Enovmem); - for(;;) { - lock(&segalloc); - if(s = segalloc.free) { - segalloc.free = s->next; - unlock(&segalloc); - - s->ref = 1; - s->steal = 0; - s->type = type; - s->base = base; - s->top = base+(size*BY2PG); - s->size = size; - s->image = 0; - s->fstart = 0; - s->flen = 0; - s->pgalloc = 0; - s->pgfree = 0; - s->flushme = 0; - memset(s->map, 0, sizeof(s->map)); - - return s; - } - unlock(&segalloc); - resrcwait("no segments"); - } - return 0; /* not reached */ + s = smalloc(sizeof(Segment)); + s->ref = 1; + s->type = type; + s->base = base; + s->top = base+(size*BY2PG); + s->size = size; + return s; } void @@ -117,10 +85,7 @@ putseg(Segment *s) qunlock(&s->lk); - lock(&segalloc); - s->next = segalloc.free; - segalloc.free = s; - unlock(&segalloc); + free(s); } } @@ -237,10 +202,10 @@ attachimage(int type, Chan *c, ulong base, ulong len) for(i = ihash(c->qid.path); i; i = i->hash) { if(c->qid.path == i->qid.path) { lock(i); - if(eqqid(c->qid, i->qid)) - if(eqqid(c->mqid, i->mqid)) - if(c->mchan == i->mchan) - if(c->type == i->type) { + if(eqqid(c->qid, i->qid) && + eqqid(c->mqid, i->mqid) && + c->mchan == i->mchan && + c->type == i->type) { i->ref++; goto found; } diff --git a/port/stfcall.c b/port/stfcall.c index 1714ddc0261be2cfb6dc807d6fb47c993fe0288b..7cb60c03075e6a82ab24eb4bc187315b793c3fc8 100644 --- a/port/stfcall.c +++ b/port/stfcall.c @@ -5,8 +5,6 @@ #include "fns.h" #include "../port/error.h" -#include "fcall.h" - enum { Twritehdr = 15, /* Min bytes for Twrite */ diff --git a/port/stream.c b/port/stream.c index a404ef6d85e2607c573953d448c3dcb3ddfc66f4..b0578f243b9291dda9d8e6c520687626bf794055 100644 --- a/port/stream.c +++ b/port/stream.c @@ -6,7 +6,6 @@ #include "io.h" #include "../port/error.h" #include "devtab.h" -#include "fcall.h" enum { Nclass=4, /* number of block classes */ @@ -30,30 +29,10 @@ Qinfo procinfo = */ static Qinfo *lds; -/* - * All stream structures are ialloc'd at boot time - */ Stream *slist; Queue *qlist; static Lock garbagelock; -/* - * The block classes. There are Nclass block sizes, each with its own free list. - * All are ialloced at qinit() time. - */ -typedef struct { - int size; - int made; - QLock; - Blist; -} Bclass; -Bclass bclass[Nclass]={ - { 0 }, - { 68 }, - { 268 }, - { 4096 }, -}; - /* * Allocate streams, queues, and blocks. Allocate n block classes with * 1/2(m+1) to class m < n-1 @@ -62,25 +41,12 @@ Bclass bclass[Nclass]={ void streaminit(void) { - int class, i, n; - Bclass *bcp; /* * allocate queues, streams */ - slist = (Stream *)ialloc(conf.nstream * sizeof(Stream), 0); - qlist = (Queue *)ialloc(conf.nqueue * sizeof(Queue), 0); - - /* - * set block classes - */ - n = conf.nblock; - for(class = 0; class < Nclass; class++){ - if(class < Nclass-1) - n = n/2; - bcp = &bclass[class]; - bcp->made = 0; - } + slist = (Stream *)xalloc(conf.nstream * sizeof(Stream)); + qlist = (Queue *)xalloc(conf.nqueue * sizeof(Queue)); /* * make stream modules available @@ -104,70 +70,6 @@ newqinfo(Qinfo *qi) (*qi->reset)(); } -/* - * upgrade a block 0 block to another class (called with bcp qlocked) - */ -int -newblock(Bclass *bcp) -{ - Page *page; - int n; - Block *bp; - uchar *cp; - - page = newpage(1, 0, 0); - page->va = VA(kmapperm(page)); - if(bcp == bclass){ - /* - * create some level zero blocks and return - */ - n = BY2PG/sizeof(Block); - bp = (Block *)(page->va); - while(n-- > 0){ - bp->flags = 0; - bp->base = bp->lim = bp->rptr = bp->wptr = 0; - if(bcp->first) - bcp->last->next = bp; - else - bcp->first = bp; - bcp->last = bp; - bcp->made++; - bp++; - } - } else { - /* - * create a page worth of new blocks - */ - n = BY2PG/bcp->size; - cp = (uchar *)(page->va); - - while(n-- > 0){ - /* - * upgrade a level 0 block - */ - bp = allocb(0); - qlock(bclass); - bclass->made--; - bcp->made++; - bp->flags = bcp - bclass; - qunlock(bclass); - - /* - * tack on the data area - */ - bp->base = bp->rptr = bp->wptr = cp; - cp += bcp->size; - bp->lim = cp; - if(bcp->first) - bcp->last->next = bp; - else - bcp->first = bp; - bcp->last = bp; - } - } - return 0; -} - /* * allocate a block */ @@ -175,37 +77,16 @@ Block * allocb(ulong size) { Block *bp; - Bclass *bcp; + uchar *data; - /* - * map size to class - */ - for(bcp=bclass; bcp->sizefirst == 0){ - if(waserror()){ - qunlock(bcp); - nexterror(); - } - newblock(bcp); - poperror(); - } - bp = bcp->first; - bcp->first = bp->next; - if(bcp->first == 0) - bcp->last = 0; - qunlock(bcp); - - /* - * return an empty block - */ - bp->flags = bcp - bclass; - bp->rptr = bp->wptr = bp->base; + data = (uchar*)bp + sizeof(Block); + bp->rptr = data; + bp->wptr = data; + bp->base = data; + bp->lim = data+size; + bp->flags = 0; bp->next = 0; bp->list = 0; bp->type = M_DATA; @@ -219,31 +100,14 @@ allocb(ulong size) void freeb(Block *bp) { - ulong mark[1]; - Block *nbp; - Bclass *bcp; - int x; - ulong pc; - -#ifdef asdf - pc = getcallerpc(((uchar*)&bp) - sizeof(bp)); - if((bp->flags&S_CLASS) >= Nclass) /* Check for double free */ - panic("freeb class last(%lux) this(%lux)", bp->pc, pc); - bp->pc = pc; -#endif asdf - for(; bp; bp = nbp){ - bcp = &bclass[bp->flags & S_CLASS]; - bp->flags = bp->flags|S_CLASS; /* Check for double free */ - qlock(bcp); - bp->rptr = bp->wptr = 0; - if(bcp->first) - bcp->last->next = bp; - else - bcp->first = bp; - bcp->last = bp; - nbp = bp->next; - bp->next = 0; - qunlock(bcp); + Block *next; + + while(bp){ + bp->rptr = 0; + bp->wptr = 0; + next = bp->next; + free(bp); + bp = next; } } @@ -1497,7 +1361,6 @@ dumpqueues(void) Queue *q; int count, qcount; Block *bp; - Bclass *bcp; print("\n"); qcount = 0; @@ -1516,11 +1379,4 @@ dumpqueues(void) dumpblocks(WR(q), 'W'); } print("%d queues\n", qcount); - for(bcp=bclass; bcp<&bclass[Nclass]; bcp++){ - for(count = 0, bp = bcp->first; bp; count++, bp = bp->next) - ; - print("%d byte blocks: %d made %d free\n", bcp->size, - bcp->made, count); - } - print("\n"); } diff --git a/port/swap.c b/port/swap.c index f02fcbcc3de49bfcfd1d9f854504605f053b30e0..f6a3ec2f6ae1062d27f8eb9ebc398747f00a64de 100644 --- a/port/swap.c +++ b/port/swap.c @@ -26,7 +26,7 @@ int ioptr; void swapinit(void) { - swapalloc.swmap = ialloc(conf.nswap, 0); + swapalloc.swmap = xalloc(conf.nswap); swapalloc.top = &swapalloc.swmap[conf.nswap]; swapalloc.alloc = swapalloc.swmap; diff --git a/port/sysfile.c b/port/sysfile.c index 82968fe73279317423f1370612196b6357fd7dc9..d1585120dd0a53fb358bf061caf82ac70403dc6d 100644 --- a/port/sysfile.c +++ b/port/sysfile.c @@ -4,7 +4,6 @@ #include "dat.h" #include "fns.h" #include "../port/error.h" -#include "fcall.h" /* * The sys*() routines needn't poperror() as they return directly to syscall(). diff --git a/port/tcpinput.c b/port/tcpinput.c index 890463bf2cd4461e56e23a7dba8f39a26ca4e9a3..f872bf35dd4f62976e3d97def0d5fc92b2faa7e7 100644 --- a/port/tcpinput.c +++ b/port/tcpinput.c @@ -11,26 +11,11 @@ int tcpdbg = 0; #define DPRINT if(tcpdbg) print #define LPRINT if(tcpdbg) print -QLock reseqlock; -Reseq *reseqfree; - char *tcpstate[] = { "Closed", "Listen", "Syn_sent", "Syn_received", "Established", "Finwait1", "Finwait2", "Close_wait", "Closing", "Last_ack", "Time_wait" }; -void -tcpinit(void) -{ - Reseq *r; - - reseqfree = ialloc(sizeof(Reseq)*Nreseq, 0); - for(r = reseqfree; r < &reseqfree[Nreseq-1]; r++) - r->next = r+1; - - r->next = 0; -} - void reset(Ipaddr source, Ipaddr dest, char tos, ushort length, Tcp *seg) { @@ -624,20 +609,10 @@ void add_reseq(Tcpctl *tcb, char tos, Tcp *seg, Block *bp, ushort length) { Reseq *rp, *rp1; - static int dropped; - qlock(&reseqlock); - if(!reseqfree) { - qunlock(&reseqlock); - if((dropped++%256) == 0) - print("tcp: no resequence descriptors\n"); - freeb(bp); + rp = malloc(sizeof(Reseq)); + if(rp == 0) return; - } - - rp = reseqfree; - reseqfree = rp->next; - qunlock(&reseqlock); rp->seg = *seg; rp->tos = tos; @@ -677,10 +652,7 @@ get_reseq(Tcpctl *tcb, char *tos, Tcp *seg, Block **bp, ushort *length) *bp = rp->bp; *length = rp->length; - qlock(&reseqlock); - rp->next = reseqfree; - reseqfree = rp; - qunlock(&reseqlock); + free(rp); } int @@ -874,11 +846,7 @@ close_self(Ipconv *s, char reason[]) for(rp = tcb->reseq;rp != 0;rp = rp1){ rp1 = rp->next; freeb(rp->bp); - - qlock(&reseqlock); - rp->next = reseqfree; - reseqfree = rp; - qunlock(&reseqlock); + free(rp); } tcb->reseq = 0; diff --git a/ss/dat.h b/ss/dat.h index dcbafa8754ce5547b721be6e319711c319b9bd7f..cbf74fa221a5b204f0b6a5470a7f19c581bbbc63 100644 --- a/ss/dat.h +++ b/ss/dat.h @@ -69,6 +69,7 @@ struct Conf ulong nimage; /* number of page cache image headers */ ulong npagetab; /* number of pte tables */ ulong nswap; /* number of swap blocks */ + ulong upages; /* number of user pages */ int nalarm; /* alarms */ int nchan; /* channels */ int nenv; /* distinct environment values */ @@ -92,7 +93,6 @@ struct Conf int npipe; /* number of pipes */ int nservice; /* number of services */ int nfsyschan; /* number of filsys open channels */ - ulong maxialloc; /* maximum bytes used by ialloc */ int copymode; /* 0 is copy on write, 1 is copy on reference */ ulong ipif; /* Ip protocol interfaces */ ulong ip; /* Ip conversations per interface */ diff --git a/ss/fns.h b/ss/fns.h index fcc7487280a0ccc54622680998277b83333abd6a..d705323008b8376f1a27ce20f3f28c0ab841dc67 100644 --- a/ss/fns.h +++ b/ss/fns.h @@ -23,6 +23,8 @@ int kbdstate(IOQ*, int); void kbdclock(void); void kbdrepeat(int); KMap* kmap(Page*); +#define KADDR(a) ((void*)((ulong)(a)|KZERO)) +#define PADDR(a) ((ulong)(a)&~KZERO) void kmapinit(void); KMap* kmappa(ulong, ulong); KMap* kmapperm(Page*); diff --git a/ss/main.c b/ss/main.c index b064f1eaf02966d72f9bfad2cdd325501bc8dc86..24a457a5c3016d4f75d088357836910e1840aaba 100644 --- a/ss/main.c +++ b/ss/main.c @@ -23,10 +23,11 @@ main(void) active.exiting = 0; active.machs = 1; confinit(); + xinit(); mmuinit(); screeninit(); printinit(); - print("sparc plan 9\n"); + pageinit(); trapinit(); kmapinit(); ioinit(); @@ -34,11 +35,9 @@ main(void) intrinit(); procinit0(); initseg(); - grpinit(); chaninit(); chandevreset(); streaminit(); - pageinit(); userinit(); clockinit(); schedinit(); @@ -198,12 +197,15 @@ confinit(void) conf.nmach = 1; if(conf.nmach > MAXMACH) panic("confinit"); + conf.npage0 = (4*1024*1024)/BY2PG; /* BUG */ conf.npage1 = (4*1024*1024)/BY2PG; /* BUG */ conf.base0 = 0; conf.base1 = 32*1024*1024; conf.npage = conf.npage0+conf.npage1; - conf.maxialloc = 4*1024*1024; /* BUG */ + + conf.upages = 1400; + mul = 1; if(conf.npage1 > 0) mul = 2; diff --git a/ss/mmu.c b/ss/mmu.c index 028f3f2e1f8e8b809fa696e36a4f9471097d8073..2dfc29f236bfd637446f52f97270bd7f61b16840 100644 --- a/ss/mmu.c +++ b/ss/mmu.c @@ -136,25 +136,31 @@ purgepid(int pid) flushcontext(); } - void mmuinit(void) { - ulong l, i, j, c, pte; + ulong ktop, l, i, j, c, pte; + /* + * TEMP: just map the first 4M of bank 0 for the kernel - philw + */ + ktop = 4*1024*1024; /* * First map lots of memory as kernel addressable in all contexts */ i = 0; /* used */ for(c=0; c