Implement memory decommit
This commit is contained in:
+12
-1
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user