static Res clientChunkCreate(Chunk *chunkReturn, Addr base, Addr limit, ClientArena clientArena) { ClientChunk clChunk; Chunk chunk; Addr alignedBase; BootBlockStruct bootStruct; BootBlock boot = &bootStruct; Res res; void *p; AVER(chunkReturn != NULL); AVER(base != (Addr)0); /* @@@@ Should refuse on small chunks, instead of AVERring. */ AVER(limit != (Addr)0); AVER(limit > base); /* Initialize boot block. */ /* Chunk has to be page-aligned, and the boot allocs must be within it. */ alignedBase = AddrAlignUp(base, ARENA_CLIENT_PAGE_SIZE); AVER(alignedBase < limit); res = BootBlockInit(boot, (void *)alignedBase, (void *)limit); if (res != ResOK) goto failBootInit; /* Allocate the chunk. */ /* See <design/arena/>.@@@@ */ res = BootAlloc(&p, boot, sizeof(ClientChunkStruct), MPS_PF_ALIGN); if (res != ResOK) goto failChunkAlloc; clChunk = p; chunk = ClientChunk2Chunk(clChunk); res = ChunkInit(chunk, ClientArena2Arena(clientArena), alignedBase, AddrAlignDown(limit, ARENA_CLIENT_PAGE_SIZE), ARENA_CLIENT_PAGE_SIZE, boot); if (res != ResOK) goto failChunkInit; ClientArena2Arena(clientArena)->committed += AddrOffset(base, PageIndexBase(chunk, chunk->allocBase)); BootBlockFinish(boot); clChunk->sig = ClientChunkSig; AVERT(ClientChunk, clChunk); *chunkReturn = chunk; return ResOK; failChunkInit: failChunkAlloc: failBootInit: return res; }
Addr (AddrAlignDown)(Addr addr, Align alignment) { AVER(AlignCheck(alignment)); return AddrAlignDown(addr, alignment); }