From f4ff188bea7cde2ff8ea49239c8ce811fc8f5357 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Sat, 10 Jul 1999 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1999-07-10 --- pc/main.c | 6 +- port/alloc.c | 800 +++++-------------------------------------------- port/allocb.c | 174 +++++++++++ port/dev.c | 2 + port/devcons.c | 17 +- port/lib.h | 3 +- port/portfns.h | 8 +- port/taslock.c | 4 +- port/xalloc.c | 20 ++ 9 files changed, 299 insertions(+), 735 deletions(-) create mode 100644 port/allocb.c diff --git a/pc/main.c b/pc/main.c index 3fe4d56711bc7592b118d7db7b49a393330af9fc..6ca0cbfe60560bdfb3b5ee7d9bcde4e79186bd2b 100644 --- a/pc/main.c +++ b/pc/main.c @@ -434,7 +434,7 @@ confinit(void) * 4MB on the first Image chunk allocation. */ if(conf.npage*BY2PG < 16*MB) - poolsetparam("Image", 0, 0, 4*1024*1024, nil); + poolsetparam(imagmem, 0, 4*1024*1024, 0, nil); } conf.upages = conf.npage - kpages; conf.ialloc = (kpages/2)*BY2PG; @@ -450,14 +450,14 @@ confinit(void) + conf.nimage*sizeof(Image) + conf.nswap + conf.nswppo*sizeof(Page); - poolsetparam("Main", kpages, 0, 0, nil); + poolsetparam(mainmem, kpages, 0, 0, nil); if(!cpuserver){ /* * give terminals lots of image memory, too; the dynamic * allocation will balance the load properly, hopefully. * be careful with 32-bit overflow. */ - poolsetparam("Image", kpages, 0, 0, nil); + poolsetparam(imagmem, kpages, 0, 0, nil); } } diff --git a/port/alloc.c b/port/alloc.c index 74772111fb23fbb7a7388c9cc7ba0aa159086159..54183d99a6de9a455bb3fd482400f6f4d7bec9b5 100644 --- a/port/alloc.c +++ b/port/alloc.c @@ -1,400 +1,69 @@ #include "u.h" #include "../port/lib.h" #include "mem.h" -#include "pool.h" #include "dat.h" #include "fns.h" #include "error.h" +#include "pool.h" -#define left u.s.bhl -#define right u.s.bhr -#define fwd u.s.bhf -#define prev u.s.bhv -#define parent u.s.bhp - -struct Pool -{ - char* name; - ulong maxsize; - int quanta; - int chunk; - ulong cursize; - ulong arenasize; - ulong hw; - Lock l; - Bhdr* root; - Bhdr* chain; - int nalloc; - int nfree; - int nbrk; - int lastfree; - void (*move)(void*, void*); +static Pool pmainmem = { + .name= "Main", + .maxsize= 4*1024*1024, + .minarena= 128*1024, + .quantum= 32, + .alloc= xalloc, + .merge= xmerge, + .flags= 0, }; -struct -{ - int n; - Pool pool[MAXPOOL]; - Lock l; -} table = { - 2, - { - { "Main", 4*1024*1024, 31, 128*1024 }, - { "Image", 16*1024*1024, 31, 2*1024*1024 }, - } +static Pool pimagmem = { + .name= "Image", + .maxsize= 16*1024*1024, + .minarena= 2*1024*1024, + .quantum= 32, + .alloc= xalloc, + .merge= xmerge, + .flags= 0, }; -Pool* mainmem = &table.pool[0]; -Pool* imagmem = &table.pool[1]; - -int poolcompact(Pool*); - -Bhdr* -poolchain(Pool *p) -{ - return p->chain; -} - -void -pooldel(Pool *p, Bhdr *t) -{ - Bhdr *s, *f, *rp, *q; - - if(t->parent == nil && p->root != t) { - t->prev->fwd = t->fwd; - t->fwd->prev = t->prev; - return; - } - - if(t->fwd != t) { - f = t->fwd; - s = t->parent; - f->parent = s; - if(s == nil) - p->root = f; - else { - if(s->left == t) - s->left = f; - else - s->right = f; - } - - rp = t->left; - f->left = rp; - if(rp != nil) - rp->parent = f; - rp = t->right; - f->right = rp; - if(rp != nil) - rp->parent = f; - - t->prev->fwd = t->fwd; - t->fwd->prev = t->prev; - return; - } - - if(t->left == nil) - rp = t->right; - else { - if(t->right == nil) - rp = t->left; - else { - f = t; - rp = t->right; - s = rp->left; - while(s != nil) { - f = rp; - rp = s; - s = rp->left; - } - if(f != t) { - s = rp->right; - f->left = s; - if(s != nil) - s->parent = f; - s = t->right; - rp->right = s; - if(s != nil) - s->parent = rp; - } - s = t->left; - rp->left = s; - s->parent = rp; - } - } - q = t->parent; - if(q == nil) - p->root = rp; - else { - if(t == q->left) - q->left = rp; - else - q->right = rp; - } - if(rp != nil) - rp->parent = q; -} - -void -pooladd(Pool *p, Bhdr *q) -{ - int size; - Bhdr *tp, *t; - - q->magic = MAGIC_F; - - q->left = nil; - q->right = nil; - q->parent = nil; - q->fwd = q; - q->prev = q; - - t = p->root; - if(t == nil) { - p->root = q; - return; - } - - size = q->size; - - tp = nil; - while(t != nil) { - if(size == t->size) { - q->fwd = t->fwd; - q->fwd->prev = q; - q->prev = t; - t->fwd = q; - return; - } - tp = t; - if(size < t->size) - t = t->left; - else - t = t->right; - } - - q->parent = tp; - if(size < tp->size) - tp->left = q; - else - tp->right = q; -} +Pool* mainmem = &pmainmem; +Pool* imagmem = &pimagmem; void* -poolalloc(Pool *p, long size) -{ - Bhdr *q, *t; - int alloc, ldr, ns, frag; - - if(size < 0 || size >= 1024*1024*1024) /* for sanity and to avoid overflow */ - return nil; - size = (size + BHDRSIZE + p->quanta) & ~(p->quanta); - - ilock(&p->l); - p->nalloc++; - - t = p->root; - q = nil; - while(t) { - if(t->size == size) { - pooldel(p, t); - t->magic = MAGIC_A; - p->cursize += t->size; - if(p->cursize > p->hw) - p->hw = p->cursize; - iunlock(&p->l); - return B2D(t); - } - if(size < t->size) { - q = t; - t = t->left; - } - else - t = t->right; - } - if(q != nil) { - pooldel(p, q); - q->magic = MAGIC_A; - frag = q->size - size; - if(frag < (size>>2)) { - p->cursize += q->size; - if(p->cursize > p->hw) - p->hw = p->cursize; - iunlock(&p->l); - return B2D(q); - } - /* Split */ - ns = q->size - size; - q->size = size; - B2T(q)->hdr = q; - t = B2NB(q); - t->size = ns; - B2T(t)->hdr = t; - pooladd(p, t); - p->cursize += q->size; - if(p->cursize > p->hw) - p->hw = p->cursize; - iunlock(&p->l); - return B2D(q); - } - - ns = p->chunk; - if(size > ns) - ns = size; - ldr = p->quanta+1; - - alloc = ns+ldr+sizeof(t->magic); - p->arenasize += alloc; - if(p->arenasize > p->maxsize) { - p->arenasize -= alloc; - - if(poolcompact(p)) { - iunlock(&p->l); - return poolalloc(p, size); - } - - iunlock(&p->l); - print("%s arena too large: size %ld cursize %lud arenasize %lud maxsize %lud\n", - p->name, size, p->cursize, p->arenasize, p->maxsize); - return nil; - } - - p->nbrk++; - t = xalloc(alloc); - if(t == nil) { - iunlock(&p->l); - return nil; - } - - t->magic = MAGIC_E; /* Make a leader */ - t->size = ldr; - t->csize = ns+ldr; - t->clink = p->chain; - p->chain = t; - B2T(t)->hdr = t; - t = B2NB(t); - - t->magic = MAGIC_A; /* Make the block we are going to return */ - t->size = size; - B2T(t)->hdr = t; - q = t; - - ns -= size; /* Free the rest */ - if(ns > 0) { - q = B2NB(t); - q->size = ns; - B2T(q)->hdr = q; - pooladd(p, q); - } - B2NB(q)->magic = MAGIC_E; /* Mark the end of the chunk */ - - p->cursize += t->size; - if(p->cursize > p->hw) - p->hw = p->cursize; - iunlock(&p->l); - return B2D(t); -} - -void -poolfree(Pool *p, void *v) -{ - Bhdr *b, *c; - - D2B(b, v); - - ilock(&p->l); - p->nfree++; - p->cursize -= b->size; - - c = B2NB(b); - if(c->magic == MAGIC_F) { /* Join forward */ - pooldel(p, c); - c->magic = 0; - b->size += c->size; - B2T(b)->hdr = b; - } - - c = B2PT(b)->hdr; - if(c->magic == MAGIC_F) { /* Join backward */ - pooldel(p, c); - b->magic = 0; - c->size += b->size; - b = c; - B2T(b)->hdr = b; - } - - pooladd(p, b); - iunlock(&p->l); -} - -int -poolread(char *va, int count, ulong offset) +smalloc(ulong size) { - Pool *p; - int n, i, signed_off; - - n = 0; - signed_off = offset; - for(i = 0; i < table.n; i++) { - p = &table.pool[i]; - n += snprint(va+n, count-n, "%11lud %11lud %11lud %11d %11d %11d %s\n", - p->cursize, - p->maxsize, - p->hw, - p->nalloc, - p->nfree, - p->nbrk, - p->name); - - if(signed_off > 0) { - signed_off -= n; - if(signed_off < 0) { - memmove(va, va+n+signed_off, -signed_off); - n = -signed_off; - } - else - n = 0; - } + void *v; + ulong *l; + for(;;) { + v = poolalloc(mainmem, size+8); + if(v != nil) + break; + tsleep(&up->sleep, return0, 0, 100); } - return n; -} - -void -tagwithpc(void *v, ulong pc) -{ - Bhdr *h; - - D2B(h, v); - B2T(h)->pad = pc; + l = v; + l[0] = getcallerpc(&size); + v = l+2; + memset(v, 0, size); + return v; } void* malloc(ulong size) { + ulong *l; void *v; - v = poolalloc(mainmem, size); - if(v != nil) - memset(v, 0, size); - if(v != nil) - tagwithpc(v, getcallerpc(&size)); - return v; -} - -void* -smalloc(ulong size) -{ - void *v; + if(size == 0) + return nil; - for(;;) { - v = poolalloc(mainmem, size); - if(v != nil) - break; - tsleep(&up->sleep, return0, 0, 100); + v = poolalloc(mainmem, size+8); + if(v != nil) { + l = v; + l[0] = getcallerpc(&size); + v = l+2; + memset(v, 0, size); } - memset(v, 0, size); - tagwithpc(v, getcallerpc(&size)); return v; } @@ -402,395 +71,84 @@ void* mallocz(ulong size, int clr) { void *v; + ulong *l; - v = poolalloc(mainmem, size); + if(size == 0) + return nil; + + v = poolalloc(mainmem, size+8); + if(v != nil) { + l = v; + l[0] = getcallerpc(&size); + v = l+2; + } if(clr && v != nil) memset(v, 0, size); - if(v != nil) - tagwithpc(v, getcallerpc(&size)); return v; } void free(void *v) { - if(v != nil) - poolfree(mainmem, v); + if(v != nil) { + poolfree(mainmem, (uchar*)v-8); + } } void* realloc(void *v, ulong size) { - Bhdr *b; + ulong *l; void *nv; - int osize; + long nsize; + if(size == 0) { + free(v); + return nil; + } if(v == nil) return malloc(size); - D2B(b, v); - - osize = b->size - BHDRSIZE; - if(osize >= size) - return v; - - nv = poolalloc(mainmem, size); - if(nv != nil) { - memmove(nv, v, osize); - free(v); - } - if(nv != nil) - tagwithpc(nv, getcallerpc(&v)); - return nv; + nv = (uchar*)v-8; + nsize = size+8; + if(l = poolrealloc(mainmem, nv, nsize)) + return l+2; + return nil; } -int +ulong msize(void *v) { - Bhdr *b; - - D2B(b, v); - return b->size - BHDRSIZE; + return poolmsize(mainmem, (uchar*)v-8)-8; } void* calloc(ulong n, ulong szelem) { - return malloc(n*szelem); -} - -/* -void -pooldump(Bhdr *b, int d, int c) -{ - Bhdr *t; - - if(b == nil) - return; - - print("%.8lux %.8lux %.8lux %c %4d %d (f %.8lux p %.8lux)\n", - b, b->left, b->right, c, d, b->size, b->fwd, b->prev); - d++; - for(t = b->fwd; t != b; t = t->fwd) - print("\t%.8lux %.8lux %.8lux\n", t, t->prev, t->fwd); - pooldump(b->left, d, 'l'); - pooldump(b->right, d, 'r'); -} - - -void -poolshow(void) -{ - int i; - - for(i = 0; i < table.n; i++) { - print("Arena: %s root=%.8lux\n", table.pool[i].name, table.pool[i].root); - pooldump(table.pool[i].root, 0, 'R'); - } + return mallocz(n*szelem, 1); } -*/ void -poolsummary(void) +poolsummary(Pool *p) { - int i; - - for(i = 0; i < table.n; i++) - print("Arena: %s cursize=%lud; arenasize=%lud; maxsize=%lud\n", - table.pool[i].name, - table.pool[i].cursize, - table.pool[i].arenasize, - table.pool[i].maxsize); + print("%s max %lud cur %lud free %lud alloc %lud\n", p->name, + p->maxsize, p->cursize, p->curfree, p->curalloc); } -/* void -pooldump(Pool *p) +mallocsummary(void) { - Bhdr *b, *base, *limit, *ptr; - - b = p->chain; - if(b == nil) - return; - base = b; - ptr = b; - limit = B2LIMIT(b); - - while(base != nil) { - print("\tbase #%.8lux ptr #%.8lux", base, ptr); - if(ptr->magic == MAGIC_A) - print("\tA%.5d\n", ptr->size); - else if(ptr->magic == MAGIC_E) - print("\tE\tL#%.8lux\tS#%.8lux\n", ptr->clink, ptr->csize); - else - print("\tF%.5d\tL#%.8lux\tR#%.8lux\tF#%.8lux\tP#%.8lux\tT#%.8lux\n", - ptr->size, ptr->left, ptr->right, ptr->fwd, ptr->prev, ptr->parent); - ptr = B2NB(ptr); - if(ptr >= limit) { - print("link to #%.8lux\n", base->clink); - base = base->clink; - if(base == nil) - break; - ptr = base; - limit = B2LIMIT(base); - } - } - return; + poolsummary(mainmem); + poolsummary(imagmem); } -*/ void -poolsetparam(char *name, ulong maxsize, int quanta, int chunk, void (*move)(void*, void*)) -{ - Pool *p; - int i; - - for(i=0; iname) == 0){ - if(maxsize != 0) - p->maxsize = maxsize; - if(quanta != 0) - p->quanta = quanta; - if(chunk != 0) - p->chunk = chunk; - if(move != nil) - p->move = move; - return; - } - } -} - -int -poolcompact(Pool *pool) -{ - Bhdr *base, *limit, *ptr, *end, *next; - int compacted, recov, nb; - - if(pool->move == nil || pool->lastfree == pool->nfree) - return 0; - - pool->lastfree = pool->nfree; - - base = pool->chain; - ptr = B2NB(base); /* First Block in arena has clink */ - limit = B2LIMIT(base); - compacted = 0; - - pool->root = nil; - end = ptr; - recov = 0; - while(base != nil) { - next = B2NB(ptr); - if(ptr->magic == MAGIC_A) { - if(ptr != end) { - memmove(end, ptr, ptr->size); - pool->move(B2D(ptr), B2D(end)); - recov = (uchar*)ptr - (uchar*)end; - compacted = 1; - } - end = B2NB(end); - } - if(next >= limit) { - nb = (uchar*)limit - (uchar*)end; - //print("recovered %d bytes\n", recov); - //print("%d bytes at end\n", nb); - USED(recov); - if(nb > 0){ - if(nb < pool->quanta+1) - panic("poolcompact: leftover too small\n"); - end->size = nb; - pooladd(pool, end); - } - base = base->clink; - if(base == nil) - break; - ptr = B2NB(base); - end = ptr; /* could do better by copying between chains */ - limit = B2LIMIT(base); - recov = 0; - } else - ptr = next; - } - - return compacted; -} - -int -recur(Bhdr *t) -{ - if(t == 0) - return 1; - if(((ulong)t) < 0x80000000) - return 0; - if(((ulong)t) > 0x90000000) - return 0; - return recur(t->right) && recur(t->left); -} - -enum -{ - Hdrspc = 64, /* leave room for high-level headers */ - Bdead = 0x51494F42, /* "QIOB" */ -}; - -struct -{ - Lock; - ulong bytes; -} ialloc; - -/* - * allocate blocks, round the data base upt to a multiple of BLOCKALIGN. - */ -Block* -allocb(int size) -{ - Block *b; - ulong addr; - int n; - - n = sizeof(Block) + size; - b = poolalloc(mainmem, n+Hdrspc); - if(b == 0) - exhausted("Blocks"); - memset(b, 0, sizeof(Block)); - - /* align start of data portion by rounding up */ - addr = (ulong)b; - addr = ROUND(addr + sizeof(Block), BLOCKALIGN); - b->base = (uchar*)addr; - - /* align end of data portion by rounding down */ - b->lim = ((uchar*)b) + msize(b); - addr = (ulong)(b->lim); - addr = addr & ~(BLOCKALIGN-1); - b->lim = (uchar*)addr; - - /* leave sluff at beginning for added headers */ - b->rp = b->lim - ROUND(size, BLOCKALIGN); - if(b->rp < b->base) - panic("allocb"); - b->wp = b->rp; - tagwithpc(b, getcallerpc(&size)); - - return b; -} - -/* - * interrupt time allocation - */ -Block* -iallocb(int size) -{ - Block *b; - ulong addr; - int n; - - if(ialloc.bytes > conf.ialloc){ - print("iallocb: limited %lud/%lud\n", - ialloc.bytes, conf.ialloc); - return 0; - } - - n = sizeof(Block) + size; - b = poolalloc(mainmem, n+Hdrspc); - if(b == 0){ - print("iallocb: no memory %lud/%lud\n", - ialloc.bytes, conf.ialloc); - return nil; - } - memset(b, 0, sizeof(Block)); - - /* align start of data portion by rounding up */ - addr = (ulong)b; - addr = ROUND(addr + sizeof(Block), BLOCKALIGN); - b->base = (uchar*)addr; - - /* align end of data portion by rounding down */ - b->lim = ((uchar*)b) + msize(b); - addr = (ulong)(b->lim); - addr = addr & ~(BLOCKALIGN-1); - b->lim = (uchar*)addr; - - /* leave sluff at beginning for added headers */ - b->rp = b->lim - ROUND(size, BLOCKALIGN); - if(b->rp < b->base) - panic("allocb"); - b->wp = b->rp; - - b->flag = BINTR; - - ilock(&ialloc); - ialloc.bytes += b->lim - b->base; - iunlock(&ialloc); - tagwithpc(b, getcallerpc(&size)); - - return b; -} - -void -freeb(Block *b) +tagwithpc(void *v, ulong pc) { - void *dead = (void*)Bdead; - - if(b == nil) - return; - - /* - * drivers which perform non cache coherent DMA manage their own buffer - * pool of uncached buffers and provide their own free routine. - */ - if(b->free) { - b->free(b); + ulong *u; + if(v == nil) return; - } - if(b->flag & BINTR) { - ilock(&ialloc); - ialloc.bytes -= b->lim - b->base; - iunlock(&ialloc); - } - - /* poison the block in case someone is still holding onto it */ - b->next = dead; - b->rp = dead; - b->wp = dead; - b->lim = dead; - b->base = dead; - - poolfree(mainmem, b); -} - -void -checkb(Block *b, char *msg) -{ - void *dead = (void*)Bdead; - - if(b == dead) - panic("checkb b %s %lux", msg, b); - if(b->base == dead || b->lim == dead || b->next == dead - || b->rp == dead || b->wp == dead){ - print("checkb: base 0x%8.8luX lim 0x%8.8luX next 0x%8.8luX\n", - b->base, b->lim, b->next); - print("checkb: rp 0x%8.8luX wp 0x%8.8luX\n", b->rp, b->wp); - panic("checkb dead: %s\n", msg); - } - - if(b->base > b->lim) - panic("checkb 0 %s %lux %lux", msg, b->base, b->lim); - if(b->rp < b->base) - panic("checkb 1 %s %lux %lux", msg, b->base, b->rp); - if(b->wp < b->base) - panic("checkb 2 %s %lux %lux", msg, b->base, b->wp); - if(b->rp > b->lim) - panic("checkb 3 %s %lux %lux", msg, b->rp, b->lim); - if(b->wp > b->lim) - panic("checkb 4 %s %lux %lux", msg, b->wp, b->lim); - + u = v; + u[-2] = pc; } -void -iallocsummary(void) -{ - print("ialloc %lud/%lud\n", ialloc.bytes, conf.ialloc); -} diff --git a/port/allocb.c b/port/allocb.c new file mode 100644 index 0000000000000000000000000000000000000000..d654ca34dbb43a7341b75832276e8a926ae7e990 --- /dev/null +++ b/port/allocb.c @@ -0,0 +1,174 @@ +#include "u.h" +#include "../port/lib.h" +#include "mem.h" +#include "dat.h" +#include "fns.h" +#include "error.h" +#include "pool.h" + +enum +{ + Hdrspc = 64, /* leave room for high-level headers */ + Bdead = 0x51494F42, /* "QIOB" */ +}; + +struct +{ + Lock; + ulong bytes; +} ialloc; + +/* + * allocate blocks, round the data base upt to a multiple of BLOCKALIGN. + */ +Block* +allocb(int size) +{ + Block *b; + ulong addr; + int n; + + n = sizeof(Block) + size; + b = malloc(n+Hdrspc); + if(b == 0) + exhausted("Blocks"); + memset(b, 0, sizeof(Block)); + + /* align start of data portion by rounding up */ + addr = (ulong)b; + addr = ROUND(addr + sizeof(Block), BLOCKALIGN); + b->base = (uchar*)addr; + + /* align end of data portion by rounding down */ + b->lim = ((uchar*)b) + msize(b); + addr = (ulong)(b->lim); + addr = addr & ~(BLOCKALIGN-1); + b->lim = (uchar*)addr; + + /* leave sluff at beginning for added headers */ + b->rp = b->lim - ROUND(size, BLOCKALIGN); + if(b->rp < b->base) + panic("allocb"); + b->wp = b->rp; + tagwithpc(b, getcallerpc(&size)); + + return b; +} + +/* + * interrupt time allocation + */ +Block* +iallocb(int size) +{ + Block *b; + ulong addr; + int n; + + if(ialloc.bytes > conf.ialloc){ + print("iallocb: limited %lud/%lud\n", + ialloc.bytes, conf.ialloc); + return 0; + } + + n = sizeof(Block) + size; + b = malloc(n+Hdrspc); + if(b == 0){ + print("iallocb: no memory %lud/%lud\n", + ialloc.bytes, conf.ialloc); + return nil; + } + memset(b, 0, sizeof(Block)); + + /* align start of data portion by rounding up */ + addr = (ulong)b; + addr = ROUND(addr + sizeof(Block), BLOCKALIGN); + b->base = (uchar*)addr; + + /* align end of data portion by rounding down */ + b->lim = ((uchar*)b) + msize(b); + addr = (ulong)(b->lim); + addr = addr & ~(BLOCKALIGN-1); + b->lim = (uchar*)addr; + + /* leave sluff at beginning for added headers */ + b->rp = b->lim - ROUND(size, BLOCKALIGN); + if(b->rp < b->base) + panic("allocb"); + b->wp = b->rp; + + b->flag = BINTR; + + ilock(&ialloc); + ialloc.bytes += b->lim - b->base; + iunlock(&ialloc); + tagwithpc(b, getcallerpc(&size)); + + return b; +} + +void +freeb(Block *b) +{ + void *dead = (void*)Bdead; + + if(b == nil) + return; + + /* + * drivers which perform non cache coherent DMA manage their own buffer + * pool of uncached buffers and provide their own free routine. + */ + if(b->free) { + b->free(b); + return; + } + if(b->flag & BINTR) { + ilock(&ialloc); + ialloc.bytes -= b->lim - b->base; + iunlock(&ialloc); + } + + /* poison the block in case someone is still holding onto it */ + b->next = dead; + b->rp = dead; + b->wp = dead; + b->lim = dead; + b->base = dead; + + free(b); +} + +void +checkb(Block *b, char *msg) +{ + void *dead = (void*)Bdead; + + if(b == dead) + panic("checkb b %s %lux", msg, b); + if(b->base == dead || b->lim == dead || b->next == dead + || b->rp == dead || b->wp == dead){ + print("checkb: base 0x%8.8luX lim 0x%8.8luX next 0x%8.8luX\n", + b->base, b->lim, b->next); + print("checkb: rp 0x%8.8luX wp 0x%8.8luX\n", b->rp, b->wp); + panic("checkb dead: %s\n", msg); + } + + if(b->base > b->lim) + panic("checkb 0 %s %lux %lux", msg, b->base, b->lim); + if(b->rp < b->base) + panic("checkb 1 %s %lux %lux", msg, b->base, b->rp); + if(b->wp < b->base) + panic("checkb 2 %s %lux %lux", msg, b->base, b->wp); + if(b->rp > b->lim) + panic("checkb 3 %s %lux %lux", msg, b->rp, b->lim); + if(b->wp > b->lim) + panic("checkb 4 %s %lux %lux", msg, b->wp, b->lim); + +} + +void +iallocsummary(void) +{ + print("ialloc %lud/%lud\n", ialloc.bytes, conf.ialloc); +} diff --git a/port/dev.c b/port/dev.c index f69e45645185b26dfe3c161950cf5ba5c9bba9f8..6b3838cd96ba484bdc7ac2017fe7de88c63ebaae 100644 --- a/port/dev.c +++ b/port/dev.c @@ -142,6 +142,8 @@ devstat(Chan *c, char *db, Dirtab *tab, int ntab, Devgen *gen) if(c->qid.path & CHDIR){ if(c->name == nil) elem = "???"; + else if(strcmp(c->name->s, "/") == 0) + elem = "/"; else for(elem=p=c->name->s; *p; p++) if(*p = '/') diff --git a/port/devcons.c b/port/devcons.c index 05d230a3a24246e44c51ae0c0b37991dfeb15c85..dd51a613461cfdd32d270ab622258d476bac70f6 100644 --- a/port/devcons.c +++ b/port/devcons.c @@ -233,7 +233,7 @@ echo(Rune r, char *buf, int n) case 'x': xsummary(); ixsummary(); - poolsummary(); + mallocsummary(); pagersummary(); break; case 'd': @@ -364,6 +364,7 @@ enum{ Qsysstat, Qtime, Quser, + Qzero, }; static Dirtab consdir[]={ @@ -394,6 +395,7 @@ static Dirtab consdir[]={ "time", {Qtime}, NUMSIZE, 0664, "timing", {Qtiming}, 3*8, 0664, "user", {Quser}, NAMELEN, 0666, + "zero", {Qzero}, 0, 0666, }; uvlong billion = 1000000000ULL; @@ -786,6 +788,10 @@ consread(Chan *c, void *buf, long n, vlong off) free(b); return n; + case Qzero: + memset(buf, 0, n); + return n; + default: print("consread %lux\n", c->qid.path); error(Egreg); @@ -869,7 +875,7 @@ conswrite(Chan *c, void *va, long n, vlong off) n = sizeof(cbuf)-1; strncpy(cbuf, a, n); cbuf[n] = 0; - f = strtovl(cbuf, 0, 0); + f = strtoll(cbuf, 0, 0); if(f <= 0L) error(Ebadarg); fasthz = f; @@ -883,8 +889,8 @@ conswrite(Chan *c, void *va, long n, vlong off) n = sizeof cbuf - 1; strncpy(cbuf, a, n); cbuf[n] = 0; - nsec = strtovl(cbuf, &a, 0); - delta = strtovl(a, &a, 0); + nsec = strtoll(cbuf, &a, 0); + delta = strtoll(a, &a, 0); n = strtol(a, &a, 0); todset(nsec, delta, n); break; @@ -966,6 +972,9 @@ conswrite(Chan *c, void *va, long n, vlong off) sysname[n-1] = 0; break; + case Qzero: + return n; + default: print("conswrite: %lud\n", c->qid.path); error(Egreg); diff --git a/port/lib.h b/port/lib.h index d4e6882e0fa05d45310b432135fcab0e2eb4eb46..c43f18947d6892991a728ee9addebebea640f387 100644 --- a/port/lib.h +++ b/port/lib.h @@ -68,7 +68,8 @@ extern int print(char*, ...); */ extern long strtol(char*, char**, int); extern ulong strtoul(char*, char**, int); -extern vlong strtovl(char*, char**, int); +extern vlong strtoll(char*, char**, int); +extern uvlong strtoull(char*, char**, int); extern char etext[]; extern char edata[]; extern char end[]; diff --git a/port/portfns.h b/port/portfns.h index 9e0e5dbfe250eb9d3a98c892965d775b96d62d7c..30dd926b2c86531f1794530e5f370c4e6f5b1143 100644 --- a/port/portfns.h +++ b/port/portfns.h @@ -154,6 +154,7 @@ Page* lookpage(Image*, ulong); void machinit(void); void* mallocz(ulong, int); void* malloc(ulong); +void mallocsummary(void); void mfreeseg(Segment*, ulong, int); void microdelay(int); void mmurelease(Proc*); @@ -163,7 +164,7 @@ long mntread9p(Chan*, void*, long, vlong); void mntrepl(char*); long mntwrite9p(Chan*, void*, long, vlong); void mountfree(Mount*); -int msize(void*); +ulong msize(void*); Chan* namec(char*, int, int, ulong); void nameok(char*); #define nelem(x) (sizeof(x)/sizeof(x[0])) @@ -194,8 +195,6 @@ void pgrpcpy(Pgrp*, Pgrp*); void pgrpnote(ulong, char*, long, int); Pgrp* pgrptab(int); void pio(Segment *, ulong, ulong, Page **); -void poolsetparam(char*, ulong, int, int, void (*)(void*, void*)); -void poolsummary(void); #define poperror() up->nerrlab-- int postnote(Proc*, int, char*, int); int pprint(char*, ...); @@ -328,11 +327,12 @@ int walk(Chan**, char*, int); int walkname(Chan**, char*, int); void wlock(RWlock*); void wunlock(RWlock*); -#define xalloc(s) xallocz(s, 1) +void* xalloc(ulong); void* xallocz(ulong, int); void xfree(void*); void xhole(ulong, ulong); void xinit(void); +int xmerge(void*, void*); void* xspanalloc(ulong, int, ulong); void xsummary(void); Segment* data2txt(Segment*); diff --git a/port/taslock.c b/port/taslock.c index 51e529a8e36cf6827b78a8a4a30a01b5e590c791..042582969ebec1a819b57f7487ec8342e264055e 100644 --- a/port/taslock.c +++ b/port/taslock.c @@ -151,7 +151,7 @@ unlock(Lock *l) if(l->key == 0) print("unlock: not locked: pc %luX\n", getcallerpc(&l)); if(l->isilock) - print("iunlock of lock: pc %lux, held by %lux\n", getcallerpc(&l), l->pc); + print("unlock of ilock: pc %lux, held by %lux\n", getcallerpc(&l), l->pc); l->pc = 0; l->key = 0; coherence(); @@ -165,7 +165,7 @@ iunlock(Lock *l) if(l->key == 0) print("iunlock: not locked: pc %luX\n", getcallerpc(&l)); if(!l->isilock) - print("unlock of ilock: pc %lux, held by %lux\n", getcallerpc(&l), l->pc); + print("iunlock of lock: pc %lux, held by %lux\n", getcallerpc(&l), l->pc); sr = l->sr; l->pc = 0; diff --git a/port/xalloc.c b/port/xalloc.c index 85f0f569d7a989d3618775a75191d7c7da5b95b6..977a0035d93838907775b1d6fdbf11f5812447c0 100644 --- a/port/xalloc.c +++ b/port/xalloc.c @@ -145,6 +145,12 @@ xallocz(ulong size, int zero) return nil; } +void* +xalloc(ulong size) +{ + return xallocz(size, 1); +} + void xfree(void *p) { @@ -158,6 +164,20 @@ xfree(void *p) xhole(PADDR(x), x->size); } +int +xmerge(void *vp, void *vq) +{ + Xhdr *p, *q; + + p = vp; + if((uchar*)vp+p->size == (uchar*)vq) { + q = vq; + p->size += q->size; + return 1; + } + return 0; +} + void xhole(ulong addr, ulong size) {