.
This commit is contained in:
parent
524ec0d1ce
commit
61c1060a98
16 changed files with 5043 additions and 31 deletions
235
tests/arena_tests.c
Normal file
235
tests/arena_tests.c
Normal file
|
|
@ -0,0 +1,235 @@
|
|||
#include "../colla.h"
|
||||
|
||||
#include "runner.h"
|
||||
|
||||
UNIT_TEST(arena_init_virtual) {
|
||||
arena_t arena = arena_make(ARENA_VIRTUAL, MB(1));
|
||||
ASSERT(arena.type == ARENA_VIRTUAL);
|
||||
ASSERT(arena.beg != NULL);
|
||||
ASSERT(arena.cur == arena.beg);
|
||||
ASSERT(arena.end == arena.beg + MB(1));
|
||||
arena_cleanup(&arena);
|
||||
}
|
||||
|
||||
UNIT_TEST(arena_init_malloc) {
|
||||
arena_t arena = arena_make(ARENA_MALLOC, KB(4));
|
||||
ASSERT(arena.type == ARENA_MALLOC);
|
||||
ASSERT(arena.beg != NULL);
|
||||
ASSERT(arena.cur == arena.beg);
|
||||
ASSERT(arena.end == arena.beg + KB(4));
|
||||
arena_cleanup(&arena);
|
||||
}
|
||||
|
||||
UNIT_TEST(arena_init_malloc_always) {
|
||||
arena_t arena = arena_make(ARENA_MALLOC_ALWAYS, KB(4));
|
||||
ASSERT(arena.type == ARENA_MALLOC_ALWAYS);
|
||||
arena_cleanup(&arena);
|
||||
}
|
||||
|
||||
UNIT_TEST(arena_init_static) {
|
||||
u8 buffer[KB(4)];
|
||||
arena_t arena = arena_make(ARENA_STATIC, KB(4), buffer);
|
||||
ASSERT(arena.type == ARENA_STATIC);
|
||||
ASSERT(arena.beg == buffer);
|
||||
ASSERT(arena.cur == arena.beg);
|
||||
ASSERT(arena.end == arena.beg + KB(4));
|
||||
arena_cleanup(&arena);
|
||||
}
|
||||
|
||||
UNIT_TEST(arena_alloc_basic) {
|
||||
arena_t arena = arena_make(ARENA_VIRTUAL, MB(1));
|
||||
int *ptr = alloc(&arena, int);
|
||||
ASSERT(ptr != NULL);
|
||||
*ptr = 42;
|
||||
ASSERT(*ptr == 42);
|
||||
ASSERT(arena.cur > arena.beg);
|
||||
arena_cleanup(&arena);
|
||||
}
|
||||
|
||||
UNIT_TEST(arena_alloc_array) {
|
||||
arena_t arena = arena_make(ARENA_VIRTUAL, MB(1));
|
||||
int *arr = alloc(&arena, int, .count = 10);
|
||||
ASSERT(arr != NULL);
|
||||
for (int i = 0; i < 10; i++) {
|
||||
arr[i] = i;
|
||||
}
|
||||
for (int i = 0; i < 10; i++) {
|
||||
ASSERT(arr[i] == i);
|
||||
}
|
||||
arena_cleanup(&arena);
|
||||
}
|
||||
|
||||
UNIT_TEST(arena_alloc_custom_align) {
|
||||
arena_t arena = arena_make(ARENA_VIRTUAL, MB(1));
|
||||
void *ptr = alloc(&arena, char, .align = 64);
|
||||
ASSERT(ptr != NULL);
|
||||
ASSERT(((uintptr_t)ptr & 63) == 0); // Should be 64-byte aligned
|
||||
arena_cleanup(&arena);
|
||||
}
|
||||
|
||||
UNIT_TEST(arena_alloc_nozero) {
|
||||
arena_t arena = arena_make(ARENA_VIRTUAL, MB(1));
|
||||
int *ptr1 = alloc(&arena, int);
|
||||
ASSERT(*ptr1 == 0); // Default zeroed
|
||||
|
||||
int *ptr2 = alloc(&arena, int, .flags = ALLOC_NOZERO);
|
||||
// We can't assert on the value as it's uninitialized
|
||||
ASSERT(ptr2 != NULL);
|
||||
arena_cleanup(&arena);
|
||||
}
|
||||
|
||||
UNIT_TEST(arena_alloc_soft_fail) {
|
||||
u8 buffer[10];
|
||||
arena_t arena = arena_make(ARENA_STATIC, 10, buffer);
|
||||
|
||||
void *ptr1 = alloc(&arena, char, .count = 5);
|
||||
ASSERT(ptr1 != NULL);
|
||||
|
||||
// This would normally fail, but with SOFT_FAIL it returns NULL
|
||||
void *ptr2 = alloc(&arena, char, .count = 10, .flags = ALLOC_SOFT_FAIL);
|
||||
ASSERT(ptr2 == NULL);
|
||||
|
||||
arena_cleanup(&arena);
|
||||
}
|
||||
|
||||
UNIT_TEST(arena_scratch) {
|
||||
arena_t arena = arena_make(ARENA_VIRTUAL, MB(1));
|
||||
arena_t scratch = arena_scratch(&arena, KB(1));
|
||||
|
||||
ASSERT(scratch.beg != NULL);
|
||||
ASSERT(scratch.type == ARENA_STATIC);
|
||||
|
||||
void *ptr = alloc(&scratch, int);
|
||||
ASSERT(ptr != NULL);
|
||||
|
||||
// Scratch cleanup happens implicitly when parent arena is cleaned up
|
||||
arena_cleanup(&arena);
|
||||
}
|
||||
|
||||
UNIT_TEST(arena_tell) {
|
||||
arena_t arena = arena_make(ARENA_VIRTUAL, MB(1));
|
||||
usize pos1 = arena_tell(&arena);
|
||||
ASSERT(pos1 == 0);
|
||||
|
||||
alloc(&arena, int);
|
||||
usize pos2 = arena_tell(&arena);
|
||||
ASSERT(pos2 > pos1);
|
||||
|
||||
arena_cleanup(&arena);
|
||||
}
|
||||
|
||||
UNIT_TEST(arena_remaining) {
|
||||
arena_t arena = arena_make(ARENA_VIRTUAL, KB(64));
|
||||
usize initial_remaining = arena_remaining(&arena);
|
||||
ASSERT(initial_remaining == KB(64));
|
||||
|
||||
alloc(&arena, char, .count = KB(4));
|
||||
usize after_alloc = arena_remaining(&arena);
|
||||
ASSERT(after_alloc < initial_remaining);
|
||||
ASSERT(after_alloc >= KB(60)); // Account for possible alignment padding
|
||||
|
||||
arena_cleanup(&arena);
|
||||
}
|
||||
|
||||
UNIT_TEST(arena_capacity) {
|
||||
arena_t arena = arena_make(ARENA_VIRTUAL, KB(64));
|
||||
usize cap = arena_capacity(&arena);
|
||||
ASSERT(cap == KB(64));
|
||||
arena_cleanup(&arena);
|
||||
}
|
||||
|
||||
UNIT_TEST(arena_rewind) {
|
||||
arena_t arena = arena_make(ARENA_VIRTUAL, MB(1));
|
||||
|
||||
usize mark = arena_tell(&arena);
|
||||
|
||||
int *ptr1 = alloc(&arena, int);
|
||||
*ptr1 = 42;
|
||||
|
||||
alloc(&arena, char, .count = 100);
|
||||
|
||||
arena_rewind(&arena, mark);
|
||||
|
||||
int *ptr2 = alloc(&arena, int);
|
||||
ASSERT(ptr2 == ptr1); // Should reuse the same memory
|
||||
|
||||
// Original value is lost after rewind
|
||||
*ptr2 = 24;
|
||||
ASSERT(*ptr2 == 24);
|
||||
|
||||
arena_cleanup(&arena);
|
||||
}
|
||||
|
||||
UNIT_TEST(arena_pop) {
|
||||
arena_t arena = arena_make(ARENA_VIRTUAL, MB(1));
|
||||
|
||||
alloc(&arena, char, .count = 100);
|
||||
usize pos = arena_tell(&arena);
|
||||
|
||||
alloc(&arena, char, .count = 50);
|
||||
|
||||
arena_pop(&arena, 50);
|
||||
ASSERT(arena_tell(&arena) == pos);
|
||||
|
||||
arena_cleanup(&arena);
|
||||
}
|
||||
|
||||
UNIT_TEST(arena_malloc_arena) {
|
||||
void *ptr = alloc(&malloc_arena, int);
|
||||
ASSERT(ptr != NULL);
|
||||
|
||||
// We need to free each allocation from malloc_arena manually
|
||||
os_free(ptr);
|
||||
}
|
||||
|
||||
UNIT_TEST(arena_alloc_mixed_types) {
|
||||
arena_t arena = arena_make(ARENA_VIRTUAL, MB(1));
|
||||
|
||||
int *i = alloc(&arena, int);
|
||||
float *f = alloc(&arena, float);
|
||||
char *c = alloc(&arena, char);
|
||||
|
||||
*i = 42;
|
||||
*f = 3.14f;
|
||||
*c = 'A';
|
||||
|
||||
ASSERT(*i == 42);
|
||||
ASSERT(*f == 3.14f);
|
||||
ASSERT(*c == 'A');
|
||||
|
||||
arena_cleanup(&arena);
|
||||
}
|
||||
|
||||
UNIT_TEST(arena_multiple_arenas) {
|
||||
arena_t arena1 = arena_make(ARENA_VIRTUAL, KB(4));
|
||||
arena_t arena2 = arena_make(ARENA_VIRTUAL, KB(4));
|
||||
|
||||
int *ptr1 = alloc(&arena1, int);
|
||||
int *ptr2 = alloc(&arena2, int);
|
||||
|
||||
*ptr1 = 42;
|
||||
*ptr2 = 24;
|
||||
|
||||
ASSERT(*ptr1 == 42);
|
||||
ASSERT(*ptr2 == 24);
|
||||
|
||||
arena_cleanup(&arena1);
|
||||
arena_cleanup(&arena2);
|
||||
}
|
||||
|
||||
UNIT_TEST(arena_stress_test) {
|
||||
arena_t arena = arena_make(ARENA_VIRTUAL, MB(10));
|
||||
|
||||
// Allocate many objects
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
int *ptr = alloc(&arena, int, .flags = ALLOC_SOFT_FAIL);
|
||||
ASSERT(ptr != NULL);
|
||||
*ptr = i;
|
||||
}
|
||||
|
||||
// Allocate a large block
|
||||
void *large = alloc(&arena, char, .count = MB(5), .flags = ALLOC_SOFT_FAIL);
|
||||
ASSERT(large != NULL);
|
||||
|
||||
arena_cleanup(&arena);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue