diff --git a/engine/base/memory_arena.c b/engine/base/memory_arena.c index 5e9a867..47d166d 100644 --- a/engine/base/memory_arena.c +++ b/engine/base/memory_arena.c @@ -74,7 +74,7 @@ void mem_arena_print() printf("O1heap Memory Arena Info\n"); printf("--------------------\n"); printf("Capacity: %.3f MB\n", diag.capacity * 1.0 / 1024 / 1024); - printf("Allocated: %.3f MB\n", diag.allocated * 1.0 /1024/1024); + printf("Allocated: %.3f MB (%lu)\n", diag.allocated * 1.0 /1024/1024, diag.allocated); printf("Peak allocated: %.3f MB\n", diag.peak_allocated * 1.0 /1024/1024); printf("Peak request: %lu\n", diag.peak_request_size); printf("OOM count: %lu\n\n", diag.oom_count); @@ -97,14 +97,19 @@ void* mem_arena_malloc(size_t size) void mem_arena_free(void* ptr) { + // Because we keep track of the memory alloc'd, we can check if the memory + // being freed has been allocated by the heap. + // The free will be ignored if it is not from the heap. + // This is useful in case you want to mix static and dynamic memory in a component field. + // And you want to universally free the pointer without care. sc_mutex_lock(&lock); - o1heapFree(heap_handle, ptr); size_t* sz = cc_get(&mmap, (uintptr_t)ptr); - assert(sz != NULL); + //assert(sz != NULL); if (sz == NULL) { return; } + o1heapFree(heap_handle, ptr); total_mallocd -= *sz; assert(cc_erase(&mmap, (uintptr_t)ptr)); diff --git a/engine/tests/base/unit/mem_arena_unit.c b/engine/tests/base/unit/mem_arena_unit.c index 951bd77..d822cea 100644 --- a/engine/tests/base/unit/mem_arena_unit.c +++ b/engine/tests/base/unit/mem_arena_unit.c @@ -44,10 +44,25 @@ static void test_simple_malloc(void **state) assert_int_equal(mem_arena_get_allocated(), 0); } +static void test_free_unallocated(void **state) +{ + (void)state; + int val = 0; + mem_arena_free(&val); +} + +static void test_free_null(void **state) +{ + (void)state; + mem_arena_free(NULL); +} + int main(void) { const struct CMUnitTest tests[] = { cmocka_unit_test_setup_teardown(test_simple_malloc, setup_mem_arena, teardown_mem_arena), + cmocka_unit_test_setup_teardown(test_free_unallocated, setup_mem_arena, teardown_mem_arena), + cmocka_unit_test_setup_teardown(test_free_null, setup_mem_arena, teardown_mem_arena), }; return cmocka_run_group_tests(tests, NULL, NULL);