aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/venti/arenas.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/venti/arenas.c')
-rw-r--r--src/cmd/venti/arenas.c404
1 files changed, 0 insertions, 404 deletions
diff --git a/src/cmd/venti/arenas.c b/src/cmd/venti/arenas.c
deleted file mode 100644
index 5275b938..00000000
--- a/src/cmd/venti/arenas.c
+++ /dev/null
@@ -1,404 +0,0 @@
-#include "stdinc.h"
-#include "dat.h"
-#include "fns.h"
-
-typedef struct AHash AHash;
-
-/*
- * hash table for finding arena's based on their names.
- */
-struct AHash
-{
- AHash *next;
- Arena *arena;
-};
-
-enum
-{
- AHashSize = 512
-};
-
-static AHash *ahash[AHashSize];
-
-static u32int
-hashstr(char *s)
-{
- u32int h;
- int c;
-
- h = 0;
- for(; c = *s; s++){
- c ^= c << 6;
- h += (c << 11) ^ (c >> 1);
- c = *s;
- h ^= (c << 14) + (c << 7) + (c << 4) + c;
- }
- return h;
-}
-
-int
-addarena(Arena *arena)
-{
- AHash *a;
- u32int h;
-
- h = hashstr(arena->name) & (AHashSize - 1);
- a = MK(AHash);
- if(a == nil)
- return -1;
- a->arena = arena;
- a->next = ahash[h];
- ahash[h] = a;
- return 0;
-}
-
-Arena*
-findarena(char *name)
-{
- AHash *a;
- u32int h;
-
- h = hashstr(name) & (AHashSize - 1);
- for(a = ahash[h]; a != nil; a = a->next)
- if(strcmp(a->arena->name, name) == 0)
- return a->arena;
- return nil;
-}
-
-int
-delarena(Arena *arena)
-{
- AHash *a, *last;
- u32int h;
-
- h = hashstr(arena->name) & (AHashSize - 1);
- last = nil;
- for(a = ahash[h]; a != nil; a = a->next){
- if(a->arena == arena){
- if(last != nil)
- last->next = a->next;
- else
- ahash[h] = a->next;
- free(a);
- return 0;
- }
- last = a;
- }
- return -1;
-}
-
-ArenaPart*
-initarenapart(Part *part)
-{
- AMapN amn;
- ArenaPart *ap;
- ZBlock *b;
- u32int i;
- int ok;
-
- b = alloczblock(HeadSize, 0);
- if(b == nil || readpart(part, PartBlank, b->data, HeadSize) < 0){
- seterr(EAdmin, "can't read arena partition header: %r");
- return nil;
- }
-
- ap = MKZ(ArenaPart);
- if(ap == nil){
- freezblock(b);
- return nil;
- }
- ap->part = part;
- ok = unpackarenapart(ap, b->data);
- freezblock(b);
- if(ok < 0){
- seterr(ECorrupt, "corrupted arena partition header: %r");
- freearenapart(ap, 0);
- return nil;
- }
-
- ap->tabbase = (PartBlank + HeadSize + ap->blocksize - 1) & ~(ap->blocksize - 1);
- if(ap->version != ArenaPartVersion){
- seterr(ECorrupt, "unknown arena partition version %d", ap->version);
- freearenapart(ap, 0);
- return nil;
- }
- if(ap->blocksize & (ap->blocksize - 1)){
- seterr(ECorrupt, "illegal non-power-of-2 block size %d\n", ap->blocksize);
- freearenapart(ap, 0);
- return nil;
- }
- if(ap->tabbase >= ap->arenabase){
- seterr(ECorrupt, "arena partition table overlaps with arena storage");
- freearenapart(ap, 0);
- return nil;
- }
- ap->tabsize = ap->arenabase - ap->tabbase;
- partblocksize(part, ap->blocksize);
- ap->size = ap->part->size & ~(u64int)(ap->blocksize - 1);
-
- if(readarenamap(&amn, part, ap->tabbase, ap->tabsize) < 0){
- freearenapart(ap, 0);
- return nil;
- }
- ap->narenas = amn.n;
- ap->map = amn.map;
- if(okamap(ap->map, ap->narenas, ap->arenabase, ap->size, "arena table") < 0){
- freearenapart(ap, 0);
- return nil;
- }
-
- ap->arenas = MKNZ(Arena*, ap->narenas);
- for(i = 0; i < ap->narenas; i++){
- ap->arenas[i] = initarena(part, ap->map[i].start, ap->map[i].stop - ap->map[i].start, ap->blocksize);
- if(ap->arenas[i] == nil){
- freearenapart(ap, 1);
- return nil;
- }
- if(namecmp(ap->map[i].name, ap->arenas[i]->name) != 0){
- seterr(ECorrupt, "arena name mismatches with expected name: %s vs. %s",
- ap->map[i].name, ap->arenas[i]->name);
- freearenapart(ap, 1);
- return nil;
- }
- if(findarena(ap->arenas[i]->name)){
- seterr(ECorrupt, "duplicate arena name %s in %s",
- ap->map[i].name, ap->part->name);
- freearenapart(ap, 1);
- return nil;
- }
- }
-
- for(i = 0; i < ap->narenas; i++)
- addarena(ap->arenas[i]);
-
- return ap;
-}
-
-ArenaPart*
-newarenapart(Part *part, u32int blocksize, u32int tabsize)
-{
- ArenaPart *ap;
-
- if(blocksize & (blocksize - 1)){
- seterr(ECorrupt, "illegal non-power-of-2 block size %d\n", blocksize);
- return nil;
- }
- ap = MKZ(ArenaPart);
- if(ap == nil)
- return nil;
-
- ap->version = ArenaPartVersion;
- ap->part = part;
- ap->blocksize = blocksize;
- partblocksize(part, blocksize);
- ap->size = part->size & ~(u64int)(blocksize - 1);
- ap->tabbase = (PartBlank + HeadSize + blocksize - 1) & ~(blocksize - 1);
- ap->arenabase = (ap->tabbase + tabsize + blocksize - 1) & ~(blocksize - 1);
- ap->tabsize = ap->arenabase - ap->tabbase;
- ap->narenas = 0;
-
- if(wbarenapart(ap) < 0){
- freearenapart(ap, 0);
- return nil;
- }
-
- return ap;
-}
-
-int
-wbarenapart(ArenaPart *ap)
-{
- ZBlock *b;
-
- if(okamap(ap->map, ap->narenas, ap->arenabase, ap->size, "arena table") < 0)
- return -1;
- b = alloczblock(HeadSize, 1);
- if(b == nil)
-//ZZZ set error message?
- return -1;
-
- if(packarenapart(ap, b->data) < 0){
- seterr(ECorrupt, "can't make arena partition header: %r");
- freezblock(b);
- return -1;
- }
- if(writepart(ap->part, PartBlank, b->data, HeadSize) < 0){
- seterr(EAdmin, "can't write arena partition header: %r");
- freezblock(b);
- return -1;
- }
- freezblock(b);
-
- return wbarenamap(ap->map, ap->narenas, ap->part, ap->tabbase, ap->tabsize);
-}
-
-void
-freearenapart(ArenaPart *ap, int freearenas)
-{
- int i;
-
- if(ap == nil)
- return;
- if(freearenas){
- for(i = 0; i < ap->narenas; i++){
- if(ap->arenas[i] == nil)
- continue;
- delarena(ap->arenas[i]);
- freearena(ap->arenas[i]);
- }
- }
- free(ap->map);
- free(ap->arenas);
- free(ap);
-}
-
-int
-okamap(AMap *am, int n, u64int start, u64int stop, char *what)
-{
- u64int last;
- u32int i;
-
- last = start;
- for(i = 0; i < n; i++){
- if(am[i].start < last){
- if(i == 0)
- seterr(ECorrupt, "invalid start address in %s", what);
- else
- seterr(ECorrupt, "overlapping ranges in %s", what);
- return -1;
- }
- if(am[i].stop < am[i].start){
- seterr(ECorrupt, "invalid range in %s", what);
- return -1;
- }
- last = am[i].stop;
- }
- if(last > stop){
- seterr(ECorrupt, "invalid ending address in %s", what);
- return -1;
- }
- return 0;
-}
-
-int
-maparenas(AMap *am, Arena **arenas, int n, char *what)
-{
- u32int i;
-
- for(i = 0; i < n; i++){
- arenas[i] = findarena(am[i].name);
- if(arenas[i] == nil){
- seterr(EAdmin, "can't find arena '%s' for '%s'\n", am[i].name, what);
- return -1;
- }
- }
- return 0;
-}
-
-int
-readarenamap(AMapN *amn, Part *part, u64int base, u32int size)
-{
- IFile f;
- u32int ok;
-
- if(partifile(&f, part, base, size) < 0)
- return -1;
- ok = parseamap(&f, amn);
- freeifile(&f);
- return ok;
-}
-
-int
-wbarenamap(AMap *am, int n, Part *part, u64int base, u64int size)
-{
- Fmt f;
- ZBlock *b;
-
- b = alloczblock(size, 1);
- if(b == nil)
- return -1;
-
- fmtzbinit(&f, b);
-
- if(outputamap(&f, am, n) < 0){
- seterr(ECorrupt, "arena set size too small");
- freezblock(b);
- return -1;
- }
- if(writepart(part, base, b->data, size) < 0){
- seterr(EAdmin, "can't write arena set: %r");
- freezblock(b);
- return -1;
- }
- freezblock(b);
- return 0;
-}
-
-/*
- * amap: n '\n' amapelem * n
- * n: u32int
- * amapelem: name '\t' astart '\t' asize '\n'
- * astart, asize: u64int
- */
-int
-parseamap(IFile *f, AMapN *amn)
-{
- AMap *am;
- u64int v64;
- u32int v;
- char *s, *flds[4];
- int i, n;
-
- /*
- * arenas
- */
- if(ifileu32int(f, &v) < 0){
- seterr(ECorrupt, "syntax error: bad number of elements in %s", f->name);
- return -1;
- }
- n = v;
- if(n > MaxAMap){
- seterr(ECorrupt, "illegal number of elements in %s", f->name);
- return -1;
- }
- am = MKNZ(AMap, n);
- if(am == nil)
- return -1;
- for(i = 0; i < n; i++){
- s = ifileline(f);
- if(s == nil || getfields(s, flds, 4, 0, "\t") != 3)
- return -1;
- if(nameok(flds[0]) < 0)
- return -1;
- namecp(am[i].name, flds[0]);
- if(stru64int(flds[1], &v64) < 0){
- seterr(ECorrupt, "syntax error: bad arena base address in %s", f->name);
- free(am);
- return -1;
- }
- am[i].start = v64;
- if(stru64int(flds[2], &v64) < 0){
- seterr(ECorrupt, "syntax error: bad arena size in %s", f->name);
- free(am);
- return -1;
- }
- am[i].stop = v64;
- }
-
- amn->map = am;
- amn->n = n;
- return 0;
-}
-
-int
-outputamap(Fmt *f, AMap *am, int n)
-{
- int i;
-
- if(fmtprint(f, "%ud\n", n) < 0)
- return -1;
- for(i = 0; i < n; i++)
- if(fmtprint(f, "%s\t%llud\t%llud\n", am[i].name, am[i].start, am[i].stop) < 0)
- return -1;
- return 0;
-}