Skip to content

Commit

Permalink
Fix pool allocator (#190)
Browse files Browse the repository at this point in the history
* Add boost-pool dependency to vcpkg.json

This commit includes the boost-pool library with version 1.86.0 as a new dependency. It ensures required functionality is available for memory pooling. No other changes were made to the dependency list.

* Add Boost.Pool library to project dependencies

The Boost.Pool library has been included in the list of dependencies in CMakeLists.txt. This change ensures that the project can leverage memory pooling functionality provided by Boost.

* Refactor memory allocation to use Boost pool allocator.

Replaced standard polymorphic memory resource with Boost's `pool` for small object allocation. This improves alignment handling and simplifies the custom allocator logic while maintaining proper deallocation behavior. Removed obsolete commented-out code for clarity.
  • Loading branch information
inakleinbottle authored Dec 17, 2024
1 parent a742cec commit e7fd8e8
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 32 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ find_boost(VERSION 1.83 COMPONENTS
endian
interprocess
multiprecision
pool
smart_ptr
type_traits
url
Expand Down
111 changes: 79 additions & 32 deletions platform/src/alloc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
#include "roughpy/platform/alloc.h"

#include <new>
#include <memory_resource>

#include <boost/pool/singleton_pool.hpp>
#include <boost/align/aligned_alloc.hpp>
#include <roughpy/core/traits.h>

Expand All @@ -25,61 +25,108 @@ void rpy::mem::aligned_free(void* ptr, size_t size) noexcept
boost::alignment::aligned_free(ptr);
}

//
// namespace {
//
// class PageAlignedMemoryResource : public std::pmr::memory_resource
// {
//
// protected:
// void* do_allocate(size_t bytes, size_t alignment) override
// {
// ignore_unused(alignment);
// void* ptr = mem::aligned_alloc(small_chunk_size, bytes);
// if (!ptr) { throw std::bad_alloc(); }
// return ptr;
// }
//
// void do_deallocate(void* p, size_t bytes, size_t alignment) override
// {
// ignore_unused(alignment);
// return mem::aligned_free(p, bytes);
// }
//
// bool do_is_equal(const std::pmr::memory_resource& other
// ) const noexcept override
// {
// return this == &other;
// }
//
// public:
// static PageAlignedMemoryResource* get() noexcept
// {
// static PageAlignedMemoryResource instance;
// return &instance;
// }
// };
//
// std::pmr::synchronized_pool_resource* get_pool() noexcept
// {
// static std::pmr::synchronized_pool_resource pool (
// std::pmr::pool_options{ small_blocks_per_chunk, small_block_size },
// PageAlignedMemoryResource::get());
// return &pool;
// }
// }


namespace {

class PageAlignedMemoryResource : public std::pmr::memory_resource
{

protected:
void* do_allocate(size_t bytes, size_t alignment) override
{
ignore_unused(alignment);
void* ptr = mem::aligned_alloc(small_chunk_size, bytes);
if (!ptr) { throw std::bad_alloc(); }
return ptr;
}
struct MyAlignedAlloc
{
using size_type = size_t;
using difference_type = ptrdiff_t;

void do_deallocate(void* p, size_t bytes, size_t alignment) override
static char* malloc BOOST_PREVENT_MACRO_SUBSTITUTION(const size_type size) noexcept
{
ignore_unused(alignment);
return mem::aligned_free(p, bytes);
return static_cast<char*>(mem::aligned_alloc(small_chunk_size, size));
}

bool do_is_equal(const std::pmr::memory_resource& other
) const noexcept override
static void free BOOST_PREVENT_MACRO_SUBSTITUTION(char* const block) noexcept
{
return this == &other;
mem::aligned_free(block, small_chunk_size);
}

public:
static PageAlignedMemoryResource* get() noexcept
{
static PageAlignedMemoryResource instance;
return &instance;
}
};

std::pmr::synchronized_pool_resource* get_pool() noexcept
boost::pool<MyAlignedAlloc>* get_pool() noexcept
{
static std::pmr::synchronized_pool_resource pool (
std::pmr::pool_options{ small_blocks_per_chunk, small_block_size },
PageAlignedMemoryResource::get());
static boost::pool<MyAlignedAlloc> pool {small_block_size, small_blocks_per_chunk};
return &pool;
}


}


void* rpy::mem::small_object_alloc(size_t size)
{
return get_pool()->allocate(size);
static constexpr size_t max_alignment = alignof(std::max_align_t);
// return get_pool()->allocate(size);
if (size > small_block_size) {
return aligned_alloc(max_alignment, size);
}
return get_pool()->malloc();
}

void rpy::mem::small_object_free(void* ptr, size_t size)
{
get_pool()->deallocate(ptr, size);
if (size > small_block_size) {
aligned_free(ptr, size);
} else {
get_pool()->free(static_cast<char*>(ptr));
}

// get_pool()->deallocate(ptr, size);
}
void* SmallObjectBase::operator new(size_t size) {

void* SmallObjectBase::operator new(size_t size)
{
return small_object_alloc(size);
}
void SmallObjectBase::operator delete(void* object, size_t size) {

void SmallObjectBase::operator delete(void* object, size_t size)
{
small_object_free(object, size);
}
}
3 changes: 3 additions & 0 deletions vcpkg.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@
}, {
"name" : "fmt",
"version>=" : "11.0.2#1"
}, {
"name" : "boost-pool",
"version>=" : "1.86.0"
} ],
"features" : {
"tests" : {
Expand Down

0 comments on commit e7fd8e8

Please sign in to comment.