finished free list allocator (linked list) and added small test
This commit is contained in:
parent
f57018317a
commit
7602982c93
2
build.sh
2
build.sh
@ -57,7 +57,7 @@ clang_out="-o"
|
|||||||
gcc_common="${include_flags} ${render_flag} -DCOMPILER_GCC -std=c99 -fuse-ld=mold -g -Wno-unknown-warning-option -Wall -Wno-missing-braces -Wno-unused-function -Wno-attributes -Wno-unused-value -Wno-unused-variable -Wno-unused-local-typedef -Wno-deprecated-declarations -Wno-unused-but-set-variable -Wno-compare-distinct-pointer-types -D_USE_MATH_DEFINES -Dstrdup=_strdup -Dgnu_printf=printf -DVMA_STATIC_VULKAN_FUNCTIONS=0"
|
gcc_common="${include_flags} ${render_flag} -DCOMPILER_GCC -std=c99 -fuse-ld=mold -g -Wno-unknown-warning-option -Wall -Wno-missing-braces -Wno-unused-function -Wno-attributes -Wno-unused-value -Wno-unused-variable -Wno-unused-local-typedef -Wno-deprecated-declarations -Wno-unused-but-set-variable -Wno-compare-distinct-pointer-types -D_USE_MATH_DEFINES -Dstrdup=_strdup -Dgnu_printf=printf -DVMA_STATIC_VULKAN_FUNCTIONS=0"
|
||||||
gcc_debug="$compiler -g -O0 -DBUILD_DEBUG=1 ${gcc_common}"
|
gcc_debug="$compiler -g -O0 -DBUILD_DEBUG=1 ${gcc_common}"
|
||||||
gcc_release="$compiler -O2 ${gcc_common} ${render_flag}"
|
gcc_release="$compiler -O2 ${gcc_common} ${render_flag}"
|
||||||
gcc_test="$compiler -O2 -DBUILD_TEST=1 ${gcc_common} ${render_flag}"
|
gcc_test="$compiler -O0 -DBUILD_TEST=1 ${gcc_common} ${render_flag}"
|
||||||
gcc_link="-lpthread -lm -lrt -ldl ${render_link} -lstdc++"
|
gcc_link="-lpthread -lm -lrt -ldl ${render_link} -lstdc++"
|
||||||
gcc_out="-o"
|
gcc_out="-o"
|
||||||
|
|
||||||
|
|||||||
259
src/allocators.c
259
src/allocators.c
@ -1,7 +1,7 @@
|
|||||||
// ::Allocator::Globals::
|
// ::Allocator::Globals::
|
||||||
|
|
||||||
Allocator g_alloc;
|
Allocator g_alloc;
|
||||||
read_only FLNode FL_NIL_NODE = {};
|
read_only FLNode FL_NIL_NODE = {0};
|
||||||
|
|
||||||
// ::Allocator::Util::Header::
|
// ::Allocator::Util::Header::
|
||||||
|
|
||||||
@ -95,6 +95,8 @@ static Arena * CreateArenaDebug(rawptr buffer, usize length, u32 init_line_no)
|
|||||||
|
|
||||||
// ::Allocator::Arena::End::
|
// ::Allocator::Arena::End::
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ::Allocator::GlobalAlloc::Start::
|
// ::Allocator::GlobalAlloc::Start::
|
||||||
|
|
||||||
static void InitAllocator(usize init_size, usize grow_size)
|
static void InitAllocator(usize init_size, usize grow_size)
|
||||||
@ -152,34 +154,71 @@ static void AllocGrow()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ::Allocator::FreeList::End::
|
// ::Allocator::GlobalAlloc::End::
|
||||||
|
|
||||||
static void FLAllocInit(FLAlloc *alloc, usize size)
|
|
||||||
|
|
||||||
|
// ::Allocator::FreeList::Start::
|
||||||
|
|
||||||
|
static void FreeListInit(FLAlloc *alloc, usize size)
|
||||||
{
|
{
|
||||||
alloc->data = MemAllocZeroed(size);
|
alloc->lists = MemAllocZeroed(sizeof(FreeList *) * 16);
|
||||||
alloc->size = size;
|
alloc->list_count = 1;
|
||||||
|
alloc->list_capacity = 16;
|
||||||
|
alloc->ticket = 0;
|
||||||
|
alloc->next_ticket = 0;
|
||||||
alloc->nil = &FL_NIL_NODE;
|
alloc->nil = &FL_NIL_NODE;
|
||||||
FLAllocFreeAll(alloc);
|
alloc->grow_size = size;
|
||||||
|
|
||||||
|
_FreeListInit(&alloc->lists[0], size);
|
||||||
|
|
||||||
|
FreeListFreeAll(alloc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void FLAllocFreeAll(FLAlloc *alloc)
|
static void _FreeListInit(FreeList **alloc, usize size)
|
||||||
{
|
{
|
||||||
FLNode *node = (FLNode *)alloc->data;
|
*alloc = (FreeList *)MemAllocZeroed(size);
|
||||||
node->size = alloc->size;
|
(*alloc)->data = (rawptr)(((uintptr)*alloc) + ((uintptr)sizeof(FreeList)));
|
||||||
node->next = alloc->nil;
|
(*alloc)->size = size;
|
||||||
|
(*alloc)->used = sizeof(FreeList);
|
||||||
alloc->used = 0;
|
|
||||||
alloc->head = node;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static FLNode *FreeListSearch(FLAlloc *alloc, usize size, u32 alignment, u32 *out_padding, FLNode **prev_node)
|
static void FreeListFreeAll(FLAlloc *alloc)
|
||||||
|
{
|
||||||
|
u32 ticket = __atomic_fetch_add(&alloc->ticket, 1, __ATOMIC_SEQ_CST);
|
||||||
|
while (ticket != alloc->next_ticket);
|
||||||
|
|
||||||
|
if (alloc->list_count > 1)
|
||||||
|
{
|
||||||
|
for (u32 i = 1; i < alloc->list_count; i++)
|
||||||
|
{
|
||||||
|
MemFree(alloc->lists[i], alloc->lists[i]->size);
|
||||||
|
alloc->lists[i] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
alloc->list_count = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
FLNode *node = (FLNode *)alloc->lists[0]->data;
|
||||||
|
node->size = alloc->lists[0]->size;
|
||||||
|
node->next = &FL_NIL_NODE;
|
||||||
|
|
||||||
|
alloc->lists[0]->head = node;
|
||||||
|
alloc->lists[0]->used = sizeof(FreeList);
|
||||||
|
|
||||||
|
__atomic_thread_fence(__ATOMIC_RELEASE);
|
||||||
|
|
||||||
|
__atomic_fetch_add(&alloc->next_ticket, 1, __ATOMIC_SEQ_CST);
|
||||||
|
}
|
||||||
|
|
||||||
|
static FLNode *FreeListSearch(FreeList *alloc, usize size, usize alignment, usize *out_padding, FLNode **prev_node)
|
||||||
{
|
{
|
||||||
FLNode *node = alloc->head;
|
FLNode *node = alloc->head;
|
||||||
FLNode *prev = alloc->nil;
|
FLNode *prev = &FL_NIL_NODE;
|
||||||
|
|
||||||
usize padding = 0;
|
usize padding = 0;
|
||||||
|
|
||||||
while (node != alloc->nil)
|
while (node != &FL_NIL_NODE)
|
||||||
{
|
{
|
||||||
padding = CalcPaddingWithHeader((uintptr)node, (uintptr)alignment, sizeof(FLNode));
|
padding = CalcPaddingWithHeader((uintptr)node, (uintptr)alignment, sizeof(FLNode));
|
||||||
usize required_size = size + padding;
|
usize required_size = size + padding;
|
||||||
@ -199,12 +238,194 @@ static FLNode *FreeListSearch(FLAlloc *alloc, usize size, u32 alignment, u32 *ou
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
static rawptr FreeListAlloc(FLAlloc *alloc, usize size, u32 alignment)
|
/*
|
||||||
|
* NOT SAFE TO CALL OUTSIDE OF FreeListAlloc
|
||||||
|
*/
|
||||||
|
static void FreeListGrow(FLAlloc *alloc, usize alloc_size)
|
||||||
|
{
|
||||||
|
alloc->list_count += 1;
|
||||||
|
u32 i = alloc->list_count;
|
||||||
|
if (i >= alloc->list_capacity)
|
||||||
|
{
|
||||||
|
alloc->list_capacity += 16;
|
||||||
|
rawptr new_mem = MemAlloc(sizeof(FreeList *) * alloc->list_capacity);
|
||||||
|
MemCpy(new_mem, alloc->lists, i);
|
||||||
|
MemFree(alloc->lists, sizeof(FreeList *) * i);
|
||||||
|
alloc->lists = new_mem;
|
||||||
|
}
|
||||||
|
|
||||||
|
usize grow_size = alloc->grow_size;
|
||||||
|
if (alloc_size > grow_size)
|
||||||
|
grow_size += alloc_size;
|
||||||
|
|
||||||
|
_FreeListInit(&alloc->lists[i], grow_size);
|
||||||
|
|
||||||
|
FLNode *node = (FLNode *)alloc->lists[i]->data;
|
||||||
|
node->size = alloc->lists[i]->size;
|
||||||
|
node->next = alloc->nil;
|
||||||
|
|
||||||
|
alloc->lists[i]->head = node;
|
||||||
|
}
|
||||||
|
|
||||||
|
static rawptr _FreeListAllocAlign(FreeList *alloc, usize size, u32 alignment)
|
||||||
{
|
{
|
||||||
usize padding = 0;
|
usize padding = 0;
|
||||||
FLNode *prev_node = alloc->nil;
|
FLNode *prev_node = &FL_NIL_NODE;
|
||||||
|
|
||||||
|
FLAllocHeader *header;
|
||||||
|
|
||||||
|
if (size < sizeof(FLNode))
|
||||||
|
size = sizeof(FLNode);
|
||||||
|
|
||||||
|
if (alignment < 8)
|
||||||
|
alignment = 8;
|
||||||
|
|
||||||
|
FLNode *node = FreeListSearch(alloc, size, alignment, &padding, &prev_node);
|
||||||
|
|
||||||
|
if (node == &FL_NIL_NODE)
|
||||||
|
Assert(0, "FreeListAllocAlign failed to allocate, oom");
|
||||||
|
|
||||||
return NULL;
|
usize alignment_padding = padding - sizeof(FLAllocHeader);
|
||||||
|
usize required_space = size + padding;
|
||||||
|
usize remaining = node->size - required_space;
|
||||||
|
|
||||||
|
if (remaining > 0)
|
||||||
|
{
|
||||||
|
FLNode *new_node = (FLNode *)(((c8 *)node) + required_space);
|
||||||
|
new_node->size = remaining;
|
||||||
|
FreeListInsert(&alloc->head, node, new_node);
|
||||||
|
}
|
||||||
|
|
||||||
|
FreeListRemove(&alloc->head, prev_node, node);
|
||||||
|
|
||||||
|
header = (FLAllocHeader *)(((c8 *)node) + alignment_padding);
|
||||||
|
header->size = required_space;
|
||||||
|
header->padding = alignment_padding;
|
||||||
|
|
||||||
|
alloc->used += required_space;
|
||||||
|
|
||||||
|
return (rawptr)(((c8 *)header) + sizeof(FLAllocHeader));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static rawptr FreeListAlloc(FLAlloc *alloc, usize size)
|
||||||
|
{
|
||||||
|
return FreeListAllocAlign(alloc, size, DEFAULT_ALIGNMENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
static rawptr FreeListAllocAlign(FLAlloc *alloc, usize size, u32 alignment)
|
||||||
|
{
|
||||||
|
u32 ticket = __atomic_fetch_add(&alloc->ticket, 1, __ATOMIC_SEQ_CST);
|
||||||
|
while (ticket != alloc->next_ticket);
|
||||||
|
|
||||||
|
FreeList *fl = NULL;
|
||||||
|
for (u32 i = 0; i < alloc->list_count; i++)
|
||||||
|
{
|
||||||
|
usize remaining = alloc->lists[i]->size - alloc->lists[i]->used;
|
||||||
|
if (size < remaining)
|
||||||
|
{
|
||||||
|
fl = alloc->lists[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fl == NULL)
|
||||||
|
{
|
||||||
|
FreeListGrow(alloc, size);
|
||||||
|
fl = alloc->lists[alloc->list_count-1];
|
||||||
|
}
|
||||||
|
|
||||||
|
rawptr ptr = _FreeListAllocAlign(fl, size, alignment);
|
||||||
|
|
||||||
|
__atomic_thread_fence(__ATOMIC_RELEASE);
|
||||||
|
|
||||||
|
__atomic_add_fetch(&alloc->next_ticket, 1, __ATOMIC_SEQ_CST);
|
||||||
|
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _FreeListFree(FreeList *alloc, rawptr ptr)
|
||||||
|
{
|
||||||
|
FLAllocHeader *header = cast(FLAllocHeader *, u8ptr(ptr) - sizeof(FLAllocHeader));
|
||||||
|
FLNode *free_node = cast(FLNode *,header);
|
||||||
|
free_node->size = header->size + header->padding;
|
||||||
|
free_node->next = &FL_NIL_NODE;
|
||||||
|
|
||||||
|
FLNode *prev_node = &FL_NIL_NODE;
|
||||||
|
FLNode *node = alloc->head;
|
||||||
|
while (node != &FL_NIL_NODE)
|
||||||
|
{
|
||||||
|
if (ptr < node)
|
||||||
|
{
|
||||||
|
FreeListInsert(&alloc->head, prev_node, free_node);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
prev_node = node;
|
||||||
|
node = node->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
alloc->used -= free_node->size;
|
||||||
|
|
||||||
|
FreeListCoalescence(alloc, prev_node, free_node);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void FreeListFree(FLAlloc *alloc, rawptr ptr)
|
||||||
|
{
|
||||||
|
if (ptr == NULL) return;
|
||||||
|
|
||||||
|
u32 ticket = __atomic_fetch_add(&alloc->ticket, 1, __ATOMIC_SEQ_CST);
|
||||||
|
while (ticket != alloc->next_ticket);
|
||||||
|
|
||||||
|
for (u32 i = 0; i < alloc->list_count; i++)
|
||||||
|
{
|
||||||
|
uintptr ptr_addr = uintptr(ptr);
|
||||||
|
uintptr start = uintptr(alloc->lists[i]->data);
|
||||||
|
uintptr end = uintptr(alloc->lists[i]->data) + uintptr(alloc->lists[i]->size);
|
||||||
|
if (ptr_addr >= start && ptr_addr < end)
|
||||||
|
{
|
||||||
|
_FreeListFree(alloc->lists[i], ptr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void FreeListCoalescence(FreeList *alloc, FLNode *prev_node, FLNode *free_node)
|
||||||
|
{
|
||||||
|
if (free_node->next != &FL_NIL_NODE && (rawptr)(((c8 *)free_node) + free_node->size) == free_node->next)
|
||||||
|
{
|
||||||
|
free_node->size += free_node->next->size;
|
||||||
|
FreeListRemove(&alloc->head, free_node, free_node->next);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (prev_node->next != &FL_NIL_NODE && (rawptr)(((c8 *)prev_node) + prev_node->size) == free_node)
|
||||||
|
{
|
||||||
|
prev_node->size += free_node->next->size;
|
||||||
|
FreeListRemove(&alloc->head, prev_node, free_node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void FreeListRemove(FLNode **head, FLNode *prev_node, FLNode *del_node)
|
||||||
|
{
|
||||||
|
if (prev_node == &FL_NIL_NODE)
|
||||||
|
*head = del_node->next;
|
||||||
|
else
|
||||||
|
prev_node->next = del_node->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void FreeListInsert(FLNode **head, FLNode *prev_node, FLNode *new_node)
|
||||||
|
{
|
||||||
|
if (prev_node == &FL_NIL_NODE)
|
||||||
|
{
|
||||||
|
if (*head != &FL_NIL_NODE)
|
||||||
|
new_node->next = *head;
|
||||||
|
else
|
||||||
|
*head = new_node;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
new_node->next = prev_node->next;
|
||||||
|
prev_node->next = new_node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ::Allocator::FreeList::End::
|
||||||
|
|||||||
@ -58,7 +58,7 @@ static void Free(rawptr ptr);
|
|||||||
|
|
||||||
typedef struct FLAllocHeader
|
typedef struct FLAllocHeader
|
||||||
{
|
{
|
||||||
usize block_size;
|
usize size;
|
||||||
usize padding;
|
usize padding;
|
||||||
} FLAllocHeader;
|
} FLAllocHeader;
|
||||||
|
|
||||||
@ -70,16 +70,35 @@ typedef struct FLNode
|
|||||||
usize size;
|
usize size;
|
||||||
} FLNode;
|
} FLNode;
|
||||||
|
|
||||||
typedef struct FLAlloc
|
typedef struct FreeList
|
||||||
{
|
{
|
||||||
rawptr data;
|
rawptr data;
|
||||||
FLNode *head;
|
FLNode *head;
|
||||||
FLNode *nil;
|
|
||||||
usize size;
|
usize size;
|
||||||
usize used;
|
usize used;
|
||||||
|
} FreeList;
|
||||||
|
|
||||||
|
typedef struct FLAlloc
|
||||||
|
{
|
||||||
|
FreeList **lists;
|
||||||
|
u32 list_count;
|
||||||
|
u32 list_capacity;
|
||||||
|
u32 volatile ticket;
|
||||||
|
u32 volatile next_ticket;
|
||||||
|
FLNode *nil;
|
||||||
|
usize grow_size;
|
||||||
} FLAlloc;
|
} FLAlloc;
|
||||||
|
|
||||||
static void FLAllocInit(FLAlloc *alloc, usize size);
|
static void _FreeListInit(FreeList **alloc, usize size);
|
||||||
static void FLAllocFreeAll(FLAlloc *alloc);
|
static void FreeListInit(FLAlloc *alloc, usize size);
|
||||||
static FLNode *FreeListSearch(FLAlloc *alloc, usize size, u32 alignment, u32 *out_padding, FLNode **prev_node);
|
static rawptr _FreeListAllocAlign(FreeList *alloc, usize size, u32 alignment);
|
||||||
static rawptr FreeListAlloc(FLAlloc *alloc, usize size, u32 alignment);
|
static rawptr FreeListAllocAlign(FLAlloc *alloc, usize size, u32 alignment);
|
||||||
|
static rawptr FreeListAlloc(FLAlloc *alloc, usize size);
|
||||||
|
static void _FreeListFree(FreeList *alloc, rawptr ptr);
|
||||||
|
static void FreeListFree(FLAlloc *alloc, rawptr ptr);
|
||||||
|
static void FreeListFreeAll(FLAlloc *alloc);
|
||||||
|
static void FreeListGrow(FLAlloc *alloc, usize alloc_size);
|
||||||
|
static FLNode *FreeListSearch(FreeList *alloc, usize size, usize alignment, usize *out_padding, FLNode **prev_node);
|
||||||
|
static void FreeListCoalescence(FreeList *alloc, FLNode *prev_node, FLNode *free_node);
|
||||||
|
static void FreeListRemove(FLNode **head, FLNode *prev_node, FLNode *del_node);
|
||||||
|
static void FreeListInsert(FLNode **head, FLNode *prev_node, FLNode *new_node);
|
||||||
|
|||||||
@ -108,7 +108,7 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
WaitForWindowEvent(inputs);
|
WaitForWindowEvent(inputs);
|
||||||
|
|
||||||
GameContext ctx = {};
|
GameContext ctx = {0};
|
||||||
|
|
||||||
InitializeGame(renderer_arena, &ctx, game_arena);
|
InitializeGame(renderer_arena, &ctx, game_arena);
|
||||||
|
|
||||||
|
|||||||
@ -31,8 +31,8 @@ const FileMapping g_Texture_File_Map[] = {
|
|||||||
{ .file_name = "purplemon.png", .ix = PATTERMON_PURPLOID },
|
{ .file_name = "purplemon.png", .ix = PATTERMON_PURPLOID },
|
||||||
};
|
};
|
||||||
|
|
||||||
c8 *g_Shader_File_Names[SHADER_ASSET_MAX] = {};
|
c8 *g_Shader_File_Names[SHADER_ASSET_MAX] = {0};
|
||||||
c8 *g_Texture_File_Names[TEXTURE_ASSET_MAX] = {};
|
c8 *g_Texture_File_Names[TEXTURE_ASSET_MAX] = {0};
|
||||||
|
|
||||||
// ::Packer::Globals::End::
|
// ::Packer::Globals::End::
|
||||||
|
|
||||||
@ -380,7 +380,7 @@ int main(int argc, c8 **argv)
|
|||||||
FILE *file = fopen("assets.sgp", "w+");
|
FILE *file = fopen("assets.sgp", "w+");
|
||||||
Assert(file != NULL, "File is null");
|
Assert(file != NULL, "File is null");
|
||||||
|
|
||||||
FileHeader header = {};
|
FileHeader header = {0};
|
||||||
InitHeader(&header);
|
InitHeader(&header);
|
||||||
|
|
||||||
PackFiles(arena, &header);
|
PackFiles(arena, &header);
|
||||||
|
|||||||
@ -17,7 +17,7 @@ static Renderer renderer = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static u32 vk_thread_indices[10] = {};
|
static u32 vk_thread_indices[10] = {0};
|
||||||
|
|
||||||
#if __linux__
|
#if __linux__
|
||||||
pthread_cond_t cond;
|
pthread_cond_t cond;
|
||||||
|
|||||||
@ -209,8 +209,8 @@ static b32 UploadToBuffer(RenderBuffer **buffers, rawptr *ptrs, u32 count, u8 th
|
|||||||
VkDevice device = renderer.vk.device;
|
VkDevice device = renderer.vk.device;
|
||||||
VkQueue queue = renderer.vk.queues.transfer_queue;
|
VkQueue queue = renderer.vk.queues.transfer_queue;
|
||||||
VmaAllocator alloc = renderer.vk.alloc;
|
VmaAllocator alloc = renderer.vk.alloc;
|
||||||
rawptr mapped_buffers[16] = {};
|
rawptr mapped_buffers[16] = {0};
|
||||||
RenderBuffer staging_buffers[16] = {};
|
RenderBuffer staging_buffers[16] = {0};
|
||||||
|
|
||||||
u32 copy_count = 0;
|
u32 copy_count = 0;
|
||||||
|
|
||||||
|
|||||||
45
src/tests.c
45
src/tests.c
@ -1,5 +1,48 @@
|
|||||||
|
|
||||||
void RunTests()
|
void RunTests()
|
||||||
{
|
{
|
||||||
|
TestFreeListAlloc();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestFreeListAlloc()
|
||||||
|
{
|
||||||
|
FLAlloc alloc = {0};
|
||||||
|
usize alloc_size = KB(256);
|
||||||
|
FreeListInit(&alloc, alloc_size);
|
||||||
|
u8 *value = (u8 *)(uintptr(alloc.lists[0]->data) + uintptr(alloc_size-sizeof(FreeList)-2));
|
||||||
|
*value = 255;
|
||||||
|
Assert(*value == 255, "data set is invalid");
|
||||||
|
|
||||||
|
u32 u32_count = 2000;
|
||||||
|
u32 f64_count = 3000;
|
||||||
|
|
||||||
|
u32 *u32_arr = FreeListAlloc(&alloc, sizeof(u32) * u32_count);
|
||||||
|
f64 *f64_arr = FreeListAlloc(&alloc, sizeof(f64) * f64_count);
|
||||||
|
|
||||||
|
for (u32 i = 0; i < u32_count; i++)
|
||||||
|
{
|
||||||
|
u32_arr[i] = 3 * i;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (u32 i = 0; i < f64_count; i++)
|
||||||
|
{
|
||||||
|
f64_arr[i] = f64(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (u32 i = 0; i < u32_count; i++)
|
||||||
|
{
|
||||||
|
Assert(u32_arr[i] == 3 * i, "u32 memory incorrect");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (u32 i = 0; i < f64_count; i++)
|
||||||
|
{
|
||||||
|
Assert(f64_arr[i] == f64(i), "f64 memory incorrect");
|
||||||
|
}
|
||||||
|
|
||||||
|
FreeListFree(&alloc, u32_arr);
|
||||||
|
|
||||||
|
for (u32 i = 0; i < f64_count; i++)
|
||||||
|
{
|
||||||
|
Assert(f64_arr[i] == f64(i), "f64 memory incorrect post free");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
void RunTests();
|
void RunTests();
|
||||||
|
void TestFreeListAlloc();
|
||||||
|
|
||||||
|
|||||||
25
src/util.h
25
src/util.h
@ -24,6 +24,31 @@ typedef struct Arena Arena;
|
|||||||
#define Str8L(x) (Str8){ .len = StrLen(x), .value = (u8 *)x }
|
#define Str8L(x) (Str8){ .len = StrLen(x), .value = (u8 *)x }
|
||||||
#define MakeString(x) #x
|
#define MakeString(x) #x
|
||||||
|
|
||||||
|
#define i8(x) ((i8)(x))
|
||||||
|
#define i16(x) ((i16)(x))
|
||||||
|
#define i32(x) ((i32)(x))
|
||||||
|
#define i64(x) ((i64)(x))
|
||||||
|
|
||||||
|
#define u8(x) ((u8)(x))
|
||||||
|
#define u16(x) ((u16)(x))
|
||||||
|
#define u32(x) ((u32)(x))
|
||||||
|
#define u64(x) ((u64)(x))
|
||||||
|
|
||||||
|
#define c8(x) ((c8)(x))
|
||||||
|
#define c8ptr(x) ((c8 *)(x))
|
||||||
|
#define u8ptr(x) ((u8 *)(x))
|
||||||
|
#define i8ptr(x) ((i8 *)(x))
|
||||||
|
|
||||||
|
#define intptr(x) ((intptr)(x))
|
||||||
|
#define uintptr(x) ((uintptr)(x))
|
||||||
|
|
||||||
|
#define f32(x) ((f32)(x))
|
||||||
|
#define f64(x) ((f64)(x))
|
||||||
|
|
||||||
|
#define rawptr(x) ((rawptr)(x))
|
||||||
|
|
||||||
|
#define cast(T, x) ((T)(x))
|
||||||
|
|
||||||
// ::Util::Defines::Header::
|
// ::Util::Defines::Header::
|
||||||
|
|
||||||
#define HM_MAX_SYMBOLS 256
|
#define HM_MAX_SYMBOLS 256
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user