91 lines
1.6 KiB
C++
91 lines
1.6 KiB
C++
#define NO_GLOBAL_ARENA_ALLOCATOR
|
|
|
|
struct MemoryArena {
|
|
|
|
u8* data;
|
|
u64 size = 0;
|
|
u64 capacity = 0;
|
|
String name = "unnamed";
|
|
|
|
MemoryArena(u64 cap, String _name = "unnamed")
|
|
{
|
|
name = _name;
|
|
capacity = cap;
|
|
printf("(i) memory arena '%s' created with capacity of %llu bytes\n", name.c_str(), capacity);
|
|
data = (u8*)malloc(cap);
|
|
}
|
|
|
|
~MemoryArena()
|
|
{
|
|
free(data);
|
|
}
|
|
|
|
void clear()
|
|
{
|
|
#ifdef DEBUG_MEMORY
|
|
printf("(i) memory arena '%s' cleared after high mark of %llu bytes\n", name.c_str(), size);
|
|
#endif
|
|
size = 0;
|
|
}
|
|
|
|
void* get(u64 size_needed)
|
|
{
|
|
u64 size_aligned = 8 + (8 * ((size_needed) / 8));
|
|
u8* result = data + size;
|
|
if(size_aligned + size >= capacity)
|
|
{
|
|
printf("(!) memory arena '%s' capacity (%llu) exceeded %llu/%llu + %llu >= %llu\n",
|
|
name.c_str(), capacity, size_needed, size_aligned, size, capacity);
|
|
return(0);
|
|
}
|
|
size += size_aligned;
|
|
#ifdef DEBUG_MEMORY_DETAILED
|
|
printf("(i) memory arena '%s' [+%llu]:%p alloc %llu/%llu bytes\n", name.c_str(), size, result, size_needed, size_aligned);
|
|
#endif
|
|
return(result);
|
|
}
|
|
|
|
};
|
|
|
|
MemoryArena* current_memory_arena = 0;
|
|
|
|
void switch_to_system_alloc()
|
|
{
|
|
#ifdef GLOBAL_ARENA_ALLOCATOR
|
|
current_memory_arena = 0;
|
|
#endif
|
|
}
|
|
|
|
void switch_to_arena(MemoryArena* a)
|
|
{
|
|
#ifdef GLOBAL_ARENA_ALLOCATOR
|
|
current_memory_arena = a;
|
|
#endif
|
|
}
|
|
|
|
#ifdef GLOBAL_ARENA_ALLOCATOR
|
|
void * operator new(decltype(sizeof(0)) n) noexcept(false)
|
|
{
|
|
if(current_memory_arena)
|
|
{
|
|
return(current_memory_arena->get(n));
|
|
}
|
|
else
|
|
{
|
|
return(malloc(n));
|
|
}
|
|
}
|
|
|
|
void operator delete(void * p) throw()
|
|
{
|
|
if(current_memory_arena)
|
|
{
|
|
|
|
}
|
|
else
|
|
{
|
|
free(p);
|
|
}
|
|
}
|
|
#endif
|