diff --git a/src/base/arena.c b/src/base/arena.c index 55b2306..4c9bcd9 100644 --- a/src/base/arena.c +++ b/src/base/arena.c @@ -10,7 +10,7 @@ static MemoryBlock *memoryblock_allocate(U32 size, U32 commit_size, U32 page_siz MemoryBlock *block = memory_reserve(size); Assert(block != NULL); - memory_commit(block, commit_size); + memory_commit(block, commit_size, false); ASAN_POISON_MEMORY_REGION(block, 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); arena->flags = opts->flags; - arena->temp_level = 0; + arena->temp_level = 0; arena->current = block; arena->block_size = aligned_size; arena->commit_size = aligned_commit_size; @@ -61,7 +61,6 @@ void *arena_push(Arena *arena, U32 size, U32 align) { Assert(IsPow2(align)); - MemoryBlock *block = arena->current; U32 start_pos = AlignUp(block->first_free, align); // might align past block->size, handled in below check 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); 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; Assert(block->committed_end <= block->size); } diff --git a/src/base/arena.h b/src/base/arena.h index 170a824..9c152b2 100644 --- a/src/base/arena.h +++ b/src/base/arena.h @@ -89,7 +89,7 @@ static INLINE void *arena_allocator_func(Allocator *allocator, AllocOperation op return NULL; } - Assert(false); + ShouldNotHappen; } static INLINE Allocator arena_allocator(Arena *arena) diff --git a/src/base/platform.c b/src/base/platform.c index f8d19c1..e9ddc5c 100644 --- a/src/base/platform.c +++ b/src/base/platform.c @@ -91,7 +91,7 @@ void *memory_reserve(size_t size) 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(size)); @@ -100,7 +100,11 @@ void memory_commit(void *mem, size_t size) int rc; rc = mprotect(mem, size, PROT_READ | PROT_WRITE); 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); } diff --git a/src/base/platform.h b/src/base/platform.h index 6526d85..b04bf57 100644 --- a/src/base/platform.h +++ b/src/base/platform.h @@ -11,6 +11,7 @@ U32 platform_page_size(void); // Memory functions expect mem and size to be page aligned void *memory_allocate_and_commit(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_free(void *mem, size_t size); diff --git a/src/main.c b/src/main.c index 9098fc2..7d7f39d 100644 --- a/src/main.c +++ b/src/main.c @@ -8,10 +8,14 @@ #include #include +#define ARENA_DEBUG 1 void arena_dump(const Arena *arena) { - return; + if (!ARENA_DEBUG) { + return; + } + MemoryBlock *block = arena->current; puts("@@@@@@@@@@"); while (block) { @@ -19,7 +23,7 @@ void arena_dump(const Arena *arena) printf("base: %p\n", block->base); printf("size: %u\n", block->size); 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); puts("-----Arena end-"); block = block->prev; @@ -166,6 +170,28 @@ static void arena_test_4(void) 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) { TRACEF("\n\n"); @@ -741,6 +767,7 @@ int main(int argc, char *argv[]) arena_test_4(); arena_test_decommit(); arena_test_allocator_interface(); + arena_test_bigger_push(); miniarena_test1(); apool_test(); apool_test_autogrow();