|
|
#include "alloc.h"
#include "string.h"
#include "print.h"
#include "types.h"
#if false
static void* leakcheckMalloc(size_t size, const char* file, s32 line) { ULE_TYPES_H_FTAG; return malloc(size); }
static void* leakcheckCalloc(size_t maxNumOfElements, size_t elementSize, const char* file, s32 line) { ULE_TYPES_H_FTAG; return calloc(maxNumOfElements, elementSize); }
static void* leakcheckRealloc(void* buffer, size_t newSize, const char* file, s32 line) { ULE_TYPES_H_FTAG; return realloc(buffer, newSize); }
static void leakcheckFree(void* ptr, const char* file, s32 line) { ULE_TYPES_H_FTAG; free(ptr); }
#define malloc(size) leakcheckMalloc(size, __FILE__, __LINE__)
#define calloc(numElements, size) leakcheckCalloc(numElements, size, __FILE__, __LINE__)
#define realloc(buffer, newSize) leakcheckRealloc(buffer, newSize, __FILE__, __LINE__)
#define free(ptr) leakcheckFree(ptr, __FILE__, __LINE__)
static void dumpLeaks() { void* address; size_t size; const char* file; s32 line; for (;;) { println("%p - %lu, %s:%d", address, size, file, line); } }
#endif
// system allocators
void* pMalloc(size_t size) { ULE_TYPES_H_FTAG; void* p = malloc(size);
if (!p) { die("Out of memory!n\nfailed to malloc %p with size %u\n", p, size); }
return p; } void* pMalloc(size_t size, void* allocatorState) { ULE_TYPES_H_FTAG; return pMalloc(size); }
void* pCalloc(size_t maxNumOfElements, size_t elementSize) { ULE_TYPES_H_FTAG; void* p = calloc(maxNumOfElements, elementSize);
if (!p) { die("Out of memory!\nfailed to calloc %p with %u elements of size %u\n", p, maxNumOfElements, elementSize); }
return p; } void* pCalloc(size_t maxNumOfElements, size_t elementSize, void* allocatorState) { ULE_TYPES_H_FTAG; return pCalloc(maxNumOfElements, elementSize); }
void* pRealloc(void* buffer, size_t newSize) { ULE_TYPES_H_FTAG; void* p = realloc(buffer, newSize);
if (!p) { //pFree(buffer); // if we ever *don't* terminate the program at this point, we should free |buffer|
die("Out of memory!\nfailed to realloc %p with size: %u\n", buffer, newSize); }
return p; } void* pRealloc(void* buffer, size_t newSize, void* allocatorState) { ULE_TYPES_H_FTAG; return pRealloc(buffer, newSize); }
void pFree(void* ptr) { ULE_TYPES_H_FTAG; free(ptr); } void pFree(void* ptr, void* allocatorState) { ULE_TYPES_H_FTAG; pFree(ptr); }
void pFree(const void* ptr) { ULE_TYPES_H_FTAG; pFree((void*) ptr); } void pFree(const void* ptr, void* allocatorState) { ULE_TYPES_H_FTAG; pFree((void*) ptr, allocatorState); }
#ifdef malloc
#undef malloc
#endif
#ifdef calloc
#undef calloc
#endif
#ifdef realloc
#undef realloc
#endif
#ifdef free
#undef free
#endif
static bool DefaultAllocatorInited = false; static Allocator DefaultAllocator; static void defaultAllocatorInit() { ULE_TYPES_H_FTAG; DefaultAllocator.state = null; DefaultAllocator.mallocate = pMalloc; DefaultAllocator.callocate = pCalloc; DefaultAllocator.reallocate = pRealloc; DefaultAllocator.free = pFree; DefaultAllocatorInited = true; }
Allocator* Allocator::GetDefault() { ULE_TYPES_H_FTAG; if (!DefaultAllocatorInited) defaultAllocatorInit(); return &DefaultAllocator; }
//================================================================================
// alignment should be a power of 2
static u64 alignForward2(u64 ptr, size_t alignment) { ULE_TYPES_H_FTAG; u64 p, a, modulo;
p = ptr; a = alignment; modulo = p & (a - 1);
if (modulo != 0) { p += a - modulo; }
return p; } static u64 alignForward(u64 ptr, size_t alignment) { ULE_TYPES_H_FTAG; return ((ptr + alignment - 1) / alignment) * alignment; }
//================================================================================
// Scratch/Arena
Arena* Arena::Init(u32 sizeInBytes) { ULE_TYPES_H_FTAG; Arena* arena = (Arena*) pMalloc(sizeof(Arena)); arena->index = 0; arena->buffer = (u8*) pMalloc(sizeof(u8) * sizeInBytes); arena->bufferSizeInBytes = sizeInBytes; return arena; } void* Arena::Alloc(u32 sizeInBytes) { ULE_TYPES_H_FTAG; u8* p = this->buffer + this->index; u32 offset = (u32) alignForward2((u64) p, 64);
if ((void*)(offset + sizeInBytes) <= (this->buffer + this->bufferSizeInBytes)) { void* ptr = &this->buffer[offset]; this->index += offset + sizeInBytes;
String::memset(ptr, 0, sizeInBytes);
return ptr; }
return null; } void Arena::Clear() { ULE_TYPES_H_FTAG; this->index = 0; } //================================================================================
struct StackAllocator { u32 bufferSize; u32 index; u8* buffer; };
struct PoolAllocator { u8* buffer; };
|