Aligned arena allocation

This commit is contained in:
Martin Fouilleul 2023-09-29 10:44:43 +02:00
parent 549e640102
commit 90dd12a69f
2 changed files with 23 additions and 14 deletions

View File

@ -13,27 +13,27 @@
#if OC_PLATFORM_ORCA #if OC_PLATFORM_ORCA
enum enum
{ {
OC_ARENA_DEFAULT_RESERVE_SIZE = 1 << 20 OC_ARENA_DEFAULT_RESERVE_SIZE = 1 << 20,
}; };
#else #else
enum enum
{ {
OC_ARENA_DEFAULT_RESERVE_SIZE = 1 << 30 OC_ARENA_DEFAULT_RESERVE_SIZE = 1 << 30,
}; };
#endif #endif
enum enum
{ {
OC_ARENA_COMMIT_ALIGNMENT = 4 << 10 OC_ARENA_COMMIT_ALIGNMENT = 4 << 10,
}; };
//-------------------------------------------------------------------------------- //--------------------------------------------------------------------------------
//NOTE(martin): memory arena //NOTE(martin): memory arena
//-------------------------------------------------------------------------------- //--------------------------------------------------------------------------------
oc_arena_chunk* oc_arena_chunk_alloc(oc_arena* arena, u64 reserveSize) oc_arena_chunk* oc_arena_chunk_alloc(oc_arena* arena, u64 chunkMinSize)
{ {
reserveSize = oc_align_up_pow2(reserveSize, OC_ARENA_COMMIT_ALIGNMENT); u64 reserveSize = oc_align_up_pow2(chunkMinSize + sizeof(oc_arena_chunk), OC_ARENA_COMMIT_ALIGNMENT);
u64 commitSize = oc_align_up_pow2(sizeof(oc_arena_chunk), OC_ARENA_COMMIT_ALIGNMENT); u64 commitSize = oc_align_up_pow2(sizeof(oc_arena_chunk), OC_ARENA_COMMIT_ALIGNMENT);
char* mem = oc_base_reserve(arena->base, reserveSize); char* mem = oc_base_reserve(arena->base, reserveSize);
@ -77,18 +77,25 @@ void oc_arena_cleanup(oc_arena* arena)
} }
void* oc_arena_push(oc_arena* arena, u64 size) void* oc_arena_push(oc_arena* arena, u64 size)
{
return oc_arena_push_aligned(arena, size, 1);
}
void* oc_arena_push_aligned(oc_arena* arena, u64 size, u32 alignment)
{ {
oc_arena_chunk* chunk = arena->currentChunk; oc_arena_chunk* chunk = arena->currentChunk;
OC_ASSERT(chunk); OC_ASSERT(chunk);
u64 nextOffset = chunk->offset + size; u64 alignedOffset = oc_align_up_pow2(chunk->offset, alignment);
u64 nextOffset = alignedOffset + size;
u64 lastCap = chunk->cap; u64 lastCap = chunk->cap;
while(nextOffset > chunk->cap) while(nextOffset > chunk->cap)
{ {
chunk = oc_list_next_entry(arena->chunks, chunk, oc_arena_chunk, listElt); chunk = oc_list_next_entry(arena->chunks, chunk, oc_arena_chunk, listElt);
if(chunk) if(chunk)
{ {
nextOffset = chunk->offset + size; alignedOffset = oc_align_up_pow2(chunk->offset, alignment);
nextOffset = alignedOffset + size;
lastCap = chunk->cap; lastCap = chunk->cap;
} }
else else
@ -98,10 +105,11 @@ void* oc_arena_push(oc_arena* arena, u64 size)
} }
if(!chunk) if(!chunk)
{ {
u64 reserveSize = oc_max(lastCap * 1.5, size); u64 chunkMinSize = oc_max(lastCap * 1.5, size + alignment);
chunk = oc_arena_chunk_alloc(arena, reserveSize); chunk = oc_arena_chunk_alloc(arena, chunkMinSize);
nextOffset = chunk->offset + size; alignedOffset = oc_align_up_pow2(chunk->offset, alignment);
nextOffset = alignedOffset + size;
} }
OC_ASSERT(nextOffset <= chunk->cap); OC_ASSERT(nextOffset <= chunk->cap);
@ -115,8 +123,8 @@ void* oc_arena_push(oc_arena* arena, u64 size)
oc_base_commit(arena->base, chunk->ptr + chunk->committed, commitSize); oc_base_commit(arena->base, chunk->ptr + chunk->committed, commitSize);
chunk->committed = nextCommitted; chunk->committed = nextCommitted;
} }
char* p = chunk->ptr + chunk->offset; char* p = chunk->ptr + alignedOffset;
chunk->offset += size; chunk->offset = nextOffset;
return (p); return (p);
} }

View File

@ -55,13 +55,14 @@ ORCA_API void oc_arena_init_with_options(oc_arena* arena, oc_arena_options* opti
ORCA_API void oc_arena_cleanup(oc_arena* arena); ORCA_API void oc_arena_cleanup(oc_arena* arena);
ORCA_API void* oc_arena_push(oc_arena* arena, u64 size); ORCA_API void* oc_arena_push(oc_arena* arena, u64 size);
ORCA_API void* oc_arena_push_aligned(oc_arena* arena, u64 size, u32 alignment);
ORCA_API void oc_arena_clear(oc_arena* arena); ORCA_API void oc_arena_clear(oc_arena* arena);
ORCA_API oc_arena_scope oc_arena_scope_begin(oc_arena* arena); ORCA_API oc_arena_scope oc_arena_scope_begin(oc_arena* arena);
ORCA_API void oc_arena_scope_end(oc_arena_scope scope); ORCA_API void oc_arena_scope_end(oc_arena_scope scope);
#define oc_arena_push_type(arena, type) ((type*)oc_arena_push(arena, sizeof(type))) #define oc_arena_push_type(arena, type) ((type*)oc_arena_push_aligned(arena, sizeof(type), _Alignof(type)))
#define oc_arena_push_array(arena, type, count) ((type*)oc_arena_push(arena, sizeof(type) * (count))) #define oc_arena_push_array(arena, type, count) ((type*)oc_arena_push_aligned(arena, sizeof(type) * (count), _Alignof(type)))
//-------------------------------------------------------------------------------- //--------------------------------------------------------------------------------
//NOTE(martin): memory pool //NOTE(martin): memory pool