int test_memory_managment() { #define MM_PARAMS n, 16, sizeof(int) int i, n; int *baz, *buf = vm_zalloc(tvm, sizeof(int) * 16); n = 14; for (i = 0; i < n; ++i) buf[i] = i; baz = mm_need(tvm, buf, MM_PARAMS); ASSERT_TRUE(buf == baz); for (i = 0; i < n; ++i) ASSERT_EQ(int, baz[i], i); n = 16; buf = mm_need(tvm, baz, MM_PARAMS); ASSERT_TRUE(buf == baz); for (i = 0; i < 14; ++i) ASSERT_EQ(int, buf[i], i); ASSERT_EQ(int, buf[14], 0); ASSERT_EQ(int, buf[15], 0); baz = mm_shrink(tvm, buf, MM_PARAMS); ASSERT_TRUE(buf == baz); n = 4; buf = mm_shrink(tvm, baz, MM_PARAMS); ASSERT_FALSE(buf == baz); for (i = 0; i < n; ++i) ASSERT_EQ(int, buf[i], i); #undef MM_PARAMS mm_free(tvm, buf, n, sizeof(int)); return 0; }
/** \brief Reduce the commit limit, down to the limit given, using only actions below the cost given. Must only be called within low-memory synchronization. */ static Bool mm_regain_extensions(Bool *enough, corecontext_t *context, mm_cost_t fill_limit, mm_cost_t cost) { Bool retry_low_mem = TRUE /* pacify the compiler */; memory_requirement_t request; mm_commit_extension_t *extension; *enough = TRUE; if ( mm_commit_limit <= mm_arena_extension.base ) return TRUE; /* quick return for the common case of no extensions */ request.pool = NULL; do { if ( mm_shrink(&mm_use_all, fill_limit) ) if ( mm_shrink(&mm_arena_extension, fill_limit) ) return TRUE; /* got it now */ else extension = &mm_arena_extension; else extension = &mm_use_all; /* @@@@ Change this to an array of requests. Or even return a request to be combine with original? */ request.size = mm_commit_limit - extension->base; request.cost = mm_cost_min(extension->cost, cost); if ( !low_mem_handle_guts(&retry_low_mem, context, 1, &request) ) { *enough = FALSE; return FALSE; /* error */ } } while ( retry_low_mem ); *enough = FALSE; return TRUE; /* didn't get it */ }
Bool mm_refill_reserves_guts(Bool *enough, mm_cost_t limit) { *enough = mm_reserve_get(limit) && (mm_commit_limit <= mm_arena_extension.base /* quick test for the common case */ || (mm_shrink(&mm_use_all, limit) && mm_shrink(&mm_arena_extension, limit))); return TRUE; }