bubel-ecs/source/ecs/block_allocator.d
2019-10-10 22:14:18 +02:00

73 lines
1.9 KiB
D

module ecs.block_allocator;
import ecs.manager;
import ecs.std;
struct BlockAllocator
{
private uint block_size;
private uint blocks_in_allocation;
struct BlockPointers
{
void*[32] blocks;
uint numberof = 0;
BlockPointers* next_pointers = null;
}
void* next_block = null;
BlockPointers* pointers = null;
void* getBlock() nothrow @nogc
{
if (next_block is null)
allocBlock();
void* ret = next_block;
next_block = *cast(void**) next_block;
return ret;
}
void freeBlock(void* block) nothrow @nogc
{
*cast(void**)block = next_block;
next_block = block;
}
private void allocBlock() nothrow @nogc
{
next_block = cast(void*) Mallocator.alignAlloc(
block_size * blocks_in_allocation, block_size);
if(pointers is null)pointers = Mallocator.make!BlockPointers;
if(pointers.numberof >= 32)
{
BlockPointers* new_pointers = Mallocator.make!BlockPointers;
new_pointers.next_pointers = pointers;
pointers = new_pointers;
}
pointers.blocks[pointers.numberof++] = next_block;
foreach (i; 0 .. blocks_in_allocation - 1)
{
void** pointer = cast(void**)(next_block + i * block_size);
*pointer = next_block + (i + 1) * block_size;
}
void** pointer = cast(void**)(
next_block + (blocks_in_allocation - 1) * block_size);
*pointer = null;
}
void freeMemory() nothrow @nogc
{
while(pointers)
{
foreach(i;0..pointers.numberof)
{
Mallocator.alignDispose(pointers.blocks[i]);
}
BlockPointers* next_pointers = pointers.next_pointers;
Mallocator.dispose(pointers);
pointers = next_pointers;
}
}
}