/* * initialize the external bucket sorting data structures */ static IEBucks* initiebucks(Part *part, int bits, uint32_t size) { IEBucks *ib; int i; ib = MKZ(IEBucks); if(ib == nil){ seterr(EOk, "out of memory"); return nil; } ib->bits = bits; ib->nbucks = 1 << bits; ib->size = size; ib->usable = (size - U32Size) / IEntrySize * IEntrySize; ib->bucks = MKNZ(IEBuck, ib->nbucks); if(ib->bucks == nil){ seterr(EOk, "out of memory allocation sorting buckets"); freeiebucks(ib); return nil; } ib->xbuf = MKN(uint8_t, size * ((1 << bits)+1)); ib->buf = (uint8_t*)(((uintptr)ib->xbuf+size-1)&~(uintptr)(size-1)); if(ib->buf == nil){ seterr(EOk, "out of memory allocating sorting buckets' buffers"); freeiebucks(ib); return nil; } for(i = 0; i < ib->nbucks; i++){ ib->bucks[i].head = TWID32; ib->bucks[i].buf = &ib->buf[i * size]; } ib->part = part; return ib; }
int initlumpqueues(int nq) { LumpQueue *q; int i; nqs = nq; lumpqs = MKNZ(LumpQueue, nq); for(i = 0; i < nq; i++){ q = &lumpqs[i]; q->full.l = &q->lock; q->empty.l = &q->lock; q->flush.l = &q->lock; if(vtproc(queueproc, q) < 0){ seterr(EOk, "can't start write queue slave: %r"); return -1; } } return 0; }
void threadmain(int argc, char *argv[]) { int vers; ArenaPart *ap; Part *part; Arena *arena; uint64_t addr, limit, asize, apsize; char *file, *name, aname[ANameSize]; int i, n, blocksize, tabsize, zero; ventifmtinstall(); statsinit(); blocksize = 8 * 1024; asize = 512 * 1024 *1024; tabsize = 512 * 1024; /* BUG: should be determine from number of arenas */ zero = -1; vers = ArenaVersion5; ARGBEGIN{ case 'D': settrace(EARGF(usage())); break; case 'a': asize = unittoull(EARGF(usage())); if(asize == TWID64) usage(); break; case 'b': blocksize = unittoull(EARGF(usage())); if(blocksize == ~0) usage(); if(blocksize > MaxDiskBlock){ fprint(2, "block size too large, max %d\n", MaxDiskBlock); threadexitsall("usage"); } break; case '4': vers = ArenaVersion4; break; case 'Z': zero = 0; break; default: usage(); break; }ARGEND if(zero == -1){ if(vers == ArenaVersion4) zero = 1; else zero = 0; } if(argc != 2) usage(); name = argv[0]; file = argv[1]; if(nameok(name) < 0) sysfatal("illegal name template %s", name); part = initpart(file, ORDWR|ODIRECT); if(part == nil) sysfatal("can't open partition %s: %r", file); if(zero) zeropart(part, blocksize); maxblocksize = blocksize; initdcache(20*blocksize); ap = newarenapart(part, blocksize, tabsize); if(ap == nil) sysfatal("can't initialize arena: %r"); apsize = ap->size - ap->arenabase; n = apsize / asize; if(apsize - (n * asize) >= MinArenaSize) n++; fprint(2, "fmtarenas %s: %,d arenas, %,lld bytes storage, %,d bytes for index map\n", file, n, apsize, ap->tabsize); ap->narenas = n; ap->map = MKNZ(AMap, n); ap->arenas = MKNZ(Arena*, n); addr = ap->arenabase; for(i = 0; i < n; i++){ limit = addr + asize; if(limit >= ap->size || ap->size - limit < MinArenaSize){ limit = ap->size; if(limit - addr < MinArenaSize) sysfatal("bad arena set math: runt arena at %lld,%lld %lld", addr, limit, ap->size); } snprint(aname, ANameSize, "%s%d", name, i); if(0) fprint(2, "adding arena %s at [%lld,%lld)\n", aname, addr, limit); arena = newarena(part, vers, aname, addr, limit - addr, blocksize); if(!arena) fprint(2, "can't make new arena %s: %r", aname); freearena(arena); ap->map[i].start = addr; ap->map[i].stop = limit; namecp(ap->map[i].name, aname); addr = limit; } if(wbarenapart(ap) < 0) fprint(2, "can't write back arena partition header for %s: %r\n", file); flushdcache(); threadexitsall(0); }
/* * initialize an entirely new index */ Index * newindex(char *name, ISect **sects, int n) { Index *ix; AMap *smap; u64int nb; u32int div, ub, xb, start, stop, blocksize, tabsize; int i, j; if(n < 1){ seterr(EOk, "creating index with no index sections"); return nil; } /* * compute the total buckets available in the index, * and the total buckets which are used. */ nb = 0; blocksize = sects[0]->blocksize; tabsize = sects[0]->tabsize; for(i = 0; i < n; i++){ /* * allow index, start, and stop to be set if index is correct * and start and stop are what we would have picked. * this allows calling fmtindex to reformat the index after * replacing a bad index section with a freshly formatted one. * start and stop are checked below. */ if(sects[i]->index[0] != '\0' && strcmp(sects[i]->index, name) != 0){ seterr(EOk, "creating new index using non-empty section %s", sects[i]->name); return nil; } if(blocksize != sects[i]->blocksize){ seterr(EOk, "mismatched block sizes in index sections"); return nil; } if(tabsize != sects[i]->tabsize){ seterr(EOk, "mismatched config table sizes in index sections"); return nil; } nb += sects[i]->blocks; } /* * check for duplicate names */ for(i = 0; i < n; i++){ for(j = i + 1; j < n; j++){ if(namecmp(sects[i]->name, sects[j]->name) == 0){ seterr(EOk, "duplicate section name %s for index %s", sects[i]->name, name); return nil; } } } if(nb >= ((u64int)1 << 32)){ fprint(2, "%s: index is 2^32 blocks or more; ignoring some of it\n", argv0); nb = ((u64int)1 << 32) - 1; } div = (((u64int)1 << 32) + nb - 1) / nb; if(div < 100){ fprint(2, "%s: index divisor %d too coarse; " "index larger than needed, ignoring some of it\n", argv0, div); div = 100; nb = (((u64int)1 << 32) - 1) / (100 - 1); } ub = (((u64int)1 << 32) - 1) / div + 1; if(ub > nb){ seterr(EBug, "index initialization math wrong"); return nil; } xb = nb - ub; /* * initialize each of the index sections * and the section map table */ smap = MKNZ(AMap, n); if(smap == nil){ seterr(EOk, "can't create new index: out of memory"); return nil; } start = 0; for(i = 0; i < n; i++){ stop = start + sects[i]->blocks - xb / n; if(i == n - 1) stop = ub; if(sects[i]->start != 0 || sects[i]->stop != 0) if(sects[i]->start != start || sects[i]->stop != stop){ seterr(EOk, "creating new index using non-empty section %s", sects[i]->name); return nil; } sects[i]->start = start; sects[i]->stop = stop; namecp(sects[i]->index, name); smap[i].start = start; smap[i].stop = stop; namecp(smap[i].name, sects[i]->name); start = stop; } /* * initialize the index itself */ ix = MKZ(Index); if(ix == nil){ seterr(EOk, "can't create new index: out of memory"); free(smap); return nil; } ix->version = IndexVersion; namecp(ix->name, name); ix->sects = sects; ix->smap = smap; ix->nsects = n; ix->blocksize = blocksize; ix->buckets = ub; ix->tabsize = tabsize; ix->div = div; if(initindex1(ix) < 0){ free(smap); return nil; } return ix; }