mirror of
https://github.com/krgamestudios/Toy.git
synced 2026-04-15 23:04:08 +10:00
Added custom allocator support
This commit is contained in:
@@ -5,7 +5,8 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
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) {
|
if (newSize == 0 && oldSize == 0) {
|
||||||
//causes issues, so just skip out with a NO-OP
|
//causes issues, so just skip out with a NO-OP
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -20,10 +21,30 @@ void* reallocate(void* pointer, size_t oldSize, size_t newSize) {
|
|||||||
void* mem = realloc(pointer, newSize);
|
void* mem = realloc(pointer, newSize);
|
||||||
|
|
||||||
if (mem == NULL) {
|
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);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return mem;
|
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);
|
||||||
|
}
|
||||||
@@ -10,5 +10,8 @@
|
|||||||
#define SHRINK_ARRAY(type, pointer, oldCount, count) (type*)reallocate((type*)pointer, sizeof(type) * (oldCount), sizeof(type) * (count))
|
#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)
|
#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);
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
#define TOY_VERSION_MAJOR 0
|
#define TOY_VERSION_MAJOR 0
|
||||||
#define TOY_VERSION_MINOR 6
|
#define TOY_VERSION_MINOR 6
|
||||||
#define TOY_VERSION_PATCH 2
|
#define TOY_VERSION_PATCH 3
|
||||||
#define TOY_VERSION_BUILD __DATE__ " " __TIME__
|
#define TOY_VERSION_BUILD __DATE__ " " __TIME__
|
||||||
|
|
||||||
//platform exports/imports
|
//platform exports/imports
|
||||||
|
|||||||
@@ -3,32 +3,74 @@
|
|||||||
#include "console_colors.h"
|
#include "console_colors.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
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
|
//test single pointer
|
||||||
int* integer = ALLOCATE(int, 1);
|
int* integer = ALLOCATE(int, 1);
|
||||||
|
|
||||||
FREE(int, integer);
|
FREE(int, integer);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
//test single pointer
|
//test single pointer array
|
||||||
int* array = ALLOCATE(int, 10);
|
int* array = ALLOCATE(int, 10);
|
||||||
|
|
||||||
|
array[1] = 42; //access the given memory
|
||||||
|
|
||||||
FREE_ARRAY(int, array, 10);
|
FREE_ARRAY(int, array, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
//test single pointer
|
//test multiple pointer arrays
|
||||||
int* array1 = ALLOCATE(int, 10);
|
int* array1 = ALLOCATE(int, 10);
|
||||||
int* array2 = 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, array1, 10);
|
||||||
FREE_ARRAY(int, array2, 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);
|
printf(NOTICE "All good\n" RESET);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user