2023-04-01 19:21:46 -07:00
|
|
|
#define BLOAT_IMPL
|
2023-04-01 22:07:44 -07:00
|
|
|
#include "Bloat.hpp"
|
2023-04-01 19:21:46 -07:00
|
|
|
|
2023-04-03 23:04:19 -07:00
|
|
|
|
2023-04-01 19:21:46 -07:00
|
|
|
namespace Memory
|
|
|
|
{
|
2023-04-09 10:59:39 -07:00
|
|
|
using namespace zpl;
|
|
|
|
|
2023-07-09 09:35:48 -07:00
|
|
|
global AllocatorInfo GlobalAllocator;
|
2023-04-05 23:21:23 -07:00
|
|
|
|
2023-07-09 09:35:48 -07:00
|
|
|
global Array(Arena) Global_AllocatorBuckets;
|
|
|
|
|
|
|
|
void* Global_Allocator_Proc( void* allocator_data, AllocType type, sw size, sw alignment, void* old_memory, sw old_size, u64 flags )
|
2023-04-01 19:21:46 -07:00
|
|
|
{
|
2023-07-09 09:35:48 -07:00
|
|
|
Arena* last = & array_back( Global_AllocatorBuckets );
|
2023-04-01 19:21:46 -07:00
|
|
|
|
2023-07-09 09:35:48 -07:00
|
|
|
switch ( type )
|
2023-04-01 19:21:46 -07:00
|
|
|
{
|
2023-07-09 09:35:48 -07:00
|
|
|
case EAllocationALLOC:
|
|
|
|
{
|
|
|
|
if ( last->total_allocated + size > last->total_size )
|
|
|
|
{
|
|
|
|
Arena bucket;
|
|
|
|
arena_init_from_allocator( & bucket, heap(), BucketSize );
|
|
|
|
|
|
|
|
if ( bucket.physical_start == nullptr )
|
|
|
|
fatal( "Failed to create bucket for Global_AllocatorBuckets");
|
|
|
|
|
|
|
|
if ( ! array_append( Global_AllocatorBuckets, bucket ) )
|
|
|
|
fatal( "Failed to append bucket to Global_AllocatorBuckets");
|
|
|
|
|
|
|
|
last = & array_back( Global_AllocatorBuckets );
|
|
|
|
}
|
|
|
|
|
|
|
|
return alloc_align( arena_allocator( last), size, alignment );
|
|
|
|
}
|
|
|
|
case EAllocationFREE:
|
|
|
|
{
|
|
|
|
// Doesn't recycle.
|
|
|
|
}
|
|
|
|
case EAllocationFREE_ALL:
|
|
|
|
{
|
|
|
|
// Memory::cleanup instead.
|
|
|
|
}
|
|
|
|
case EAllocationRESIZE:
|
|
|
|
{
|
|
|
|
if ( last->total_allocated + size > last->total_size )
|
|
|
|
{
|
|
|
|
Arena bucket;
|
|
|
|
arena_init_from_allocator( & bucket, heap(), BucketSize );
|
|
|
|
|
|
|
|
if ( bucket.physical_start == nullptr )
|
|
|
|
fatal( "Failed to create bucket for Global_AllocatorBuckets");
|
|
|
|
|
|
|
|
if ( ! array_append( Global_AllocatorBuckets, bucket ) )
|
|
|
|
fatal( "Failed to append bucket to Global_AllocatorBuckets");
|
|
|
|
|
|
|
|
last = & array_back( Global_AllocatorBuckets );
|
|
|
|
}
|
|
|
|
|
|
|
|
void* result = alloc_align( arena_allocator( last), size, alignment );
|
|
|
|
|
|
|
|
if ( result != nullptr && old_memory != nullptr )
|
|
|
|
{
|
|
|
|
mem_copy( result, old_memory, size );
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
2023-04-01 19:21:46 -07:00
|
|
|
}
|
2023-07-09 09:35:48 -07:00
|
|
|
|
|
|
|
return nullptr;
|
2023-04-01 19:21:46 -07:00
|
|
|
}
|
2023-04-05 23:21:23 -07:00
|
|
|
|
2023-07-09 09:35:48 -07:00
|
|
|
void setup()
|
2023-04-01 19:21:46 -07:00
|
|
|
{
|
2023-07-09 09:35:48 -07:00
|
|
|
GlobalAllocator = AllocatorInfo { & Global_Allocator_Proc, nullptr };
|
2023-04-05 23:21:23 -07:00
|
|
|
|
2023-07-09 09:35:48 -07:00
|
|
|
if ( ! array_init_reserve( Global_AllocatorBuckets, heap(), 128 ) )
|
|
|
|
fatal( "Failed to reserve memory for Global_AllocatorBuckets");
|
2023-04-05 23:21:23 -07:00
|
|
|
|
2023-07-09 09:35:48 -07:00
|
|
|
Arena bucket;
|
|
|
|
arena_init_from_allocator( & bucket, heap(), BucketSize );
|
|
|
|
|
|
|
|
if ( bucket.physical_start == nullptr )
|
|
|
|
fatal( "Failed to create first bucket for Global_AllocatorBuckets");
|
|
|
|
|
|
|
|
array_append( Global_AllocatorBuckets, bucket );
|
2023-04-01 19:21:46 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void cleanup()
|
|
|
|
{
|
2023-07-09 09:35:48 -07:00
|
|
|
s32 index = 0;
|
|
|
|
s32 left = array_count( Global_AllocatorBuckets );
|
|
|
|
do
|
|
|
|
{
|
|
|
|
Arena* bucket = & Global_AllocatorBuckets[ index ];
|
|
|
|
arena_free( bucket );
|
|
|
|
index++;
|
|
|
|
}
|
|
|
|
while ( left--, left );
|
|
|
|
|
|
|
|
array_free( Global_AllocatorBuckets );
|
2023-04-05 23:21:23 -07:00
|
|
|
}
|
2023-04-01 19:21:46 -07:00
|
|
|
}
|