Skip to content

Commit

Permalink
Use Open() and Create().
Browse files Browse the repository at this point in the history
  • Loading branch information
ehpor committed Dec 20, 2024
1 parent a0cfe0b commit 820b565
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 28 deletions.
23 changes: 9 additions & 14 deletions benchmarks/free_list_allocator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@

void benchmark_linux_scalability()
{
typedef FreeListAllocator Allocator;

const size_t N = 10000000;

const size_t NUM_BLOCKS = N * 2;
Expand All @@ -16,19 +14,18 @@ void benchmark_linux_scalability()
size_t buffer_size = FreeListAllocator::ComputeMetadataBufferSize(NUM_BLOCKS);
char *buffer = new char[buffer_size];

FreeListAllocator allocator(buffer);
allocator.Initialize(NUM_BLOCKS, ALIGNMENT, NUM_BLOCKS * ALIGNMENT);
auto allocator = FreeListAllocator::Create(buffer, NUM_BLOCKS, ALIGNMENT, NUM_BLOCKS * ALIGNMENT);

auto start = GetTimeStamp();

for (size_t i = 0; i < N; ++i)
{
handles[i] = allocator.Allocate(16);
handles[i] = allocator->Allocate(16);
}

for (size_t i = 0; i < N; ++i)
{
allocator.Deallocate(handles[i]);
allocator->Deallocate(handles[i]);
}

auto end = GetTimeStamp();
Expand All @@ -54,21 +51,20 @@ void benchmark_threadtest()
size_t buffer_size = FreeListAllocator::ComputeMetadataBufferSize(NUM_BLOCKS);
char *buffer = new char[buffer_size];

FreeListAllocator allocator(buffer);
allocator.Initialize(NUM_BLOCKS, ALIGNMENT, NUM_BLOCKS * ALIGNMENT);
auto allocator = FreeListAllocator::Create(buffer, NUM_BLOCKS, ALIGNMENT, NUM_BLOCKS * ALIGNMENT);

auto start = GetTimeStamp();

for (size_t i = 0; i < M; ++i)
{
for (size_t j = 0; j < N; ++j)
{
handles[j] = allocator.Allocate(16);
handles[j] = allocator->Allocate(16);
}

for (size_t j = 0; j < N; ++j)
{
allocator.Deallocate(handles[j]);
allocator->Deallocate(handles[j]);
}
}

Expand Down Expand Up @@ -101,8 +97,7 @@ void benchmark_larson()
size_t buffer_size = FreeListAllocator::ComputeMetadataBufferSize(NUM_BLOCKS);
char *buffer = new char[buffer_size];

FreeListAllocator allocator(buffer);
allocator.Initialize(NUM_BLOCKS, ALIGNMENT, MAX_SIZE * NUM_BLOCKS);
auto allocator = FreeListAllocator::Create(buffer, NUM_BLOCKS, ALIGNMENT, MAX_SIZE * NUM_BLOCKS);

auto *indices = new size_t[N];
auto *sizes = new size_t[N];
Expand All @@ -121,10 +116,10 @@ void benchmark_larson()

if (handles[index] != -1)
{
allocator.Deallocate(handles[index]);
allocator->Deallocate(handles[index]);
}

handles[index] = allocator.Allocate(size);
handles[index] = allocator->Allocate(size);
}

auto end = GetTimeStamp();
Expand Down
33 changes: 22 additions & 11 deletions catkit_core/FreeListAllocator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,24 +76,35 @@ std::size_t FreeListAllocator::ComputeMetadataBufferSize(std::size_t max_num_blo
return size;
}

void FreeListAllocator::Initialize(std::size_t max_num_blocks, std::size_t alignment, std::size_t buffer_size)
std::shared_ptr<FreeListAllocator> FreeListAllocator::Open(void *metadata_buffer)
{
std::copy(VERSION, VERSION + sizeof(VERSION), m_Header.version);
m_Header.max_num_blocks = max_num_blocks;
m_Header.alignment = alignment;
m_Header.total_buffer_size = buffer_size;
return std::shared_ptr<FreeListAllocator>(new FreeListAllocator(metadata_buffer));
}

std::shared_ptr<FreeListAllocator> FreeListAllocator::Create(void *metadata_buffer, std::size_t max_num_blocks, std::size_t alignment, std::size_t buffer_size)
{
auto allocator = std::shared_ptr<FreeListAllocator>(new FreeListAllocator(metadata_buffer));

auto &header = allocator->m_Header;

std::copy(VERSION, VERSION + sizeof(VERSION), header.version);
header.max_num_blocks = max_num_blocks;
header.alignment = alignment;
header.total_buffer_size = buffer_size;

// Initialize the internal allocator.
m_BlockAllocator.Initialize(max_num_blocks);
allocator->m_BlockAllocator.Initialize(max_num_blocks);

// Initialize the free list.
m_Head = m_BlockAllocator.Allocate();
allocator->m_Head = allocator->m_BlockAllocator.Allocate();

std::size_t block_list_offset = sizeof(Header) + PoolAllocator::CalculateMetadataBufferSize(m_MaxNumBlocks);
m_Blocks = reinterpret_cast<Block *>(static_cast<char *>(m_MetadataBuffer) + block_list_offset);
std::size_t block_list_offset = sizeof(Header) + PoolAllocator::CalculateMetadataBufferSize(max_num_blocks);
allocator->m_Blocks = reinterpret_cast<Block *>(static_cast<char *>(metadata_buffer) + block_list_offset);

allocator->m_Blocks[allocator->m_Head].descriptor = BlockDescriptor(0, buffer_size, true);
allocator->m_Blocks[allocator->m_Head].next = INVALID_HANDLE;

m_Blocks[m_Head].descriptor = BlockDescriptor(0, buffer_size, true);
m_Blocks[m_Head].next = INVALID_HANDLE;
return allocator;
}

typename FreeListAllocator::BlockHandle FreeListAllocator::Allocate(std::size_t size)
Expand Down
9 changes: 6 additions & 3 deletions catkit_core/FreeListAllocator.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,25 @@

#include <atomic>
#include <cstdint>
#include <memory>

// A simple lock-free free list allocator.
class FreeListAllocator
{
private:
FreeListAllocator(void *metadata_buffer);

public:
using BlockHandle = PoolAllocator::BlockHandle;
using Offset = std::uint32_t;
using Size = std::uint32_t;

static const BlockHandle INVALID_HANDLE = PoolAllocator::INVALID_HANDLE;

FreeListAllocator(void *metadata_buffer);

static std::size_t ComputeMetadataBufferSize(std::size_t max_num_blocks);

void Initialize(std::size_t max_num_blocks, std::size_t alignment, std::size_t buffer_size);
static std::shared_ptr<FreeListAllocator> Create(void *metadata_buffer, std::size_t max_num_blocks, std::size_t alignment, std::size_t buffer_size);
static std::shared_ptr<FreeListAllocator> Open(void *metadata_buffer);

BlockHandle Allocate(std::size_t size);
void Deallocate(BlockHandle index);
Expand Down

0 comments on commit 820b565

Please sign in to comment.