refactor: Changed align_arena to arena_align and changed signatrue, added arena_calculate_capacity

I need to assure that capacity is enough, i mean, for something like
an array just doubling size is good because you are storing things
that are the same size but for something like an arena you could actually
store anything so we need to make sure the growth factor stays cool while
an overflow doesn't occur, that's why the change with arena_calculate_capacity
and also changing signatrues to use results, A LOT of boilerplate but
i guess is fine for me.
This commit is contained in:
2026-03-29 20:59:32 -06:00
parent 00942d3bd6
commit a8423ca80f
2 changed files with 31 additions and 7 deletions

View File

@@ -36,6 +36,14 @@ typedef struct {
}; };
} ArenaResult; } ArenaResult;
typedef struct {
bool is_valid;
union {
ArenaErr err;
size_t val;
};
} SizeResult;
ArenaResult arena_init(size_t size); ArenaResult arena_init(size_t size);
void arena_destroy(Arena *arena); void arena_destroy(Arena *arena);
@@ -43,6 +51,7 @@ ArenaPointer arena_alloc(Arena *arena, size_t size, size_t alignment);
ArenaErr arena_push(Arena *arena, void *data, size_t size, size_t alignment); ArenaErr arena_push(Arena *arena, void *data, size_t size, size_t alignment);
ArenaErr arena_realloc(Arena *arena, size_t new_size); ArenaErr arena_realloc(Arena *arena, size_t new_size);
size_t align_arena_offset(Arena *arena, size_t alignment); SizeResult align_arena_offset(Arena *arena, size_t alignment);
SizeResult arena_compute_necessary_capacity(size_t capacity, size_t elem_size);
#endif // !ARENA_H #endif // !ARENA_H

View File

@@ -55,8 +55,16 @@ ArenaPointer arena_alloc(Arena *arena, size_t size, size_t alignment) {
return err; return err;
} }
size_t new_offset = align_arena_offset(arena, alignment); SizeResult new_offset = align_arena_offset(arena, alignment);
if (new_offset + size >= arena->size) { if (!new_offset.is_valid) {
ArenaPointer err = {
.is_valid = false,
.err = new_offset.err,
};
return err;
}
if (new_offset.val + size >= arena->size) {
ArenaPointer err = { ArenaPointer err = {
.is_valid = false, .is_valid = false,
.err = ARENA_OUT_OF_SPACE, .err = ARENA_OUT_OF_SPACE,
@@ -64,7 +72,7 @@ ArenaPointer arena_alloc(Arena *arena, size_t size, size_t alignment) {
return err; return err;
} }
arena->offset = new_offset; arena->offset = new_offset.val;
ArenaPointer val = { ArenaPointer val = {
.is_valid = true, .is_valid = true,
@@ -81,13 +89,18 @@ ArenaErr arena_push(Arena *arena, void *data, size_t size, size_t alignment) {
ArenaPointer pointer = arena_alloc(arena, size, alignment); ArenaPointer pointer = arena_alloc(arena, size, alignment);
if (!pointer.is_valid) { if (!pointer.is_valid) {
size_t new_size = arena->size * 2; SizeResult new_size = arena_compute_necessary_capacity(arena->size, size);
ArenaErr err = arena_realloc(arena, new_size); if (!new_size.is_valid) {
return new_size.err;
}
ArenaErr err = arena_realloc(arena, new_size.val);
if (err != ARENA_OK) { if (err != ARENA_OK) {
return err; return err;
} }
}
pointer = arena_alloc(arena, size, alignment);
}
memcpy( memcpy(
pointer.address, pointer.address,
@@ -111,3 +124,5 @@ ArenaErr arena_realloc(Arena *arena, size_t new_size) {
arena->size = new_size; arena->size = new_size;
return ARENA_OK; return ARENA_OK;
} }