Add lazy commit option

This commit is contained in:
2026-09-23 18:33:29 +02:00
parent 25dc1cf8f5
commit b096434964
5 changed files with 41 additions and 10 deletions
+3 -4
View File
@@ -10,7 +10,7 @@ static MemoryBlock *memoryblock_allocate(U32 size, U32 commit_size, U32 page_siz
MemoryBlock *block = memory_reserve(size); MemoryBlock *block = memory_reserve(size);
Assert(block != NULL); Assert(block != NULL);
memory_commit(block, commit_size); memory_commit(block, commit_size, false);
ASAN_POISON_MEMORY_REGION(block, size); ASAN_POISON_MEMORY_REGION(block, size);
ASAN_UNPOISON_MEMORY_REGION(block, MemoryBlock_Header_Size); ASAN_UNPOISON_MEMORY_REGION(block, MemoryBlock_Header_Size);
@@ -38,7 +38,7 @@ void arena_init(Arena *arena, const ArenaOptions *opts)
MemoryBlock *block = memoryblock_allocate(aligned_size, aligned_commit_size, page_size); MemoryBlock *block = memoryblock_allocate(aligned_size, aligned_commit_size, page_size);
arena->flags = opts->flags; arena->flags = opts->flags;
arena->temp_level = 0; arena->temp_level = 0;
arena->current = block; arena->current = block;
arena->block_size = aligned_size; arena->block_size = aligned_size;
arena->commit_size = aligned_commit_size; arena->commit_size = aligned_commit_size;
@@ -61,7 +61,6 @@ void *arena_push(Arena *arena, U32 size, U32 align)
{ {
Assert(IsPow2(align)); Assert(IsPow2(align));
MemoryBlock *block = arena->current; MemoryBlock *block = arena->current;
U32 start_pos = AlignUp(block->first_free, align); // might align past block->size, handled in below check U32 start_pos = AlignUp(block->first_free, align); // might align past block->size, handled in below check
U32 available = block->size - start_pos; U32 available = block->size - start_pos;
@@ -97,7 +96,7 @@ void *arena_push(Arena *arena, U32 size, U32 align)
U32 aligned_size = RoundUpToMultiple(aligned_end_pos - block->committed_end, arena->commit_size); U32 aligned_size = RoundUpToMultiple(aligned_end_pos - block->committed_end, arena->commit_size);
aligned_size = Min(aligned_size, block->size - block->committed_end); aligned_size = Min(aligned_size, block->size - block->committed_end);
memory_commit(&block->base[block->committed_end], aligned_size); memory_commit(&block->base[block->committed_end], aligned_size, false);
block->committed_end += aligned_size; block->committed_end += aligned_size;
Assert(block->committed_end <= block->size); Assert(block->committed_end <= block->size);
} }
+1 -1
View File
@@ -89,7 +89,7 @@ static INLINE void *arena_allocator_func(Allocator *allocator, AllocOperation op
return NULL; return NULL;
} }
Assert(false); ShouldNotHappen;
} }
static INLINE Allocator arena_allocator(Arena *arena) static INLINE Allocator arena_allocator(Arena *arena)
+6 -2
View File
@@ -91,7 +91,7 @@ void *memory_reserve(size_t size)
return mem; return mem;
} }
void memory_commit(void *mem, size_t size) void memory_commit(void *mem, size_t size, bool lazy)
{ {
Assert(IsPageAligned((UMM)mem)); Assert(IsPageAligned((UMM)mem));
Assert(IsPageAligned(size)); Assert(IsPageAligned(size));
@@ -100,7 +100,11 @@ void memory_commit(void *mem, size_t size)
int rc; int rc;
rc = mprotect(mem, size, PROT_READ | PROT_WRITE); rc = mprotect(mem, size, PROT_READ | PROT_WRITE);
Assert(rc == 0); Assert(rc == 0);
rc = madvise(mem, size, MADV_WILLNEED); if (lazy) {
rc = madvise(mem, size, MADV_POPULATE_WRITE);
} else {
rc = madvise(mem, size, MADV_WILLNEED);
}
Assert(rc == 0); Assert(rc == 0);
} }
+2 -1
View File
@@ -11,6 +11,7 @@ U32 platform_page_size(void);
// Memory functions expect mem and size to be page aligned // Memory functions expect mem and size to be page aligned
void *memory_allocate_and_commit(size_t size); void *memory_allocate_and_commit(size_t size);
void *memory_reserve(size_t size); void *memory_reserve(size_t size);
void memory_commit(void *mem, size_t size);
void memory_commit(void *mem, size_t size, bool lazy);
void memory_decommit(void *mem, size_t size); void memory_decommit(void *mem, size_t size);
void memory_free(void *mem, size_t size); void memory_free(void *mem, size_t size);
+29 -2
View File
@@ -8,10 +8,14 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#define ARENA_DEBUG 1
void arena_dump(const Arena *arena) void arena_dump(const Arena *arena)
{ {
return; if (!ARENA_DEBUG) {
return;
}
MemoryBlock *block = arena->current; MemoryBlock *block = arena->current;
puts("@@@@@@@@@@"); puts("@@@@@@@@@@");
while (block) { while (block) {
@@ -19,7 +23,7 @@ void arena_dump(const Arena *arena)
printf("base: %p\n", block->base); printf("base: %p\n", block->base);
printf("size: %u\n", block->size); printf("size: %u\n", block->size);
printf("first_free: %u\n", block->first_free); printf("first_free: %u\n", block->first_free);
printf("total_used: %lu\n",block->arena_offset); printf("arena_offset: %lu\n",block->arena_offset);
printf("prev: %p\n", block->prev); printf("prev: %p\n", block->prev);
puts("-----Arena end-"); puts("-----Arena end-");
block = block->prev; block = block->prev;
@@ -166,6 +170,28 @@ static void arena_test_4(void)
arena_free(&arena); arena_free(&arena);
} }
static void arena_test_bigger_push(void)
{
TRACEF("\n\n");
ArenaOptions arena_params = {};
U32 arena_size = KB(256) + MemoryBlock_Header_Size;
U32 commit_size = KB(8);
arena_params.size = arena_size;
arena_params.commit_size = commit_size;
Arena arena;
arena_init(&arena, &arena_params);
arena_dump(&arena);
void *ptr = arena_push(&arena, KB(256), 1);
MemoryZero(ptr, 512);
printf("Allocated ptr %p\n", ptr);
arena_dump(&arena);
ptr = arena_push(&arena, MB(4), 4);
MemoryZero(ptr, MB(4));
printf("Allocated ptr %p\n", ptr);
arena_dump(&arena);
arena_free(&arena);
}
static void arena_test_allocator_interface(void) static void arena_test_allocator_interface(void)
{ {
TRACEF("\n\n"); TRACEF("\n\n");
@@ -741,6 +767,7 @@ int main(int argc, char *argv[])
arena_test_4(); arena_test_4();
arena_test_decommit(); arena_test_decommit();
arena_test_allocator_interface(); arena_test_allocator_interface();
arena_test_bigger_push();
miniarena_test1(); miniarena_test1();
apool_test(); apool_test();
apool_test_autogrow(); apool_test_autogrow();