static Res MVFFInit(Pool pool, ArgList args) { Size extendBy = MVFF_EXTEND_BY_DEFAULT; Size avgSize = MVFF_AVG_SIZE_DEFAULT; Size align = MVFF_ALIGN_DEFAULT; Bool slotHigh = MVFF_SLOT_HIGH_DEFAULT; Bool arenaHigh = MVFF_ARENA_HIGH_DEFAULT; Bool firstFit = MVFF_FIRST_FIT_DEFAULT; MVFF mvff; Arena arena; Res res; void *p; ArgStruct arg; AVERT(Pool, pool); arena = PoolArena(pool); /* .arg: class-specific additional arguments; see */ /* <design/poolmvff/#method.init> */ /* .arg.check: we do the same checks here and in MVFFCheck */ /* except for arenaHigh, which is stored only in the segPref. */ if (ArgPick(&arg, args, MPS_KEY_EXTEND_BY)) extendBy = arg.val.size; if (ArgPick(&arg, args, MPS_KEY_MEAN_SIZE)) avgSize = arg.val.size; if (ArgPick(&arg, args, MPS_KEY_ALIGN)) align = arg.val.align; if (ArgPick(&arg, args, MPS_KEY_MVFF_SLOT_HIGH)) slotHigh = arg.val.b; if (ArgPick(&arg, args, MPS_KEY_MVFF_ARENA_HIGH)) arenaHigh = arg.val.b; if (ArgPick(&arg, args, MPS_KEY_MVFF_FIRST_FIT)) firstFit = arg.val.b; AVER(extendBy > 0); /* .arg.check */ AVER(avgSize > 0); /* .arg.check */ AVER(avgSize <= extendBy); /* .arg.check */ AVER(SizeIsAligned(align, MPS_PF_ALIGN)); AVERT(Bool, slotHigh); AVERT(Bool, arenaHigh); AVERT(Bool, firstFit); mvff = Pool2MVFF(pool); mvff->extendBy = extendBy; if (extendBy < ArenaAlign(arena)) mvff->minSegSize = ArenaAlign(arena); else mvff->minSegSize = extendBy; mvff->avgSize = avgSize; pool->alignment = align; mvff->slotHigh = slotHigh; mvff->firstFit = firstFit; res = ControlAlloc(&p, arena, sizeof(SegPrefStruct), FALSE); if (res != ResOK) return res; mvff->segPref = (SegPref)p; SegPrefInit(mvff->segPref); SegPrefExpress(mvff->segPref, arenaHigh ? SegPrefHigh : SegPrefLow, NULL); mvff->total = 0; mvff->free = 0; res = FreelistInit(FreelistOfMVFF(mvff), align); if (res != ResOK) goto failInit; res = CBSInit(CBSOfMVFF(mvff), arena, (void *)mvff, align, /* fastFind */ TRUE, /* zoned */ FALSE, args); if (res != ResOK) goto failInit; mvff->sig = MVFFSig; AVERT(MVFF, mvff); EVENT8(PoolInitMVFF, pool, arena, extendBy, avgSize, align, BOOL(slotHigh), BOOL(arenaHigh), BOOL(firstFit)); return ResOK; failInit: ControlFree(arena, p, sizeof(SegPrefStruct)); return res; }
extern int main(int argc, char *argv[]) { mps_arena_t mpsArena; Arena arena; /* the ANSI arena which we use to allocate the BT */ FBMStateStruct state; void *p; Addr dummyBlock; BT allocTable; FreelistStruct flStruct; CBSStruct cbsStruct; Align align; randomize(argc, argv); align = (1 << rnd() % 4) * MPS_PF_ALIGN; NAllocateTried = NAllocateSucceeded = NDeallocateTried = NDeallocateSucceeded = 0; die(mps_arena_create(&mpsArena, mps_arena_class_vm(), testArenaSIZE), "mps_arena_create"); arena = (Arena)mpsArena; /* avoid pun */ die((mps_res_t)BTCreate(&allocTable, arena, ArraySize), "failed to create alloc table"); /* We're not going to use this block, but I feel unhappy just */ /* inventing addresses. */ die((mps_res_t)ControlAlloc(&p, arena, ArraySize * align, /* withReservoirPermit */ FALSE), "failed to allocate block"); dummyBlock = p; /* avoid pun */ if (verbose) { printf("Allocated block [%p,%p)\n", (void*)dummyBlock, (char *)dummyBlock + ArraySize); } die((mps_res_t)CBSInit(&cbsStruct, arena, arena, align, /* fastFind */ TRUE, /* zoned */ FALSE, mps_args_none), "failed to initialise CBS"); state.type = FBMTypeCBS; state.align = align; state.block = dummyBlock; state.allocTable = allocTable; state.the.cbs = &cbsStruct; test(&state, nCBSOperations); CBSFinish(&cbsStruct); die((mps_res_t)FreelistInit(&flStruct, align), "failed to initialise Freelist"); state.type = FBMTypeFreelist; state.the.fl = &flStruct; test(&state, nFLOperations); FreelistFinish(&flStruct); mps_arena_destroy(arena); printf("\nNumber of allocations attempted: %ld\n", NAllocateTried); printf("Number of allocations succeeded: %ld\n", NAllocateSucceeded); printf("Number of deallocations attempted: %ld\n", NDeallocateTried); printf("Number of deallocations succeeded: %ld\n", NDeallocateSucceeded); printf("%s: Conclusion: Failed to find any defects.\n", argv[0]); return 0; }