diff --git a/arena.c b/arena.c index 6d6d025..e82c208 100644 --- a/arena.c +++ b/arena.c @@ -100,7 +100,7 @@ MA_API void MA_SetAlignment(MA_Arena *arena, int alignment) { } MA_API uint8_t *MA_GetTop(MA_Arena *a) { - MA_ASSERT(a->memory.data); + MA_ASSERT(a->memory.data); // arena needs to be inited return a->memory.data + a->len; } diff --git a/arena.h b/arena.h index 7b505db..490871a 100644 --- a/arena.h +++ b/arena.h @@ -112,39 +112,37 @@ struct MA_Checkpoint { #define MA_CLAMP(x, min, max) ((x) >= (max) ? (max) : (x) <= (min) ? (min) \ : (x)) // clang-format off +MA_API void MA_InitEx(MA_Arena *a, size_t reserve); +MA_API void MA_Init(MA_Arena *a); +MA_API MA_Arena MA_Create(); +MA_API void MA_MakeSureInitialized(MA_Arena *a); +MA_API MA_Arena * MA_Bootstrap(void); +MA_API void MA_InitFromBuffer(MA_Arena *arena, void *buffer, size_t size); +MA_API MA_Arena MA_MakeFromBuffer(void *buffer, size_t size); +MA_API MA_Arena MA_PushArena(MA_Arena *arena, size_t size); + +MA_API void * MA_PushSizeNonZeroed(MA_Arena *a, size_t size); +MA_API void * MA_PushSize(MA_Arena *arena, size_t size); +MA_API char * MA_PushStringCopy(MA_Arena *arena, char *p, size_t size); +MA_API void * MA_PushCopy(MA_Arena *arena, void *p, size_t size); +MA_API MA_Checkpoint MA_Save(MA_Arena *arena); +MA_API void MA_Load(MA_Checkpoint checkpoint); + +MA_API void MA_PopToPos(MA_Arena *arena, size_t pos); +MA_API void * MA_PopSize(MA_Arena *arena, size_t size); +MA_API void MA_DeallocateArena(MA_Arena *arena); +MA_API void MA_DeallocateStub(MA_Arena *arena, void *p); +MA_API void MA_Reset(MA_Arena *arena); + MA_API void MA_MemoryZero(void *p, size_t size); MA_API void MA_MemoryCopy(void *dst, void *src, size_t size); MA_API size_t MA_GetAlignOffset(size_t size, size_t align); MA_API size_t MA_AlignUp(size_t size, size_t align); MA_API size_t MA_AlignDown(size_t size, size_t align); -MA_API void MA_DeallocateStub(MA_Arena *arena, void *p); - -MA_API void MA_InitEx(MA_Arena *a, size_t reserve); -MA_API void MA_Init(MA_Arena *a); -MA_API MA_Arena MA_Create(); - -MA_API void MA_PopToPos(MA_Arena *arena, size_t pos); -MA_API void * MA_PopSize(MA_Arena *arena, size_t size); -MA_API void MA_DeallocateArena(MA_Arena *arena); -MA_API void MA_Reset(MA_Arena *arena); +MA_API bool MA_IsPointerInside(MA_Arena *arena, void *p); MA_API void MA_SetAlignment(MA_Arena *arena, int alignment); MA_API uint8_t * MA_GetTop(MA_Arena *a); -MA_API void * MA_PushSizeNonZeroed(MA_Arena *a, size_t size); -MA_API void * MA_PushSize(MA_Arena *arena, size_t size); -MA_API void MA_MakeSureInitialized(MA_Arena *a); -MA_API MA_Arena * MA_Bootstrap(void); -MA_API void MA_InitFromBuffer(MA_Arena *arena, void *buffer, size_t size); -MA_API MA_Arena MA_MakeFromBuffer(void *buffer, size_t size); -MA_API char * MA_PushStringCopy(MA_Arena *arena, char *p, size_t size); -MA_API void * MA_PushCopy(MA_Arena *arena, void *p, size_t size); -MA_API bool MA_IsPointerInside(MA_Arena *arena, void *p); -MA_API MA_Arena MA_PushArena(MA_Arena *arena, size_t size); -MA_API MA_Checkpoint MA_Save(MA_Arena *arena); -MA_API void MA_Load(MA_Checkpoint checkpoint); -MA_API MA_Checkpoint MA_GetScratchEx(MA_Arena **conflicts, int conflict_count); -MA_API MA_Checkpoint MA_GetScratch(void); -MA_API MA_Checkpoint MA_GetScratch1(MA_Arena *conflict); MA_API MV_Memory MV_Reserve(size_t size); MA_API bool MV_Commit(MV_Memory *m, size_t commit); @@ -163,6 +161,10 @@ MA_API M_Allocator MA_GetAllocator(MA_Arena *arena); #ifndef MA_DISABLE_SCRATCH extern MA_THREAD_LOCAL MA_Arena MA_ScratchArenaPool[]; +MA_API MA_Checkpoint MA_GetScratchEx(MA_Arena **conflicts, int conflict_count); +MA_API MA_Checkpoint MA_GetScratch(void); +MA_API MA_Checkpoint MA_GetScratch1(MA_Arena *conflict); + #define MA_ScratchScope(x) for (MA_Checkpoint x = MA_GetScratch(); x.arena; (MA_ReleaseScratch(x), x.arena = 0)) #define MA_ReleaseScratch MA_Load @@ -170,6 +172,11 @@ extern MA_THREAD_LOCAL MA_Arena MA_ScratchArenaPool[]; struct MA_Scratch { MA_Checkpoint checkpoint; MA_Scratch() { this->checkpoint = MA_GetScratch(); } + MA_Scratch(MA_Checkpoint conflict) { this->checkpoint = MA_GetScratch1(conflict.arena); } + MA_Scratch(MA_Checkpoint c1, MA_Checkpoint c2) { + MA_Arena *conflicts[] = {c1.arena, c2.arena}; + this->checkpoint = MA_GetScratchEx(conflicts, 2); + } ~MA_Scratch() { MA_Load(checkpoint); } operator MA_Arena *() { return checkpoint.arena; } operator M_Allocator() { return MA_GetAllocator(checkpoint.arena); } diff --git a/build.bat b/build.bat index 4ba1e83..8382e12 100644 --- a/build.bat +++ b/build.bat @@ -15,12 +15,16 @@ mkdir build cd build +cl.exe -Fe:test_arena.exe ../test/test_arena.cpp %DEBUG_LINE% +if %errorlevel% neq 0 exit /b %errorlevel% +test_arena.exe +if %errorlevel% neq 0 exit /b %errorlevel% + cl.exe -Fe:test_table.exe ../test/test_table.cpp %DEBUG_LINE% if %errorlevel% neq 0 exit /b %errorlevel% test_table.exe if %errorlevel% neq 0 exit /b %errorlevel% - cl.exe -Fe:test_array.exe ../test/test_array.cpp %DEBUG_LINE% if %errorlevel% neq 0 exit /b %errorlevel% test_array.exe diff --git a/test/test_arena.cpp b/test/test_arena.cpp new file mode 100644 index 0000000..f67535d --- /dev/null +++ b/test/test_arena.cpp @@ -0,0 +1,55 @@ +#include "../core.c" + +void TestScratch() { + MA_Arena *scratch_arena_test = NULL; + { + MA_Scratch scratch; + IO_Assert(scratch.checkpoint.arena->len == 0); + IO_Assert(scratch.checkpoint.arena->memory.data == NULL); + int *a = MA_PushStruct(scratch, int); + IO_Assert(scratch.checkpoint.arena->memory.data); + IO_Assert(scratch.checkpoint.arena->len == sizeof(int)); + IO_Assert(scratch.checkpoint.arena); + scratch_arena_test = scratch.checkpoint.arena; + + int b = 10; + IO_Assert(MA_IsPointerInside(scratch, a)); + IO_Assert(!MA_IsPointerInside(scratch, &b)); + } + + { + MA_Scratch scratch; + IO_Assert(scratch_arena_test == scratch.checkpoint.arena); + IO_Assert(scratch.checkpoint.arena->len == 0); + + MA_Scratch scratch2(scratch.checkpoint); + IO_Assert(scratch.checkpoint.arena != scratch2.checkpoint.arena); + + MA_Scratch scratch3(scratch.checkpoint, scratch2.checkpoint); + IO_Assert(scratch3.checkpoint.arena != scratch2.checkpoint.arena); + } +} + +void TestBuffer() { + char buffer[1024]; + MA_Arena buffer_arena = MA_MakeFromBuffer(buffer, 1024); + void *result = MA_PushSize(&buffer_arena, 1024); + IO_Assert(buffer == result); + IO_Assert(buffer_arena.len == 1024); + IO_Assert(buffer_arena.memory.commit == 1024); + IO_Assert(buffer_arena.memory.reserve == 1024); +} + +void TestCreateAllocate() { + MA_Arena created_arena = MA_Create(); + IO_Assert(MA_GetTop(&created_arena) != 0); + MA_PushSize(&created_arena, MA_MIB(64)); + IO_Assert(created_arena.len == MA_MIB(64)); + MA_DeallocateArena(&created_arena); +} + +int main() { + TestScratch(); + TestBuffer(); + TestCreateAllocate(); +} \ No newline at end of file diff --git a/test/test_array.cpp b/test/test_array.cpp index c1e6de9..5632728 100644 --- a/test/test_array.cpp +++ b/test/test_array.cpp @@ -1,14 +1,4 @@ -#include "../io.c" -#define MA_ASSERT(x) IO_Assert(x) -#include "../arena.c" -#include "../defer.hpp" -#define ARRAY_REALLOCATE(allocator, p, size, old_size) M_ReallocNonZeroed(allocator, p, size, old_size) -#define ARRAY_DEALLOCATE(allocator, p) M_Dealloc(allocator, p) -#define ARRAY_Allocator M_Allocator -#define ARRAY_SET_DEFAULT_ALLOCATOR \ - if (!allocator.p) allocator = M_GetSystemAllocator(); -#include "../array.hpp" - +#include "../core.c" void TestExclusiveArenaBackedArray() { MA_Scratch scratch; MA_Arena ex = MA_Create(); @@ -105,7 +95,7 @@ void TestReverseLoop() { int i = 99; For(array.reverse()) { - assert(it == i--); + IO_Assert(it == i--); } array.dealloc();