From 4518b5941720dac75a16d9e571cb489a0d38deed Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Sat, 19 Nov 2022 08:18:45 +0000 Subject: [PATCH] Added custom allocator support --- source/memory.c | 25 ++++++++++++++++++++-- source/memory.h | 5 ++++- source/toy_common.h | 2 +- test/test_memory.c | 52 ++++++++++++++++++++++++++++++++++++++++----- 4 files changed, 75 insertions(+), 9 deletions(-) diff --git a/source/memory.c b/source/memory.c index 0a444da..feab031 100644 --- a/source/memory.c +++ b/source/memory.c @@ -5,7 +5,8 @@ #include #include -void* reallocate(void* pointer, size_t oldSize, size_t newSize) { +//default allocator +void* defaultAllocator(void* pointer, size_t oldSize, size_t newSize) { if (newSize == 0 && oldSize == 0) { //causes issues, so just skip out with a NO-OP return NULL; @@ -20,10 +21,30 @@ void* reallocate(void* pointer, size_t oldSize, size_t newSize) { void* mem = realloc(pointer, newSize); if (mem == NULL) { - fprintf(stderr, ERROR "[internal]Memory allocation error (requested %d for %ld, replacing %d)\n" ERROR, (int)newSize, (long int)pointer, (int)oldSize); + fprintf(stderr, ERROR "[internal] Memory allocation error (requested %d for %ld, replacing %d)\n" RESET, (int)newSize, (long int)pointer, (int)oldSize); exit(-1); } return mem; } +//exposed API +static AllocatorFn allocator = defaultAllocator; + +void setAllocator(AllocatorFn fn) { + if (fn == NULL) { + fprintf(stderr, ERROR "[internal] Memory allocator error (can't be null)\n" RESET); + exit(-1); + } + + if (fn == reallocate) { + fprintf(stderr, ERROR "[internal] Memory allocator error (can't loop the reallocate function)\n" RESET); + exit(-1); + } + + allocator = fn; +} + +void* reallocate(void* pointer, size_t oldSize, size_t newSize) { + return allocator(pointer, oldSize, newSize); +} \ No newline at end of file diff --git a/source/memory.h b/source/memory.h index c0d1aae..1dcabae 100644 --- a/source/memory.h +++ b/source/memory.h @@ -10,5 +10,8 @@ #define SHRINK_ARRAY(type, pointer, oldCount, count) (type*)reallocate((type*)pointer, sizeof(type) * (oldCount), sizeof(type) * (count)) #define FREE_ARRAY(type, pointer, oldCount) reallocate((type*)pointer, sizeof(type) * (oldCount), 0) -void* reallocate(void* pointer, size_t oldSize, size_t newSize); +//implementation details +typedef void* (*AllocatorFn)(void* pointer, size_t oldSize, size_t newSize); +void setAllocator(AllocatorFn); +void* reallocate(void* pointer, size_t oldSize, size_t newSize); diff --git a/source/toy_common.h b/source/toy_common.h index 71369ac..0adba45 100644 --- a/source/toy_common.h +++ b/source/toy_common.h @@ -6,7 +6,7 @@ #define TOY_VERSION_MAJOR 0 #define TOY_VERSION_MINOR 6 -#define TOY_VERSION_PATCH 2 +#define TOY_VERSION_PATCH 3 #define TOY_VERSION_BUILD __DATE__ " " __TIME__ //platform exports/imports diff --git a/test/test_memory.c b/test/test_memory.c index 9c23174..bb1f15f 100644 --- a/test/test_memory.c +++ b/test/test_memory.c @@ -3,32 +3,74 @@ #include "console_colors.h" #include +#include -int main() { +//the test allocator +static int callCount = 0; + +void* allocator(void* pointer, size_t oldSize, size_t newSize) { + callCount++; + + if (newSize == 0 && oldSize == 0) { + return NULL; + } + + if (newSize == 0) { + free(pointer); + return NULL; + } + + void* mem = realloc(pointer, newSize); + + if (mem == NULL) { + exit(-1); + } + + return mem; +} + +void testMemoryAllocation() { { //test single pointer int* integer = ALLOCATE(int, 1); - FREE(int, integer); } { - //test single pointer + //test single pointer array int* array = ALLOCATE(int, 10); + array[1] = 42; //access the given memory + FREE_ARRAY(int, array, 10); } { - //test single pointer + //test multiple pointer arrays int* array1 = ALLOCATE(int, 10); int* array2 = ALLOCATE(int, 10); + array1[1] = 42; //access the given memory + array2[1] = 42; //access the given memory + FREE_ARRAY(int, array1, 10); FREE_ARRAY(int, array2, 10); } +} + +int main() { + //test the default allocator + testMemoryAllocation(); + + //test the custom allocator + setAllocator(allocator); + testMemoryAllocation(); + + if (callCount != 8) { + fprintf(stderr, ERROR "Unexpected call count for custom allocator; was called %d times" RESET, callCount); + return -1; + } printf(NOTICE "All good\n" RESET); return 0; } -