Implement memory decommit

This commit is contained in:
Nils O. Selåsdal
2026-06-16 23:46:52 +02:00
parent 612b9f0e8a
commit 4a75eddd8f
3 changed files with 48 additions and 4 deletions
+12 -1
View File
@@ -115,7 +115,7 @@ void arena_reset_to(Arena *arena, U64 total_offset)
MemoryBlock *prev = block->prev;
if (block->arena_offset >= total_offset) {
ASAN_UNPOISON_MEMORY_REGION(block->base, block->size);
ASAN_UNPOISON_MEMORY_REGION(block->base, block->committed_end);
memory_free(block->base, block->size);
arena->current = prev;
} else {
@@ -123,8 +123,19 @@ void arena_reset_to(Arena *arena, U64 total_offset)
new_pos = Max(MemoryBlock_Header_Size, new_pos);
// Disallow arbitrary pops to positions that previously were not commited.
Assert(new_pos <= block->committed_end);
Assert(new_pos <= block->size);
block->first_free = new_pos;
ASAN_POISON_MEMORY_REGION(&block->base[block->first_free], memoryblock_available(block));
if ((arena->flags & ArenaFlag_NoDecommit) == 0) {
U32 aligned_pos = RoundUpToMultiple(block->first_free, arena->commit_size);
if (aligned_pos < block->committed_end) {
ASAN_UNPOISON_MEMORY_REGION(&block->base[aligned_pos], block->committed_end);
memory_decommit(&block->base[aligned_pos], block->committed_end - aligned_pos);
block->committed_end = aligned_pos;
}
}
break;
}
+3
View File
@@ -4,6 +4,9 @@
typedef U32 ArenaFlags;
typedef struct ArenaOptions ArenaOptions;
enum {
ArenaFlag_NoDecommit, // arena_ temp_end/reset/reset_to doesn't decommit memory
};
struct ArenaOptions {
U32 size;
U32 commit_size;
+32 -2
View File
@@ -162,6 +162,34 @@ static void arena_test_4(void)
arena_free(&arena);
}
static void arena_test_decommit(void)
{
TRACEF("\n");
U32 page_size = platform_page_size();
ArenaOptions arena_params = {};
U32 arena_size = MB(1) + MemoryBlock_Header_Size;
U32 commit_size = KB(64);
arena_params.size = arena_size;
arena_params.commit_size = commit_size;
Arena arena;
arena_init(&arena, &arena_params);
void *ptr = arena_push(&arena, commit_size * 10, 8);
MemoryZero(ptr, commit_size * 10);
arena_reset(&arena);
void *pre_ptr = arena_push(&arena, 5, 4);
ATemp tmp = arena_temp_begin(&arena);
ptr = arena_push(&arena, commit_size * 2 + 13, 8);
MemoryZero(ptr, commit_size * 2 + 13);
arena_temp_end(&tmp);
MemoryZero(pre_ptr, 5);
arena_free(&arena);
}
void miniarena_test1(void)
{
#define arena_size 4096
@@ -290,8 +318,10 @@ int main(int argc, char *argv[])
// arena_test_2();
// arena_test_3();
// arena_test_4();
arena_test_decommit();
// miniarena_test1();
apool_test();
apool_test_autogrow();
// apool_test();
// apool_test_autogrow();
}