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;
|
MemoryBlock *prev = block->prev;
|
||||||
|
|
||||||
if (block->arena_offset >= total_offset) {
|
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);
|
memory_free(block->base, block->size);
|
||||||
arena->current = prev;
|
arena->current = prev;
|
||||||
} else {
|
} else {
|
||||||
@@ -123,8 +123,19 @@ void arena_reset_to(Arena *arena, U64 total_offset)
|
|||||||
new_pos = Max(MemoryBlock_Header_Size, new_pos);
|
new_pos = Max(MemoryBlock_Header_Size, new_pos);
|
||||||
// Disallow arbitrary pops to positions that previously were not commited.
|
// Disallow arbitrary pops to positions that previously were not commited.
|
||||||
Assert(new_pos <= block->committed_end);
|
Assert(new_pos <= block->committed_end);
|
||||||
|
Assert(new_pos <= block->size);
|
||||||
block->first_free = new_pos;
|
block->first_free = new_pos;
|
||||||
ASAN_POISON_MEMORY_REGION(&block->base[block->first_free], memoryblock_available(block));
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,9 @@
|
|||||||
|
|
||||||
typedef U32 ArenaFlags;
|
typedef U32 ArenaFlags;
|
||||||
typedef struct ArenaOptions ArenaOptions;
|
typedef struct ArenaOptions ArenaOptions;
|
||||||
|
enum {
|
||||||
|
ArenaFlag_NoDecommit, // arena_ temp_end/reset/reset_to doesn't decommit memory
|
||||||
|
};
|
||||||
struct ArenaOptions {
|
struct ArenaOptions {
|
||||||
U32 size;
|
U32 size;
|
||||||
U32 commit_size;
|
U32 commit_size;
|
||||||
|
|||||||
+33
-3
@@ -162,6 +162,34 @@ static void arena_test_4(void)
|
|||||||
|
|
||||||
arena_free(&arena);
|
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)
|
void miniarena_test1(void)
|
||||||
{
|
{
|
||||||
#define arena_size 4096
|
#define arena_size 4096
|
||||||
@@ -290,8 +318,10 @@ int main(int argc, char *argv[])
|
|||||||
// arena_test_2();
|
// arena_test_2();
|
||||||
// arena_test_3();
|
// arena_test_3();
|
||||||
// arena_test_4();
|
// arena_test_4();
|
||||||
// miniarena_test1();
|
arena_test_decommit();
|
||||||
apool_test();
|
|
||||||
apool_test_autogrow();
|
// miniarena_test1();
|
||||||
|
// apool_test();
|
||||||
|
// apool_test_autogrow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user