/* TEST_HEADER id = $HopeName: MMQA_test_function!118.c(trunk.5) $ summary = Collect with a fully initialised (but not committed) buffer language = c link = testlib.o END_HEADER */ #include "testlib.h" #include "mpscamc.h" #include "mpsavm.h" #define genCOUNT (3) static mps_gen_param_s testChain[genCOUNT] = { { 6000, 0.90 }, { 8000, 0.65 }, { 16000, 0.50 } }; #define testArenaSIZE ((size_t)64<<20) /* objSIZE should be such that when this size is requested in a reserve */ /* the buffer gets filled with exactly this much memory */ #define objSIZE 8192 static mps_ap_t ap; static mps_res_t simple_scan(mps_ss_t ss, mps_addr_t base, mps_addr_t limit) { return MPS_RES_OK; } static mps_addr_t simple_skip(mps_addr_t limit) { return (void *)((char *)limit + objSIZE); } static void simple_fwd(mps_addr_t old, mps_addr_t new) { ((mps_addr_t *)old)[1] = new; ((mps_word_t *)old)[0] = 1; } static mps_addr_t simple_is_fwd(mps_addr_t obj) { if(*(mps_word_t *)obj) { return ((mps_addr_t *)obj)[1]; } else { return NULL; } } static void simple_pad(mps_addr_t addr, size_t size) { } static void simple_copy(mps_addr_t obj, mps_addr_t to) { error("copy method not implemented in this test"); } struct mps_fmt_A_s simple_fmt_A = { 4, &simple_scan, &simple_skip, &simple_copy, &simple_fwd, &simple_is_fwd, &simple_pad }; static mps_addr_t make(void) { size_t size = objSIZE; mps_addr_t p; mps_res_t res; do { MPS_RESERVE_BLOCK(res, p, ap, size); if(res) die(res, "MPS_RESERVE_BLOCK"); *(mps_word_t *)p = 0; } while(!mps_commit(ap, p, size)); return p; } static void test(void) { mps_addr_t busy_init; mps_ap_t busy_ap; mps_arena_t arena; mps_thr_t thread; mps_fmt_t format; mps_chain_t chain; mps_pool_t pool; unsigned long i; die(mps_arena_create(&arena, mps_arena_class_vm(), testArenaSIZE), "arena_create"); die(mps_thread_reg(&thread, arena), "thread_reg"); die(mps_fmt_create_A(&format, arena, &simple_fmt_A), "fmt_create"); die(mps_chain_create(&chain, arena, genCOUNT, testChain), "chain_create"); die(mmqa_pool_create_chain(&pool, arena, mps_class_amc(), format, chain), "create pool"); die(mps_ap_create(&ap, pool, MPS_RANK_EXACT), "BufferCreate"); die(mps_ap_create(&busy_ap, pool, MPS_RANK_EXACT), "BufferCreate"); /* create an ap, and leave it busy */ die(mps_reserve(&busy_init, busy_ap, objSIZE), "mps_reserve busy"); /* now simulate first part of commit */ busy_ap->init = busy_ap->alloc; for(i = 0; i < 100000; ++i) { make(); } /* now simulate rest of commit */ (void)(busy_ap->limit != 0 || mps_ap_trip(busy_ap, busy_init, objSIZE)); mps_ap_destroy(busy_ap); mps_ap_destroy(ap); mps_pool_destroy(pool); mps_chain_destroy(chain); mps_fmt_destroy(format); mps_thread_dereg(thread); mps_arena_destroy(arena); } int main(void) { easy_tramp(test); pass(); return 0; }