Kaltenberg/modules/utility/src-c/allocation/arena.c

58 lines
1.6 KiB
C
Raw Normal View History

#include <voxula/internals/utility/allocation.h>
#include <voxula/internals/utility/math.h>
#include <voxula/internals/utility/containers.h>
#include <stdlib.h>
#include <string.h>
vx_arena_s * vx_new_arena(uint32_t capacity)
{
vx_arena_s *arena = malloc(vx_ceil_to(sizeof(vx_arena_s), 32) + capacity);
arena->usage = 0;
arena->capacity = capacity;
arena->allocation = (void *) ((int8_t *) arena) + 32;
arena->continuation = NULL;
return arena;
}
void vx_free_arena(vx_arena_s *arena)
{
if(arena->continuation)
{
vx_free_arena(arena->continuation);
}
free(arena);
}
void * vx_arena_alloc(vx_arena_s *arena, uint32_t length)
{
if((arena->usage + length) >= arena->capacity)
{
if( ! arena->continuation)
{
arena->continuation = vx_new_arena(vx_max_u64(arena->capacity * 2, length * 2));
}
return vx_arena_alloc(arena->continuation, length);
}
void *allocation = (uint8_t *) arena->allocation + arena->usage;
arena->usage += length;
return allocation;
}
char * vx_arena_dupe_string(vx_arena_s *arena, const char *string)
{
uint32_t len_string = strlen(string);
char *string_duplicate = vx_arena_alloc(arena, len_string + 1);
memcpy(string_duplicate, string, len_string);
return string_duplicate;
}
char * vx_arena_dupe_string_up_to(vx_arena_s *arena, const char *string, uint32_t maximum)
{
uint32_t length = vx_measure_string_up_to(string, maximum);
char *string_duplicate = vx_arena_alloc(arena, length + 1);
memcpy(string_duplicate, string, length);
string_duplicate[length] = 0;
return string_duplicate;
}