static void test(void *stack_pointer) { mps_arena_t arena; mps_pool_t pool; mps_addr_t block[ITERATIONS]; unsigned i; MPS_ARGS_BEGIN(args) { MPS_ARGS_ADD(args, MPS_KEY_ARENA_SIZE, CHUNKSIZE); die(mps_arena_create_k(&arena, mps_arena_class_vm(), args), "arena_create"); } MPS_ARGS_END(args); MPS_ARGS_BEGIN(args) { MPS_ARGS_ADD(args, MPS_KEY_SPARE, 0); die(mps_pool_create_k(&pool, arena, mps_class_mvff(), args), "pool_create"); } MPS_ARGS_END(args); check_chunks(arena, 1); for (i = 0; i < ITERATIONS; ++i) { die(mps_alloc(&block[i], pool, CHUNKSIZE), "mps_alloc"); check_chunks(arena, i + 2); } for (i = ITERATIONS; i > 0; --i) { mps_free(pool, block[i - 1], CHUNKSIZE); mps_arena_collect(arena); /* ensure ArenaCompact is called */ check_chunks(arena, i); } mps_pool_destroy(pool); mps_arena_destroy(arena); }
static void testInArena(mps_arena_class_t arena_class, mps_arg_s *arena_args, mps_pool_debug_option_s *options) { mps_arena_t arena; die(mps_arena_create_k(&arena, arena_class, arena_args), "mps_arena_create"); MPS_ARGS_BEGIN(args) { mps_align_t align = sizeof(void *) << (rnd() % 4); MPS_ARGS_ADD(args, MPS_KEY_ALIGN, align); MPS_ARGS_ADD(args, MPS_KEY_MVFF_ARENA_HIGH, TRUE); MPS_ARGS_ADD(args, MPS_KEY_MVFF_SLOT_HIGH, TRUE); MPS_ARGS_ADD(args, MPS_KEY_MVFF_FIRST_FIT, TRUE); MPS_ARGS_ADD(args, MPS_KEY_SPARE, rnd_double()); die(stress(arena, NULL, randomSize8, align, "MVFF", mps_class_mvff(), args), "stress MVFF"); } MPS_ARGS_END(args); MPS_ARGS_BEGIN(args) { mps_align_t align = sizeof(void *) << (rnd() % 4); MPS_ARGS_ADD(args, MPS_KEY_ALIGN, align); MPS_ARGS_ADD(args, MPS_KEY_MVFF_ARENA_HIGH, TRUE); MPS_ARGS_ADD(args, MPS_KEY_MVFF_SLOT_HIGH, TRUE); MPS_ARGS_ADD(args, MPS_KEY_MVFF_FIRST_FIT, TRUE); MPS_ARGS_ADD(args, MPS_KEY_SPARE, rnd_double()); MPS_ARGS_ADD(args, MPS_KEY_POOL_DEBUG_OPTIONS, options); die(stress(arena, options, randomSize8, align, "MVFF debug", mps_class_mvff_debug(), args), "stress MVFF debug"); } MPS_ARGS_END(args); MPS_ARGS_BEGIN(args) { mps_align_t align = (mps_align_t)1 << (rnd() % 6); MPS_ARGS_ADD(args, MPS_KEY_ALIGN, align); die(stress(arena, NULL, randomSize, align, "MV", mps_class_mv(), args), "stress MV"); } MPS_ARGS_END(args); MPS_ARGS_BEGIN(args) { mps_align_t align = (mps_align_t)1 << (rnd() % 6); MPS_ARGS_ADD(args, MPS_KEY_ALIGN, align); MPS_ARGS_ADD(args, MPS_KEY_POOL_DEBUG_OPTIONS, options); die(stress(arena, options, randomSize, align, "MV debug", mps_class_mv_debug(), args), "stress MV debug"); } MPS_ARGS_END(args); MPS_ARGS_BEGIN(args) { fixedSizeSize = 1 + rnd() % 64; MPS_ARGS_ADD(args, MPS_KEY_MFS_UNIT_SIZE, fixedSizeSize); MPS_ARGS_ADD(args, MPS_KEY_EXTEND_BY, 100000); die(stress(arena, NULL, fixedSize, MPS_PF_ALIGN, "MFS", mps_class_mfs(), args), "stress MFS"); } MPS_ARGS_END(args); /* Manual allocation should not cause any garbage collections. */ Insist(mps_collections(arena) == 0); mps_arena_destroy(arena); }
static void test(void *stack_pointer) { mps_thr_t thread; mps_pool_t pool; mps_addr_t a; char *c; cdie(mps_arena_create(&arena, mps_arena_class_vm(), (size_t) (1024*1024*50)), "create arena"); cdie(mps_thread_reg(&thread, arena), "register thread"); MPS_ARGS_BEGIN(args) { MPS_ARGS_ADD(args, MPS_KEY_POOL_DEBUG_OPTIONS, &debugOpts); die(mps_pool_create_k(&pool, arena, mps_class_mvff_debug(), args), "create MVFF pool"); } MPS_ARGS_END(args); die(mps_alloc(&a, pool, 64), "alloc a"); c = a; c -= 1; *c = 0; mps_pool_check_fenceposts(pool); comment("Fencepost check."); c += 67; *c = 0; mps_pool_check_fenceposts(pool); comment("Fencepost check."); mps_pool_destroy(pool); mps_thread_dereg(thread); mps_arena_destroy(arena); }
mps_res_t mps_fmt_create_auto_header(mps_fmt_t *mps_fmt_o, mps_arena_t arena, mps_fmt_auto_header_s *mps_fmt) { Format format; Res res; ArenaEnter(arena); AVER(mps_fmt_o != NULL); AVERT(Arena, arena); AVER(mps_fmt != NULL); MPS_ARGS_BEGIN(args) { MPS_ARGS_ADD(args, MPS_KEY_FMT_ALIGN, mps_fmt->align); MPS_ARGS_ADD(args, MPS_KEY_FMT_HEADER_SIZE, mps_fmt->mps_headerSize); MPS_ARGS_ADD(args, MPS_KEY_FMT_SCAN, mps_fmt->scan); MPS_ARGS_ADD(args, MPS_KEY_FMT_SKIP, mps_fmt->skip); MPS_ARGS_ADD(args, MPS_KEY_FMT_FWD, mps_fmt->fwd); MPS_ARGS_ADD(args, MPS_KEY_FMT_ISFWD, mps_fmt->isfwd); MPS_ARGS_ADD(args, MPS_KEY_FMT_PAD, mps_fmt->pad); res = FormatCreate(&format, arena, args); } MPS_ARGS_END(args); ArenaLeave(arena); if (res != ResOK) return res; *mps_fmt_o = (mps_fmt_t)format; return MPS_RES_OK; }
mps_res_t mps_fmt_create_fixed(mps_fmt_t *mps_fmt_o, mps_arena_t arena, mps_fmt_fixed_s *mps_fmt_fixed) { Format format; Res res; ArenaEnter(arena); AVER(mps_fmt_o != NULL); AVERT(Arena, arena); AVER(mps_fmt_fixed != NULL); MPS_ARGS_BEGIN(args) { MPS_ARGS_ADD(args, MPS_KEY_FMT_ALIGN, mps_fmt_fixed->align); MPS_ARGS_ADD(args, MPS_KEY_FMT_SCAN, mps_fmt_fixed->scan); MPS_ARGS_ADD(args, MPS_KEY_FMT_FWD, mps_fmt_fixed->fwd); MPS_ARGS_ADD(args, MPS_KEY_FMT_ISFWD, mps_fmt_fixed->isfwd); MPS_ARGS_ADD(args, MPS_KEY_FMT_PAD, mps_fmt_fixed->pad); res = FormatCreate(&format, arena, args); } MPS_ARGS_END(args); ArenaLeave(arena); if (res != ResOK) return res; *mps_fmt_o = (mps_fmt_t)format; return MPS_RES_OK; }
int main(int argc, char *argv[]) { testlib_init(argc, argv); MPS_ARGS_BEGIN(args) { MPS_ARGS_ADD(args, MPS_KEY_ARENA_SIZE, testArenaSIZE); test_in_arena(mps_arena_class_vm(), args); } MPS_ARGS_END(args); MPS_ARGS_BEGIN(args) { MPS_ARGS_ADD(args, MPS_KEY_ARENA_SIZE, testArenaSIZE); MPS_ARGS_ADD(args, MPS_KEY_ARENA_ZONED, FALSE); test_in_arena(mps_arena_class_vm(), args); } MPS_ARGS_END(args); printf("%s: Conclusion: Failed to find any defects.\n", argv[0]); return 0; }
int main(int argc, char *argv[]) { testlib_init(argc, argv); MPS_ARGS_BEGIN(args) { MPS_ARGS_ADD(args, MPS_KEY_ARENA_SIZE, testArenaSIZE); MPS_ARGS_ADD(args, MPS_KEY_ARENA_GRAIN_SIZE, rnd_grain(testArenaSIZE)); testInArena(mps_arena_class_vm(), args, &bothOptions); } MPS_ARGS_END(args); MPS_ARGS_BEGIN(args) { MPS_ARGS_ADD(args, MPS_KEY_ARENA_SIZE, smallArenaSIZE); MPS_ARGS_ADD(args, MPS_KEY_ARENA_GRAIN_SIZE, rnd_grain(smallArenaSIZE)); testInArena(mps_arena_class_vm(), args, &fenceOptions); } MPS_ARGS_END(args); printf("%s: Conclusion: Failed to find any defects.\n", argv[0]); return 0; }
static void test_main(void *marker, int interior, int stack) { mps_res_t res; mps_chain_t obj_chain; mps_fmt_t obj_fmt; mps_thr_t thread; mps_root_t reg_root = NULL; res = mps_arena_create_k(&scheme_arena, mps_arena_class_vm(), mps_args_none); if (res != MPS_RES_OK) error("Couldn't create arena"); res = mps_chain_create(&obj_chain, scheme_arena, sizeof(obj_gen_params) / sizeof(*obj_gen_params), obj_gen_params); if (res != MPS_RES_OK) error("Couldn't create obj chain"); scheme_fmt(&obj_fmt); MPS_ARGS_BEGIN(args) { MPS_ARGS_ADD(args, MPS_KEY_CHAIN, obj_chain); MPS_ARGS_ADD(args, MPS_KEY_FORMAT, obj_fmt); MPS_ARGS_ADD(args, MPS_KEY_INTERIOR, interior); die(mps_pool_create_k(&obj_pool, scheme_arena, mps_class_amc(), args), "mps_pool_create_k"); } MPS_ARGS_END(args); res = mps_ap_create_k(&obj_ap, obj_pool, mps_args_none); if (res != MPS_RES_OK) error("Couldn't create obj allocation point"); res = mps_thread_reg(&thread, scheme_arena); if (res != MPS_RES_OK) error("Couldn't register thread"); if (stack) { res = mps_root_create_thread(®_root, scheme_arena, thread, marker); if (res != MPS_RES_OK) error("Couldn't create root"); } test_air(interior, stack); mps_arena_park(scheme_arena); if (stack) mps_root_destroy(reg_root); mps_thread_dereg(thread); mps_ap_destroy(obj_ap); mps_pool_destroy(obj_pool); mps_chain_destroy(obj_chain); mps_fmt_destroy(obj_fmt); mps_arena_destroy(scheme_arena); }
static void test(void) { mps_arena_t arena; mps_pool_t pool; mps_fmt_t format; mps_ap_t ap; mps_addr_t p; cdie(mps_arena_create(&arena, mps_arena_class_vm(), mmqaArenaSIZE), "create arena"); cdie(mps_fmt_create_k(&format, arena, mps_args_none), "create format"); MPS_ARGS_BEGIN(args) { MPS_ARGS_ADD(args, MPS_KEY_FORMAT, format); cdie(mps_pool_create_k(&pool, arena, mps_class_ams(), args), "create pool"); } MPS_ARGS_END(args); MPS_ARGS_BEGIN(args) { MPS_ARGS_ADD(args, MPS_KEY_RANK, mps_rank_weak()); cdie(mps_ap_create_k(&ap, pool, args), "create ap"); } MPS_ARGS_END(args); do { cdie(mps_reserve(&p, ap, 0x100), "Reserve: "); } while (!mps_commit(ap, p, 0x100)); comment("Committed."); mps_ap_destroy(ap); comment("Destroyed ap."); mps_pool_destroy(pool); comment("Destroyed pool."); mps_fmt_destroy(format); comment("Destroyed format."); mps_arena_destroy(arena); comment("Destroyed arena."); }
static void runArenaTest(size_t size, mps_bool_t failcase, mps_bool_t usefulFailcase) { mps_arena_t arena; MPS_ARGS_BEGIN(args) { MPS_ARGS_ADD(args, MPS_KEY_ARENA_SIZE, size); MPS_ARGS_ADD(args, MPS_KEY_ARENA_ZONED, FALSE); MPS_ARGS_ADD(args, MPS_KEY_COMMIT_LIMIT, size - chunkSize); die(mps_arena_create_k(&arena, mps_arena_class_vm(), args), "mps_arena_create"); } MPS_ARGS_END(args); testInArena(arena, failcase, usefulFailcase); mps_arena_destroy(arena); }
static void test(void *stack_pointer) { void *marker = ▮ mps_arena_t arena; mps_pool_t pool; mps_thr_t thread; mps_root_t root; mps_fmt_t format; mps_ap_t ap; mps_addr_t p, q, unaligned; cdie(mps_arena_create_k(&arena, mps_arena_class_vm(), mps_args_none), "create arena"); mps_arena_park(arena); cdie(mps_thread_reg(&thread, arena), "register thread"); cdie(mps_root_create_thread(&root, arena, thread, marker), "create root"); cdie(mps_fmt_create_A(&format, arena, &fmtA), "create format"); MPS_ARGS_BEGIN(args) { MPS_ARGS_ADD(args, MPS_KEY_FORMAT, format); cdie(mps_pool_create_k(&pool, arena, mps_class_ams(), args), "pool"); } MPS_ARGS_END(args); cdie(mps_ap_create(&ap, pool, mps_rank_exact()), "ap"); /* p is in the AMS pool */ p = allocone(ap, 0, NULL, NULL, sizeof(mycell)); /* q is in the AMS pool with unaligned exact reference to p */ unaligned = (void *)((char*)p + 1); q = allocone(ap, 1, p, unaligned, sizeof(mycell)); mps_arena_start_collect(arena); mps_arena_park(arena); /* Keep q (and thus p) alive during the collection. */ report("q", "%p", q); mps_ap_destroy(ap); mps_pool_destroy(pool); mps_fmt_destroy(format); mps_root_destroy(root); mps_thread_dereg(thread); mps_arena_destroy(arena); }
int main(int argc, char *argv[]) { mps_arena_t arena; testlib_init(argc, argv); MPS_ARGS_BEGIN(args) { MPS_ARGS_ADD(args, MPS_KEY_ARENA_SIZE, testArenaSIZE); MPS_ARGS_ADD(args, MPS_KEY_ARENA_ZONED, FALSE); die(mps_arena_create_k(&arena, mps_arena_class_vm(), args), "mps_arena_create"); } MPS_ARGS_END(args); testInArena(arena); mps_arena_destroy(arena); printf("%s: Conclusion: Failed to find any defects.\n", argv[0]); return 0; }
static void test_in_arena(mps_arena_class_t arena_class, mps_arg_s *arena_args) { mps_arena_t arena; die(mps_arena_create_k(&arena, arena_class, arena_args), "mps_arena_create"); size_min = MPS_PF_ALIGN; size_mean = 42; size_max = 8192; MPS_ARGS_BEGIN(args) { mps_align_t align = sizeof(void *) << (rnd() % 4); MPS_ARGS_ADD(args, MPS_KEY_ALIGN, align); MPS_ARGS_ADD(args, MPS_KEY_MIN_SIZE, size_min); MPS_ARGS_ADD(args, MPS_KEY_MEAN_SIZE, size_mean); MPS_ARGS_ADD(args, MPS_KEY_MAX_SIZE, size_max); MPS_ARGS_ADD(args, MPS_KEY_MVT_RESERVE_DEPTH, TEST_SET_SIZE/2); MPS_ARGS_ADD(args, MPS_KEY_MVT_FRAG_LIMIT, 0.3); die(stress(arena, align, randomSize, mps_class_mvt(), args), "stress MVT"); } MPS_ARGS_END(args); mps_arena_destroy(arena); }
static Res DebugPoolInit(Pool pool, ArgList args) { Res res; PoolDebugOptions options; PoolDebugMixin debug; TagInitMethod tagInit; Size tagSize; ArgStruct arg; AVERT(Pool, pool); /* TODO: Split this structure into separate keyword arguments, now that we can support them. */ ArgRequire(&arg, args, MPS_KEY_POOL_DEBUG_OPTIONS); options = (PoolDebugOptions)arg.val.pool_debug_options; AVERT(PoolDebugOptions, options); /* @@@@ Tag parameters should be taken from options, but tags have */ /* not been published yet. */ tagInit = NULL; tagSize = 0; res = SuperclassOfPool(pool)->init(pool, args); if (res != ResOK) return res; debug = DebugPoolDebugMixin(pool); AVER(debug != NULL); /* fencepost init */ /* @@@@ This parses a user argument, options, so it should really */ /* go through the MPS interface. The template needs to be copied */ /* into Addr memory, to avoid breaking <design/type/#addr.use>. */ debug->fenceSize = options->fenceSize; if (debug->fenceSize != 0) { if (debug->fenceSize % PoolAlignment(pool) != 0) { res = ResPARAM; goto alignFail; } /* Fenceposting turns on tagging */ if (tagInit == NULL) { tagSize = 0; tagInit = TagTrivInit; } debug->fenceTemplate = options->fenceTemplate; } /* free-checking init */ /* @@@@ This parses a user argument, options, so it should really */ /* go through the MPS interface. The template needs to be copied */ /* into Addr memory, to avoid breaking <design/type#addr.use>. */ debug->freeSize = options->freeSize; if (debug->freeSize != 0) { if (PoolAlignment(pool) % debug->freeSize != 0) { res = ResPARAM; goto alignFail; } debug->freeTemplate = options->freeTemplate; } /* tag init */ debug->tagInit = tagInit; if (debug->tagInit != NULL) { debug->tagSize = tagSize + sizeof(tagStruct) - 1; /* This pool has to be like the arena control pool: the blocks */ /* allocated must be accessible using void*. */ MPS_ARGS_BEGIN(pcArgs) { MPS_ARGS_ADD(pcArgs, MPS_KEY_EXTEND_BY, debug->tagSize); /* FIXME: Check this */ MPS_ARGS_ADD(pcArgs, MPS_KEY_MFS_UNIT_SIZE, debug->tagSize); MPS_ARGS_DONE(pcArgs); res = PoolCreate(&debug->tagPool, PoolArena(pool), PoolClassMFS(), pcArgs); } MPS_ARGS_END(pcArgs); if (res != ResOK) goto tagFail; debug->missingTags = 0; SplayTreeInit(&debug->index, TagComp, NULL); }
static void t_alloc(int spare, int spare_total, int commit, int obj_size) { size_t size, hisize, comsize, comlimit; size_t spsize = 0, losize = 0; /* stop warnings */ mps_res_t res, res_expected; if (obj_size == OBJ_SMALL) size = SMALL_SIZE; else size = BIG_SIZE; switch (spare_total) { case SPARE_EMPTY: spsize = 0; break; case SPARE_LESS: if (size > DIFF_SIZE) { spsize = size-DIFF_SIZE; } else { spsize = 0; } break; case SPARE_EXACT: spsize = size; break; case SPARE_MORE: spsize = size+DIFF_SIZE; break; default: error("Illegal spare.\n"); break; } switch (spare) { case SPARE_EMPTY: losize = 0; break; case SPARE_LESS: if (size > DIFF_SIZE) { losize = size-DIFF_SIZE; } else { losize = 0; } break; case SPARE_EXACT: losize = size; break; case SPARE_MORE: losize = size+DIFF_SIZE; break; } if (losize > spsize) { losize = spsize; hisize = 0; } else { hisize = spsize-losize; } /* turn off commit limit for a moment */ mps_arena_commit_limit_set(arena, HUGE); /* create low and high pools */ MPS_ARGS_BEGIN(args) { MPS_ARGS_ADD(args, MPS_KEY_EXTEND_BY, EXTEND); MPS_ARGS_ADD(args, MPS_KEY_MEAN_SIZE, AVGSIZE); MPS_ARGS_ADD(args, MPS_KEY_MVFF_ARENA_HIGH, 1); MPS_ARGS_ADD(args, MPS_KEY_MVFF_SLOT_HIGH, 1); MPS_ARGS_ADD(args, MPS_KEY_MVFF_FIRST_FIT, 0); MPS_ARGS_ADD(args, MPS_KEY_SPARE, 0.0); die(mps_pool_create_k(&poolhi, arena, mps_class_mvff(), args), "create high pool"); } MPS_ARGS_END(args); MPS_ARGS_BEGIN(args) { MPS_ARGS_ADD(args, MPS_KEY_EXTEND_BY, EXTEND); MPS_ARGS_ADD(args, MPS_KEY_MEAN_SIZE, AVGSIZE); MPS_ARGS_ADD(args, MPS_KEY_MVFF_ARENA_HIGH, 0); MPS_ARGS_ADD(args, MPS_KEY_MVFF_SLOT_HIGH, 0); MPS_ARGS_ADD(args, MPS_KEY_MVFF_FIRST_FIT, 1); MPS_ARGS_ADD(args, MPS_KEY_SPARE, 0.0); die(mps_pool_create_k(&poollo, arena, mps_class_mvff(), args), "create low pool"); } MPS_ARGS_END(args); /* flush hysteresis fund, then set limit */ mps_arena_spare_set(arena, SPARE_ZERO); mps_arena_spare_set(arena, SPARE_LIMIT); /* allocate something in each pool (to reduce risk of subsidiary allocation being needed later) */ die(mps_alloc(&objlo, poollo, EXTEND), "low alloc"); mps_free(poollo, objlo, EXTEND); die(mps_alloc(&objhi, poolhi, EXTEND), "high alloc"); mps_free(poolhi, objhi, EXTEND); /* set up spare committed the way we want it */ if (losize>0) { die(mps_alloc(&objlo, poollo, losize), "low setup"); mps_free(poollo, objlo, losize); } if (hisize>0) { die(mps_alloc(&objhi, poolhi, hisize), "high setup"); mps_free(poolhi, objhi, hisize); } /* spare is now set up correctly */ /* now we need to set the commit limit correctly */ comsize = arena_committed_and_used(arena); /* allow for 1/16th memory overhead in setting commit limit */ if (commit == COMMIT_EXACT) { comlimit = comsize+size+(size/16); } else if (commit == COMMIT_NOCHANGE) { comlimit = mps_arena_committed(arena); } else if (commit == COMMIT_PLENTY) { comlimit = HUGE; } else /* commit == COMMIT_LITTLE */ { if (size > DIFF_SIZE) { comlimit = comsize+size+(size/16)+DIFF_SIZE; } else { comlimit = comsize+size+(size/16); } } die(mps_arena_commit_limit_set(arena, comlimit), "commit limit set"); res = mps_alloc(&objlo, poollo, size); asserts(comlimit >= comsize, "comlimit was less than comsize!"); if (size <= (comlimit-comsize)) { res_expected = MPS_RES_OK; } else { res_expected = MPS_RES_COMMIT_LIMIT; } if (res != res_expected) { comment("hisize=%lu losize=%lu\n" "comsize=%lu comlimit=%lu\n" "Expected %s. Got %s", (unsigned long)hisize, (unsigned long)losize, (unsigned long)comsize, (unsigned long)comlimit, err_text(res_expected), err_text(res)); report("failed", "yes"); } mps_pool_destroy(poollo); mps_pool_destroy(poolhi); }
static void test(void *stack_pointer) { mps_arena_t arena; mps_pool_t poolMVFF, poolAMC; mps_thr_t thread; mps_fmt_t format; mps_chain_t chain; mps_ap_t ap; mps_res_t r; mycell *a; mps_addr_t p; int i; int s1, s2, s3; cdie(mps_arena_create(&arena, mps_arena_class_vm(), mmqaArenaSIZE), "create arena"); cdie(mps_thread_reg(&thread, arena), "register thread"); die(mps_fmt_create_A(&format, arena, &fmtA), "create format"); cdie(mps_chain_create(&chain, arena, genCOUNT, testChain), "chain_create"); formatcomments = 0; die(mmqa_pool_create_chain(&poolAMC, arena, mps_class_amc(), format, chain), "create pool"); cdie( mps_ap_create(&ap, poolAMC, mps_rank_exact()), "create ap"); comment("Sizes in megabytes:"); MPS_ARGS_BEGIN(args) { MPS_ARGS_ADD(args, MPS_KEY_EXTEND_BY, EXTEND_BY); MPS_ARGS_ADD(args, MPS_KEY_MEAN_SIZE, MEAN_SIZE); cdie(mps_pool_create_k(&poolMVFF, arena, mps_class_mvff(), args), "create MVFF pool"); } MPS_ARGS_END(args); i = 0; while ((r=mps_alloc(&p, poolMVFF, 1024*1024)) == 0) i++; report("refuse1", "%s", err_text(r)); report("size1", "%i", i); s1 = i; mps_pool_destroy(poolMVFF); MPS_ARGS_BEGIN(args) { MPS_ARGS_ADD(args, MPS_KEY_EXTEND_BY, EXTEND_BY); MPS_ARGS_ADD(args, MPS_KEY_MEAN_SIZE, MEAN_SIZE); cdie(mps_pool_create_k(&poolMVFF, arena, mps_class_mvff(), args), "create MVFF pool"); } MPS_ARGS_END(args); i = 0; while ((r=mps_alloc(&p, poolMVFF, 1024*1024)) == 0) i++; report("refuse2", "%s", err_text(r)); report("size2", "%i", i); s2 = i; mps_pool_destroy(poolMVFF); a = allocdumb(ap, 1024*1024*30); /* allocate 30 M object */ MPS_ARGS_BEGIN(args) { MPS_ARGS_ADD(args, MPS_KEY_EXTEND_BY, EXTEND_BY); MPS_ARGS_ADD(args, MPS_KEY_MEAN_SIZE, MEAN_SIZE); cdie(mps_pool_create_k(&poolMVFF, arena, mps_class_mvff(), args), "create MVFF pool"); } MPS_ARGS_END(args); i=0; while ((r=mps_alloc(&p, poolMVFF, 1024*1024)) == 0) i++; report("refuse3", "%s", err_text(r)); report("size3", "%i", i); s3 = i; report("diff12", "%i", s1-s2); report("diff23", "%i", s2-s3); for(i = 0; i < 10; i++) { r = mps_alloc(&p, poolMVFF, 1024*1024); report("refuse4", "%s", err_text(r)); } mps_arena_park(arena); mps_pool_destroy(poolMVFF); mps_ap_destroy(ap); mps_pool_destroy(poolAMC); comment("Destroyed pool."); mps_chain_destroy(chain); mps_fmt_destroy(format); mps_thread_dereg(thread); mps_arena_destroy(arena); comment("Destroyed arena."); }
static Res DebugPoolInit(Pool pool, Arena arena, PoolClass klass, ArgList args) { Res res; PoolDebugOptions options = &debugPoolOptionsDefault; PoolDebugMixin debug; TagInitFunction tagInit; Size tagSize; ArgStruct arg; AVER(pool != NULL); AVERT(Arena, arena); AVERT(PoolClass, klass); AVERT(ArgList, args); if (ArgPick(&arg, args, MPS_KEY_POOL_DEBUG_OPTIONS)) options = (PoolDebugOptions)arg.val.pool_debug_options; AVERT(PoolDebugOptions, options); /* @@@@ Tag parameters should be taken from options, but tags have */ /* not been published yet. */ tagInit = NULL; tagSize = 0; res = SuperclassPoly(Pool, klass)->init(pool, arena, klass, args); if (res != ResOK) return res; SetClassOfPoly(pool, klass); debug = DebugPoolDebugMixin(pool); AVER(debug != NULL); /* fencepost init */ /* @@@@ This parses a user argument, options, so it should really */ /* go through the MPS interface. The template needs to be copied */ /* into Addr memory, to avoid breaking <design/type#.addr.use>. */ debug->fenceSize = options->fenceSize; if (debug->fenceSize != 0) { /* Fenceposting turns on tagging */ if (tagInit == NULL) { tagSize = 0; tagInit = TagTrivInit; } debug->fenceTemplate = options->fenceTemplate; } /* free-checking init */ /* @@@@ This parses a user argument, options, so it should really */ /* go through the MPS interface. The template needs to be copied */ /* into Addr memory, to avoid breaking <design/type#addr.use>. */ debug->freeSize = options->freeSize; if (debug->freeSize != 0) { debug->freeTemplate = options->freeTemplate; } /* tag init */ debug->tagInit = tagInit; if (debug->tagInit != NULL) { debug->tagSize = tagSize + sizeof(tagStruct) - 1; /* This pool has to be like the arena control pool: the blocks */ /* allocated must be accessible using void*. */ MPS_ARGS_BEGIN(pcArgs) { /* By setting EXTEND_BY to debug->tagSize we get the smallest possible extensions compatible with the tags, and so the least amount of wasted space. */ MPS_ARGS_ADD(pcArgs, MPS_KEY_EXTEND_BY, debug->tagSize); MPS_ARGS_ADD(pcArgs, MPS_KEY_MFS_UNIT_SIZE, debug->tagSize); res = PoolCreate(&debug->tagPool, PoolArena(pool), PoolClassMFS(), pcArgs); } MPS_ARGS_END(pcArgs); if (res != ResOK) goto tagFail; debug->missingTags = 0; SplayTreeInit(&debug->index, TagCompare, TagKey, SplayTrivUpdate); }
static void *test(void *arg, size_t s) { mps_arena_t arena; mps_fmt_t format; mps_root_t exactRoot, ambigRoot; size_t lastStep = 0, i, r; unsigned long objs; mps_ap_t busy_ap; mps_addr_t busy_init; const char *indent = " "; mps_chain_t chain; static mps_gen_param_s genParam = {1024, 0.2}; arena = (mps_arena_t)arg; (void)s; /* unused */ die(mps_fmt_create_A(&format, arena, dylan_fmt_A()), "fmt_create"); die(mps_chain_create(&chain, arena, 1, &genParam), "chain_create"); MPS_ARGS_BEGIN(args) { MPS_ARGS_ADD(args, MPS_KEY_FORMAT, format); MPS_ARGS_ADD(args, MPS_KEY_CHAIN, chain); MPS_ARGS_ADD(args, MPS_KEY_GEN, 0); die(mps_pool_create_k(&pool, arena, mps_class_amst(), args), "pool_create(amst)"); } MPS_ARGS_END(args); die(mps_ap_create(&ap, pool, mps_rank_exact()), "BufferCreate"); die(mps_ap_create(&busy_ap, pool, mps_rank_exact()), "BufferCreate 2"); for(i = 0; i < exactRootsCOUNT; ++i) exactRoots[i] = objNULL; for(i = 0; i < ambigRootsCOUNT; ++i) ambigRoots[i] = rnd_addr(); die(mps_root_create_table_masked(&exactRoot, arena, mps_rank_exact(), (mps_rm_t)0, &exactRoots[0], exactRootsCOUNT, (mps_word_t)1), "root_create_table(exact)"); die(mps_root_create_table(&ambigRoot, arena, mps_rank_ambig(), (mps_rm_t)0, &ambigRoots[0], ambigRootsCOUNT), "root_create_table(ambig)"); puts(indent); /* create an ap, and leave it busy */ die(mps_reserve(&busy_init, busy_ap, 64), "mps_reserve busy"); objs = 0; while(totalSize < totalSizeMAX) { if (totalSize > lastStep + totalSizeSTEP) { lastStep = totalSize; printf("\nSize %"PRIuLONGEST" bytes, %"PRIuLONGEST" objects.\n", (ulongest_t)totalSize, (ulongest_t)objs); printf("%s", indent); (void)fflush(stdout); for(i = 0; i < exactRootsCOUNT; ++i) cdie(exactRoots[i] == objNULL || dylan_check(exactRoots[i]), "all roots check"); } r = (size_t)rnd(); if (r & 1) { i = (r >> 1) % exactRootsCOUNT; if (exactRoots[i] != objNULL) cdie(dylan_check(exactRoots[i]), "dying root check"); exactRoots[i] = make(); if (exactRoots[(exactRootsCOUNT-1) - i] != objNULL) dylan_write(exactRoots[(exactRootsCOUNT-1) - i], exactRoots, exactRootsCOUNT); } else {
static void *test(mps_arena_t arena, mps_class_t pool_class) { mps_chain_t chain; mps_fmt_t format; mps_pool_t pool; mps_root_t exactRoot; size_t i; unsigned long objs; struct stepper_data sdStruct, *sd; die(dylan_fmt(&format, arena), "fmt_create"); die(mps_chain_create(&chain, arena, genCOUNT, testChain), "chain_create"); MPS_ARGS_BEGIN(args) { MPS_ARGS_ADD(args, MPS_KEY_FORMAT, format); MPS_ARGS_ADD(args, MPS_KEY_CHAIN, chain); MPS_ARGS_ADD(args, MPS_KEY_AWL_FIND_DEPENDENT, test_awl_find_dependent); die(mps_pool_create_k(&pool, arena, pool_class, args), "pool_create"); } MPS_ARGS_END(args); die(mps_ap_create(&ap, pool, mps_rank_exact()), "ap_create"); for(i = 0; i < exactRootsCOUNT; ++i) exactRoots[i] = objNULL; die(mps_root_create_table_masked(&exactRoot, arena, mps_rank_exact(), (mps_rm_t)0, &exactRoots[0], exactRootsCOUNT, (mps_word_t)1), "root_create_table(exact)"); objs = 0; while(objs < objCOUNT) { size_t r; r = objs; i = r % exactRootsCOUNT; if(exactRoots[i] != objNULL) { cdie(dylan_check(exactRoots[i]), "dying root check"); } exactRoots[i] = make(); if(exactRoots[(exactRootsCOUNT-1) - i] != objNULL) dylan_write(exactRoots[(exactRootsCOUNT-1) - i], exactRoots, exactRootsCOUNT); ++objs; } sd = &sdStruct; sd->arena = arena; sd->expect_pool = pool; sd->expect_fmt = format; sd->count = 0; mps_arena_formatted_objects_walk(arena, stepper, sd, sizeof *sd); /* Note: stepper finds more than we expect, due to pad objects */ /* printf("stepper found %ld objs\n", sd->count); */ mps_ap_destroy(ap); mps_root_destroy(exactRoot); mps_pool_destroy(pool); mps_chain_destroy(chain); mps_fmt_destroy(format); return NULL; }
static Res MVTInit(Pool pool, Arena arena, PoolClass klass, ArgList args) { Size align = MVT_ALIGN_DEFAULT; Size minSize = MVT_MIN_SIZE_DEFAULT; Size meanSize = MVT_MEAN_SIZE_DEFAULT; Size maxSize = MVT_MAX_SIZE_DEFAULT; Count reserveDepth = MVT_RESERVE_DEPTH_DEFAULT; Count fragLimit = MVT_FRAG_LIMIT_DEFAULT; Size reuseSize, fillSize; Count abqDepth; MVT mvt; Res res; ArgStruct arg; AVER(pool != NULL); AVERT(Arena, arena); AVERT(ArgList, args); UNUSED(klass); /* used for debug pools only */ if (ArgPick(&arg, args, MPS_KEY_ALIGN)) align = arg.val.align; if (ArgPick(&arg, args, MPS_KEY_MIN_SIZE)) minSize = arg.val.size; if (ArgPick(&arg, args, MPS_KEY_MEAN_SIZE)) meanSize = arg.val.size; if (ArgPick(&arg, args, MPS_KEY_MAX_SIZE)) maxSize = arg.val.size; if (ArgPick(&arg, args, MPS_KEY_MVT_RESERVE_DEPTH)) reserveDepth = arg.val.count; if (ArgPick(&arg, args, MPS_KEY_MVT_FRAG_LIMIT)) { /* pending complete fix for job003319 */ AVER(0 <= arg.val.d); AVER(arg.val.d <= 1); fragLimit = (Count)(arg.val.d * 100); } AVERT(Align, align); /* This restriction on the alignment is necessary because of the use of a Freelist to store the free address ranges in low-memory situations. <design/freelist#.impl.grain.align>. */ AVER(AlignIsAligned(align, FreelistMinimumAlignment)); AVER(align <= ArenaGrainSize(arena)); AVER(0 < minSize); AVER(minSize <= meanSize); AVER(meanSize <= maxSize); AVER(reserveDepth > 0); AVER(fragLimit <= 100); /* TODO: More parameter checks possible? */ /* see <design/poolmvt#.arch.parameters> */ fillSize = SizeArenaGrains(maxSize, arena); /* see <design/poolmvt#.arch.fragmentation.internal> */ reuseSize = 2 * fillSize; abqDepth = (reserveDepth * meanSize + reuseSize - 1) / reuseSize; /* keep the abq from being useless */ if (abqDepth < 3) abqDepth = 3; res = NextMethod(Pool, MVTPool, init)(pool, arena, klass, args); if (res != ResOK) goto failNextInit; mvt = CouldBeA(MVTPool, pool); res = LandInit(MVTFreePrimary(mvt), CLASS(CBSFast), arena, align, mvt, mps_args_none); if (res != ResOK) goto failFreePrimaryInit; res = LandInit(MVTFreeSecondary(mvt), CLASS(Freelist), arena, align, mvt, mps_args_none); if (res != ResOK) goto failFreeSecondaryInit; MPS_ARGS_BEGIN(foArgs) { MPS_ARGS_ADD(foArgs, FailoverPrimary, MVTFreePrimary(mvt)); MPS_ARGS_ADD(foArgs, FailoverSecondary, MVTFreeSecondary(mvt)); res = LandInit(MVTFreeLand(mvt), CLASS(Failover), arena, align, mvt, foArgs); } MPS_ARGS_END(foArgs); if (res != ResOK) goto failFreeLandInit; res = ABQInit(arena, MVTABQ(mvt), (void *)mvt, abqDepth, sizeof(RangeStruct)); if (res != ResOK) goto failABQInit; pool->alignment = align; pool->alignShift = SizeLog2(pool->alignment); mvt->reuseSize = reuseSize; mvt->fillSize = fillSize; mvt->abqOverflow = FALSE; mvt->minSize = minSize; mvt->meanSize = meanSize; mvt->maxSize = maxSize; mvt->fragLimit = fragLimit; mvt->splinter = FALSE; mvt->splinterBase = (Addr)0; mvt->splinterLimit = (Addr)0; /* accounting */ mvt->size = 0; mvt->allocated = 0; mvt->available = 0; mvt->availLimit = 0; mvt->unavailable = 0; /* meters*/ METER_INIT(mvt->segAllocs, "segment allocations", (void *)mvt); METER_INIT(mvt->segFrees, "segment frees", (void *)mvt); METER_INIT(mvt->bufferFills, "buffer fills", (void *)mvt); METER_INIT(mvt->bufferEmpties, "buffer empties", (void *)mvt); METER_INIT(mvt->poolFrees, "pool frees", (void *)mvt); METER_INIT(mvt->poolSize, "pool size", (void *)mvt); METER_INIT(mvt->poolAllocated, "pool allocated", (void *)mvt); METER_INIT(mvt->poolAvailable, "pool available", (void *)mvt); METER_INIT(mvt->poolUnavailable, "pool unavailable", (void *)mvt); METER_INIT(mvt->poolUtilization, "pool utilization", (void *)mvt); METER_INIT(mvt->finds, "ABQ finds", (void *)mvt); METER_INIT(mvt->overflows, "ABQ overflows", (void *)mvt); METER_INIT(mvt->underflows, "ABQ underflows", (void *)mvt); METER_INIT(mvt->refills, "ABQ refills", (void *)mvt); METER_INIT(mvt->refillPushes, "ABQ refill pushes", (void *)mvt); METER_INIT(mvt->returns, "ABQ returns", (void *)mvt); METER_INIT(mvt->perfectFits, "perfect fits", (void *)mvt); METER_INIT(mvt->firstFits, "first fits", (void *)mvt); METER_INIT(mvt->secondFits, "second fits", (void *)mvt); METER_INIT(mvt->failures, "failures", (void *)mvt); METER_INIT(mvt->emergencyContingencies, "emergency contingencies", (void *)mvt); METER_INIT(mvt->fragLimitContingencies, "fragmentation limit contingencies", (void *)mvt); METER_INIT(mvt->contingencySearches, "contingency searches", (void *)mvt); METER_INIT(mvt->contingencyHardSearches, "contingency hard searches", (void *)mvt); METER_INIT(mvt->splinters, "splinters", (void *)mvt); METER_INIT(mvt->splintersUsed, "splinters used", (void *)mvt); METER_INIT(mvt->splintersDropped, "splinters dropped", (void *)mvt); METER_INIT(mvt->sawdust, "sawdust", (void *)mvt); METER_INIT(mvt->exceptions, "exceptions", (void *)mvt); METER_INIT(mvt->exceptionSplinters, "exception splinters", (void *)mvt); METER_INIT(mvt->exceptionReturns, "exception returns", (void *)mvt); SetClassOfPoly(pool, CLASS(MVTPool)); mvt->sig = MVTSig; AVERC(MVT, mvt); EVENT6(PoolInitMVT, pool, minSize, meanSize, maxSize, reserveDepth, fragLimit); return ResOK; failABQInit: LandFinish(MVTFreeLand(mvt)); failFreeLandInit: LandFinish(MVTFreeSecondary(mvt)); failFreeSecondaryInit: LandFinish(MVTFreePrimary(mvt)); failFreePrimaryInit: NextMethod(Inst, MVTPool, finish)(MustBeA(Inst, pool)); failNextInit: AVER(res != ResOK); return res; }
static void test(mps_arena_t arena, mps_pool_class_t pool_class) { mps_chain_t chain; mps_fmt_t format; mps_pool_t pool; mps_root_t exactRoot; size_t i; size_t totalSize, freeSize, allocSize, bufferSize; unsigned long objs; struct stepper_data sdStruct, *sd; PoolClass class; die(dylan_fmt(&format, arena), "fmt_create"); die(mps_chain_create(&chain, arena, genCOUNT, testChain), "chain_create"); MPS_ARGS_BEGIN(args) { MPS_ARGS_ADD(args, MPS_KEY_FORMAT, format); MPS_ARGS_ADD(args, MPS_KEY_CHAIN, chain); die(mps_pool_create_k(&pool, arena, pool_class, args), "pool_create"); } MPS_ARGS_END(args); die(mps_ap_create(&ap, pool, mps_rank_exact()), "ap_create"); for(i = 0; i < exactRootsCOUNT; ++i) exactRoots[i] = objNULL; die(mps_root_create_table_masked(&exactRoot, arena, mps_rank_exact(), (mps_rm_t)0, &exactRoots[0], exactRootsCOUNT, (mps_word_t)1), "root_create_table(exact)"); objs = 0; while(objs < objCOUNT) { size_t r; r = objs; i = r % exactRootsCOUNT; if(exactRoots[i] != objNULL) { cdie(dylan_check(exactRoots[i]), "dying root check"); } exactRoots[i] = make(); if(exactRoots[(exactRootsCOUNT-1) - i] != objNULL) dylan_write(exactRoots[(exactRootsCOUNT-1) - i], exactRoots, exactRootsCOUNT); ++objs; } mps_arena_park(arena); sd = &sdStruct; sd->arena = arena; sd->expect_pool = pool; sd->expect_fmt = format; sd->count = 0; sd->objSize = 0; sd->padSize = 0; mps_arena_formatted_objects_walk(arena, stepper, sd, sizeof *sd); Insist(sd->count == objs); totalSize = mps_pool_total_size(pool); freeSize = mps_pool_free_size(pool); allocSize = totalSize - freeSize; bufferSize = AddrOffset(ap->init, ap->limit); class = ClassOfPoly(Pool, pool); printf("%s: obj=%lu pad=%lu total=%lu free=%lu alloc=%lu buffer=%lu\n", ClassName(class), (unsigned long)sd->objSize, (unsigned long)sd->padSize, (unsigned long)totalSize, (unsigned long)freeSize, (unsigned long)allocSize, (unsigned long)bufferSize); Insist(sd->objSize + sd->padSize + bufferSize == allocSize); mps_ap_destroy(ap); mps_root_destroy(exactRoot); mps_pool_destroy(pool); mps_chain_destroy(chain); mps_fmt_destroy(format); mps_arena_release(arena); }
static void dt(int kind, size_t extendBy, size_t avgSize, unsigned long mins, unsigned long maxs, int number, int iter) { mps_pool_t pool; int i, hd; clock_t time0, time1; size_t size; double secs; asserts(number <= MAXNUMBER, "number too big"); time0 = clock(); asserts(time0 != -1, "processor time not available"); MPS_ARGS_BEGIN(args) { MPS_ARGS_ADD(args, MPS_KEY_EXTEND_BY, extendBy); MPS_ARGS_ADD(args, MPS_KEY_MEAN_SIZE, avgSize); cdie(mps_pool_create_k(&pool, arena, mps_class_mvff(), args), "pool"); } MPS_ARGS_END(args); for(hd=0; hd<number; hd++) { size = ranrange(mins, maxs); if ((ranint(2) && (kind & 2)) || (kind==DUMMY)) { queue[hd].addr=NULL; } else { die(mps_alloc(&queue[hd].addr, pool, size), "alloc"); setobj(queue[hd].addr, size, (unsigned char) (hd%256)); queue[hd].size = size; } }; hd=-1; for(i=0; i<iter; i++) { if (kind & 1) hd = ranint(number); else {ranint(number); hd=(hd+1)%number;} /* call raninit anyway to use same time */ if (queue[hd].addr != NULL) { asserts(chkobj(queue[hd].addr, queue[hd].size, (unsigned char) (hd%256)), "corrupt at %x (%s: %x, %x, %lx, %lx, %i, %i)", queue[hd].addr, tdesc[kind], (int) extendBy, (int) avgSize, mins, maxs, number, iter); mps_free(pool, queue[hd].addr, queue[hd].size); } size = ranrange(mins, maxs); if ((ranint(2) && (kind & 2)) || (kind==DUMMY)) { queue[hd].addr=NULL; } else { die(mps_alloc(&queue[hd].addr, pool, size),"alloc"); setobj(queue[hd].addr, size, (unsigned char) (hd%256)); queue[hd].size = size; } } mps_pool_destroy(pool); time1=clock(); secs=(time1-time0)/(double)CLOCKS_PER_SEC; comment("%s test (%x, %x, %lx, %lx, %i, %i) in %.2f s", tdesc[kind], (int) extendBy, (int) avgSize, mins, maxs, number, iter, secs); }