2026-03-29 10:40:09 -06:00
|
|
|
#include "arena.h"
|
2026-03-29 17:53:10 -06:00
|
|
|
#include <stdbool.h>
|
2026-03-30 11:26:05 -06:00
|
|
|
#include <stddef.h>
|
|
|
|
|
#include <stdint.h>
|
2026-03-29 17:53:10 -06:00
|
|
|
#include <stdlib.h>
|
2026-03-29 18:35:13 -06:00
|
|
|
#include <string.h>
|
2026-03-29 17:53:10 -06:00
|
|
|
|
2026-04-10 20:54:02 -06:00
|
|
|
|
|
|
|
|
|
2026-03-30 11:26:05 -06:00
|
|
|
ArenaResult arena_init(size_t capacity) {
|
refactor(all): Fixed alloc and moved growing logic to another function
OK, so evrything was a fucknig mess, it still kinda is, AI helped
me to clean my own mess, it really sucks but the fucking debugger
and address sanitizer were not working, also, there were small
small errors so no big deal but still, a bit sad, also changed a
the way i cast from uint8_t to double and int in the tests, may
change that i guess, verything else i might say is good :)
2026-04-03 12:44:01 -06:00
|
|
|
if (capacity < 1) {
|
2026-04-03 15:57:54 -06:00
|
|
|
return (ArenaResult) {.is_valid = false, .err = ARENA_INVALID_SIZE};
|
2026-03-29 17:53:10 -06:00
|
|
|
}
|
|
|
|
|
|
refactor(all): Fixed alloc and moved growing logic to another function
OK, so evrything was a fucknig mess, it still kinda is, AI helped
me to clean my own mess, it really sucks but the fucking debugger
and address sanitizer were not working, also, there were small
small errors so no big deal but still, a bit sad, also changed a
the way i cast from uint8_t to double and int in the tests, may
change that i guess, verything else i might say is good :)
2026-04-03 12:44:01 -06:00
|
|
|
void *buffer = malloc(capacity);
|
|
|
|
|
if (buffer == NULL) {
|
2026-04-03 15:57:54 -06:00
|
|
|
return (ArenaResult) {.is_valid = false, .err = ARENA_BAD_ALLOC};
|
2026-03-29 17:53:10 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Arena new_arena = {
|
2026-03-29 19:06:49 -06:00
|
|
|
.buffer = buffer,
|
2026-03-30 11:26:05 -06:00
|
|
|
.capacity = capacity,
|
2026-03-29 17:53:10 -06:00
|
|
|
.offset = 0,
|
|
|
|
|
};
|
|
|
|
|
|
2026-04-03 15:57:54 -06:00
|
|
|
return (ArenaResult) {.is_valid = true, .arena = new_arena};
|
2026-03-29 17:53:10 -06:00
|
|
|
}
|
2026-03-29 18:00:57 -06:00
|
|
|
|
|
|
|
|
void arena_destroy(Arena *arena) {
|
refactor(all): Fixed alloc and moved growing logic to another function
OK, so evrything was a fucknig mess, it still kinda is, AI helped
me to clean my own mess, it really sucks but the fucking debugger
and address sanitizer were not working, also, there were small
small errors so no big deal but still, a bit sad, also changed a
the way i cast from uint8_t to double and int in the tests, may
change that i guess, verything else i might say is good :)
2026-04-03 12:44:01 -06:00
|
|
|
free(arena->buffer);
|
|
|
|
|
arena->buffer = NULL;
|
2026-03-29 18:00:57 -06:00
|
|
|
arena->offset = 0;
|
2026-03-30 11:26:05 -06:00
|
|
|
arena->capacity = 0;
|
2026-03-29 18:00:57 -06:00
|
|
|
}
|
2026-03-29 18:35:13 -06:00
|
|
|
|
|
|
|
|
ArenaPointer arena_alloc(Arena *arena, size_t size, size_t alignment) {
|
|
|
|
|
if (arena == NULL) {
|
2026-04-03 15:57:54 -06:00
|
|
|
return (ArenaPointer) {.is_valid = false, .err = ARENA_NULL_ARG};
|
2026-03-29 18:35:13 -06:00
|
|
|
}
|
|
|
|
|
|
2026-04-11 11:30:04 -06:00
|
|
|
if (size < 1) {
|
|
|
|
|
return (ArenaPointer) {.is_valid = false, .err = ARENA_INVALID_SIZE};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (alignment < 1) {
|
|
|
|
|
return (ArenaPointer) {.is_valid = false, .err = ARENA_INVALID_ALIGN};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SizeResult padding = arena_get_align_padding(arena, alignment);
|
refactor(all): Fixed alloc and moved growing logic to another function
OK, so evrything was a fucknig mess, it still kinda is, AI helped
me to clean my own mess, it really sucks but the fucking debugger
and address sanitizer were not working, also, there were small
small errors so no big deal but still, a bit sad, also changed a
the way i cast from uint8_t to double and int in the tests, may
change that i guess, verything else i might say is good :)
2026-04-03 12:44:01 -06:00
|
|
|
if (!padding.is_valid) {
|
2026-04-03 15:57:54 -06:00
|
|
|
return (ArenaPointer) {.is_valid = false, .err = padding.err};
|
2026-03-29 20:59:32 -06:00
|
|
|
}
|
|
|
|
|
|
2026-04-11 11:30:04 -06:00
|
|
|
if (arena->offset + padding.val + size > arena->capacity) {
|
2026-04-03 15:57:54 -06:00
|
|
|
return (ArenaPointer) {.is_valid = false, .err = ARENA_OUT_OF_SPACE};
|
2026-03-29 18:35:13 -06:00
|
|
|
}
|
|
|
|
|
|
refactor(all): Fixed alloc and moved growing logic to another function
OK, so evrything was a fucknig mess, it still kinda is, AI helped
me to clean my own mess, it really sucks but the fucking debugger
and address sanitizer were not working, also, there were small
small errors so no big deal but still, a bit sad, also changed a
the way i cast from uint8_t to double and int in the tests, may
change that i guess, verything else i might say is good :)
2026-04-03 12:44:01 -06:00
|
|
|
if (arena->offset > SIZE_MAX - padding.val - size) {
|
2026-04-03 15:57:54 -06:00
|
|
|
return (ArenaPointer) {.is_valid = false, .err = ARENA_CAPACITY_OVERFLOW};
|
refactor(all): Fixed alloc and moved growing logic to another function
OK, so evrything was a fucknig mess, it still kinda is, AI helped
me to clean my own mess, it really sucks but the fucking debugger
and address sanitizer were not working, also, there were small
small errors so no big deal but still, a bit sad, also changed a
the way i cast from uint8_t to double and int in the tests, may
change that i guess, verything else i might say is good :)
2026-04-03 12:44:01 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
size_t aligned_offset = arena->offset + padding.val;
|
2026-03-29 18:35:13 -06:00
|
|
|
|
refactor(all): Fixed alloc and moved growing logic to another function
OK, so evrything was a fucknig mess, it still kinda is, AI helped
me to clean my own mess, it really sucks but the fucking debugger
and address sanitizer were not working, also, there were small
small errors so no big deal but still, a bit sad, also changed a
the way i cast from uint8_t to double and int in the tests, may
change that i guess, verything else i might say is good :)
2026-04-03 12:44:01 -06:00
|
|
|
arena->offset = aligned_offset + size;
|
2026-04-10 20:54:02 -06:00
|
|
|
return (ArenaPointer) {.is_valid = true, .offset = aligned_offset, .arena = arena};
|
2026-03-29 18:35:13 -06:00
|
|
|
}
|
2026-03-29 19:06:49 -06:00
|
|
|
|
refactor(all): Fixed alloc and moved growing logic to another function
OK, so evrything was a fucknig mess, it still kinda is, AI helped
me to clean my own mess, it really sucks but the fucking debugger
and address sanitizer were not working, also, there were small
small errors so no big deal but still, a bit sad, also changed a
the way i cast from uint8_t to double and int in the tests, may
change that i guess, verything else i might say is good :)
2026-04-03 12:44:01 -06:00
|
|
|
ArenaErr arena_ensure_capacity(Arena *arena, size_t size, size_t alignment) {
|
|
|
|
|
if (arena == NULL) {
|
|
|
|
|
return ARENA_NULL_ARG;
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-11 21:15:31 -06:00
|
|
|
if (size == 0 || size == SIZE_MAX) {
|
2026-04-11 11:30:04 -06:00
|
|
|
return ARENA_INVALID_SIZE;
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-11 21:15:31 -06:00
|
|
|
if (alignment == 0 || (alignment & (alignment - 1)) != 0) {
|
2026-04-11 11:30:04 -06:00
|
|
|
return ARENA_INVALID_ALIGN;
|
|
|
|
|
}
|
2026-04-11 21:15:31 -06:00
|
|
|
|
|
|
|
|
SizeResult padding_res = arena_get_align_padding(arena, alignment);
|
|
|
|
|
if (!padding_res.is_valid) {
|
|
|
|
|
return padding_res.err;
|
2026-04-03 12:51:49 -06:00
|
|
|
}
|
2026-04-11 21:15:31 -06:00
|
|
|
|
|
|
|
|
size_t padding = padding_res.val;
|
|
|
|
|
|
refactor(all): Fixed alloc and moved growing logic to another function
OK, so evrything was a fucknig mess, it still kinda is, AI helped
me to clean my own mess, it really sucks but the fucking debugger
and address sanitizer were not working, also, there were small
small errors so no big deal but still, a bit sad, also changed a
the way i cast from uint8_t to double and int in the tests, may
change that i guess, verything else i might say is good :)
2026-04-03 12:44:01 -06:00
|
|
|
while (true) {
|
2026-04-11 21:15:31 -06:00
|
|
|
size_t required;
|
|
|
|
|
|
|
|
|
|
if (arena->offset > SIZE_MAX - padding) {
|
refactor(all): Fixed alloc and moved growing logic to another function
OK, so evrything was a fucknig mess, it still kinda is, AI helped
me to clean my own mess, it really sucks but the fucking debugger
and address sanitizer were not working, also, there were small
small errors so no big deal but still, a bit sad, also changed a
the way i cast from uint8_t to double and int in the tests, may
change that i guess, verything else i might say is good :)
2026-04-03 12:44:01 -06:00
|
|
|
return ARENA_CAPACITY_OVERFLOW;
|
|
|
|
|
}
|
2026-04-11 21:15:31 -06:00
|
|
|
required = arena->offset + padding;
|
refactor(all): Fixed alloc and moved growing logic to another function
OK, so evrything was a fucknig mess, it still kinda is, AI helped
me to clean my own mess, it really sucks but the fucking debugger
and address sanitizer were not working, also, there were small
small errors so no big deal but still, a bit sad, also changed a
the way i cast from uint8_t to double and int in the tests, may
change that i guess, verything else i might say is good :)
2026-04-03 12:44:01 -06:00
|
|
|
|
2026-04-11 21:15:31 -06:00
|
|
|
if (required > SIZE_MAX - size) {
|
|
|
|
|
return ARENA_CAPACITY_OVERFLOW;
|
|
|
|
|
}
|
|
|
|
|
required += size;
|
refactor(all): Fixed alloc and moved growing logic to another function
OK, so evrything was a fucknig mess, it still kinda is, AI helped
me to clean my own mess, it really sucks but the fucking debugger
and address sanitizer were not working, also, there were small
small errors so no big deal but still, a bit sad, also changed a
the way i cast from uint8_t to double and int in the tests, may
change that i guess, verything else i might say is good :)
2026-04-03 12:44:01 -06:00
|
|
|
|
|
|
|
|
if (required <= arena->capacity) {
|
|
|
|
|
return ARENA_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
size_t new_capacity;
|
2026-04-11 21:15:31 -06:00
|
|
|
|
|
|
|
|
if (arena->capacity > SIZE_MAX / 2) {
|
refactor(all): Fixed alloc and moved growing logic to another function
OK, so evrything was a fucknig mess, it still kinda is, AI helped
me to clean my own mess, it really sucks but the fucking debugger
and address sanitizer were not working, also, there were small
small errors so no big deal but still, a bit sad, also changed a
the way i cast from uint8_t to double and int in the tests, may
change that i guess, verything else i might say is good :)
2026-04-03 12:44:01 -06:00
|
|
|
return ARENA_CAPACITY_OVERFLOW;
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-11 21:15:31 -06:00
|
|
|
new_capacity = arena->capacity * 2;
|
|
|
|
|
|
|
|
|
|
if (new_capacity < required) {
|
|
|
|
|
new_capacity = required;
|
|
|
|
|
}
|
|
|
|
|
|
refactor(all): Fixed alloc and moved growing logic to another function
OK, so evrything was a fucknig mess, it still kinda is, AI helped
me to clean my own mess, it really sucks but the fucking debugger
and address sanitizer were not working, also, there were small
small errors so no big deal but still, a bit sad, also changed a
the way i cast from uint8_t to double and int in the tests, may
change that i guess, verything else i might say is good :)
2026-04-03 12:44:01 -06:00
|
|
|
ArenaErr err = arena_realloc(arena, new_capacity);
|
|
|
|
|
if (err != ARENA_OK) {
|
|
|
|
|
return err;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
test and rework: Added push test and cahnged arena_push return
So added a little test that just adds 3 ints to an arena, nothing much
but the basics work, also changed arena_push because it only pushed and
didn't returned a ponter (wich is fucking useless) so also fixed that,
everything seems fine now, need more tests.
# Tipos:
# feat, fix, refactor, docs, style, test, chore
2026-03-31 19:15:37 -06:00
|
|
|
ArenaPointer arena_push(Arena *arena, void *data, size_t size, size_t alignment) {
|
2026-03-29 19:06:49 -06:00
|
|
|
if (arena == NULL || data == NULL) {
|
2026-04-03 15:57:54 -06:00
|
|
|
return (ArenaPointer) {.is_valid = false, .err = ARENA_NULL_ARG};
|
2026-03-29 19:06:49 -06:00
|
|
|
}
|
|
|
|
|
|
2026-04-11 11:30:04 -06:00
|
|
|
if (size < 1) {
|
|
|
|
|
return (ArenaPointer) {.is_valid = false, .err = ARENA_INVALID_SIZE};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (size < 1) {
|
|
|
|
|
return (ArenaPointer) {.is_valid = false, .err = ARENA_INVALID_ALIGN};
|
|
|
|
|
}
|
|
|
|
|
|
refactor(all): Fixed alloc and moved growing logic to another function
OK, so evrything was a fucknig mess, it still kinda is, AI helped
me to clean my own mess, it really sucks but the fucking debugger
and address sanitizer were not working, also, there were small
small errors so no big deal but still, a bit sad, also changed a
the way i cast from uint8_t to double and int in the tests, may
change that i guess, verything else i might say is good :)
2026-04-03 12:44:01 -06:00
|
|
|
ArenaErr err = arena_ensure_capacity(arena, size, alignment);
|
|
|
|
|
if (err != ARENA_OK) {
|
2026-04-03 15:57:54 -06:00
|
|
|
return (ArenaPointer) {.is_valid = false, .err = err};
|
refactor(all): Fixed alloc and moved growing logic to another function
OK, so evrything was a fucknig mess, it still kinda is, AI helped
me to clean my own mess, it really sucks but the fucking debugger
and address sanitizer were not working, also, there were small
small errors so no big deal but still, a bit sad, also changed a
the way i cast from uint8_t to double and int in the tests, may
change that i guess, verything else i might say is good :)
2026-04-03 12:44:01 -06:00
|
|
|
}
|
2026-03-29 19:06:49 -06:00
|
|
|
|
refactor(all): Fixed alloc and moved growing logic to another function
OK, so evrything was a fucknig mess, it still kinda is, AI helped
me to clean my own mess, it really sucks but the fucking debugger
and address sanitizer were not working, also, there were small
small errors so no big deal but still, a bit sad, also changed a
the way i cast from uint8_t to double and int in the tests, may
change that i guess, verything else i might say is good :)
2026-04-03 12:44:01 -06:00
|
|
|
ArenaPointer pointer = arena_alloc(arena, size, alignment);
|
2026-03-29 19:06:49 -06:00
|
|
|
if (!pointer.is_valid) {
|
test and rework: Added push test and cahnged arena_push return
So added a little test that just adds 3 ints to an arena, nothing much
but the basics work, also changed arena_push because it only pushed and
didn't returned a ponter (wich is fucking useless) so also fixed that,
everything seems fine now, need more tests.
# Tipos:
# feat, fix, refactor, docs, style, test, chore
2026-03-31 19:15:37 -06:00
|
|
|
return pointer;
|
2026-03-30 11:26:05 -06:00
|
|
|
}
|
refactor(all): Fixed alloc and moved growing logic to another function
OK, so evrything was a fucknig mess, it still kinda is, AI helped
me to clean my own mess, it really sucks but the fucking debugger
and address sanitizer were not working, also, there were small
small errors so no big deal but still, a bit sad, also changed a
the way i cast from uint8_t to double and int in the tests, may
change that i guess, verything else i might say is good :)
2026-04-03 12:44:01 -06:00
|
|
|
|
2026-03-29 19:06:49 -06:00
|
|
|
memcpy(
|
2026-04-10 20:54:02 -06:00
|
|
|
arena_unwrap_pointer(pointer),
|
2026-03-29 19:06:49 -06:00
|
|
|
data,
|
|
|
|
|
size);
|
|
|
|
|
|
test and rework: Added push test and cahnged arena_push return
So added a little test that just adds 3 ints to an arena, nothing much
but the basics work, also changed arena_push because it only pushed and
didn't returned a ponter (wich is fucking useless) so also fixed that,
everything seems fine now, need more tests.
# Tipos:
# feat, fix, refactor, docs, style, test, chore
2026-03-31 19:15:37 -06:00
|
|
|
return pointer;
|
2026-03-29 19:06:49 -06:00
|
|
|
}
|
|
|
|
|
|
2026-03-30 11:26:05 -06:00
|
|
|
ArenaErr arena_realloc(Arena *arena, size_t new_capacity) {
|
2026-03-29 19:06:49 -06:00
|
|
|
if (arena == NULL) {
|
|
|
|
|
return ARENA_NULL_ARG;
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-11 11:30:04 -06:00
|
|
|
if (new_capacity < 1) {
|
|
|
|
|
return ARENA_INVALID_SIZE;
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-30 11:26:05 -06:00
|
|
|
uint8_t *tmp = realloc(arena->buffer, new_capacity);
|
2026-03-29 19:06:49 -06:00
|
|
|
if (tmp == NULL) {
|
|
|
|
|
return ARENA_BAD_ALLOC;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
arena->buffer = tmp;
|
2026-03-30 11:26:05 -06:00
|
|
|
arena->capacity = new_capacity;
|
2026-03-29 19:06:49 -06:00
|
|
|
return ARENA_OK;
|
|
|
|
|
}
|
2026-03-29 20:59:32 -06:00
|
|
|
|
2026-04-10 20:54:02 -06:00
|
|
|
|
|
|
|
|
|
2026-04-11 11:30:04 -06:00
|
|
|
SizeResult arena_get_align_padding(Arena *arena, size_t alignment) {
|
2026-03-29 21:08:34 -06:00
|
|
|
if (arena == NULL) {
|
2026-04-11 21:15:31 -06:00
|
|
|
return (SizeResult){ .is_valid = false, .err = ARENA_NULL_ARG };
|
2026-03-29 21:08:34 -06:00
|
|
|
}
|
|
|
|
|
|
2026-04-11 21:15:31 -06:00
|
|
|
if (alignment == 0 || (alignment & (alignment - 1)) != 0) {
|
|
|
|
|
return (SizeResult){ .is_valid = false, .err = ARENA_INVALID_ALIGN };
|
2026-03-29 21:08:34 -06:00
|
|
|
}
|
|
|
|
|
|
2026-04-11 21:15:31 -06:00
|
|
|
uintptr_t current_address = (uintptr_t)(arena->buffer + arena->offset);
|
|
|
|
|
|
|
|
|
|
size_t mask = alignment - 1;
|
|
|
|
|
size_t padding = (size_t)(-current_address) & mask;
|
2026-04-03 15:57:54 -06:00
|
|
|
|
2026-04-11 21:15:31 -06:00
|
|
|
return (SizeResult){
|
|
|
|
|
.is_valid = true,
|
|
|
|
|
.val = padding
|
|
|
|
|
};
|
2026-03-29 21:08:34 -06:00
|
|
|
}
|
2026-03-29 20:59:32 -06:00
|
|
|
|
2026-04-10 20:54:02 -06:00
|
|
|
void *arena_unwrap_pointer(ArenaPointer p) {
|
|
|
|
|
if (!p.is_valid) {
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
return p.arena->buffer + p.offset;
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-30 11:26:05 -06:00
|
|
|
|