Program Listing for File ConcurrentPool.h
↰ Return to documentation for file (ADS/memory/ConcurrentPool.h)
/*--------------------------------------------------------------------------*/
/*------------------------- File ConcurrentPool.h --------------------------*/
/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
/*----------------------------- DEFINITIONS --------------------------------*/
/*--------------------------------------------------------------------------*/
#ifndef __ADS_ConcurrentPool
#define __ADS_ConcurrentPool
/* self-identification: #endif constant */
/*--------------------------------------------------------------------------*/
/*------------------------------ INCLUDES ----------------------------------*/
/*--------------------------------------------------------------------------*/
#include "ADS/Contract.h"
#include "ADS/memory/PageHeap.h"
#include "ADS/memory/PoolAllocator.h"
#include <atomic>
#include <cstddef>
#include <cstdint>
#include <new>
#include <thread>
#include <vector>
/*--------------------------------------------------------------------------*/
/*--------------------------- NAMESPACE ------------------------------------*/
/*--------------------------------------------------------------------------*/
namespace ADS {
/*--------------------------------------------------------------------------*/
/*---------------------- CLASS ConcurrentPoolResource ----------------------*/
/*--------------------------------------------------------------------------*/
template< std::size_t M = 256 >
class ConcurrentPoolResource {
static_assert( ( M >= 16 ) && ( M % 16 == 0 ) && ( M <= 4096 ) ,
"the largest class is a multiple of 16 bytes, up to 4096" );
/*--------------------------------------------------------------------------*/
public:
static constexpr std::size_t GRAIN = 8;
static constexpr std::size_t ALIGN = 16;
static constexpr std::size_t MAX = M;
static constexpr std::size_t CLASSES = M / GRAIN;
static constexpr std::size_t SEGMENT = detail::PageHeap< CLASSES >::SEGMENT;
[[nodiscard]] static constexpr bool pooled( std::size_t b ,
std::size_t a ) {
return( ( b >= 1 ) && ( b <= M ) && ( a <= ALIGN ) );
}
ConcurrentPoolResource( void );
ConcurrentPoolResource( const ConcurrentPoolResource & ) = delete;
ConcurrentPoolResource & operator=( const ConcurrentPoolResource & ) =
delete;
~ConcurrentPoolResource();
[[nodiscard]] static ConcurrentPoolResource & global( void );
template< std::size_t b , std::size_t a = alignof( std::max_align_t ) >
[[nodiscard]] void * allocate( void );
template< std::size_t b , std::size_t a = alignof( std::max_align_t ) >
void deallocate( void * p );
[[nodiscard]] void * allocate( std::size_t b ,
std::size_t a = alignof( std::max_align_t )
);
void deallocate( void * p , std::size_t b ,
std::size_t a = alignof( std::max_align_t ) );
void collect( void );
[[nodiscard]] std::size_t heaps( void ) const;
[[nodiscard]] std::size_t bytes( void ) const;
/*--------------------------------------------------------------------------*/
private:
using Pages = detail::PageHeap< CLASSES >;
using Free = typename Pages::Free;
using Page = typename Pages::Page;
struct alignas( 64 ) Returns {
std::atomic< Free * > top{ nullptr };
};
struct Heap;
struct Batch {
Heap * to = nullptr;
Free * head = nullptr;
Free * tail = nullptr;
std::uint32_t n = 0;
};
static constexpr std::uint32_t BATCH = 32;
struct Heap {
std::thread::id id;
Heap * link = nullptr;
Pages pages{ this };
Batch out[ CLASSES ];
Returns returns[ CLASSES ];
};
static void send( Batch & b , std::size_t c );
[[nodiscard]] static constexpr std::size_t classOf( std::size_t b ,
std::size_t a ) {
return( ( a > GRAIN ? ( b + 15 ) / 16 * 2 : ( b + 7 ) / 8 ) - 1 );
}
struct Cache {
std::uint64_t id = 0;
Heap * heap = nullptr;
};
[[nodiscard]] Heap * mine( void );
Heap * find( void );
[[nodiscard]] void * take( std::size_t c );
void * refill( Heap & h , std::size_t c );
void give( void * p , std::size_t c );
inline static thread_local Cache s_cache;
inline static std::atomic< std::uint64_t > s_ids{ 0 };
const std::uint64_t f_id;
std::atomic< Heap * > f_heaps{ nullptr };
}; // end( class ConcurrentPoolResource )
/*--------------------------------------------------------------------------*/
} // end( namespace ADS )
/*--------------------------------------------------------------------------*/
/*-------------------------- IMPLEMENTATION --------------------------------*/
/*--------------------------------------------------------------------------*/
#include "ADS/memory/impl/ConcurrentPool.tpp"
/*--------------------------------------------------------------------------*/
#endif /* ConcurrentPool.h included */
/*--------------------------------------------------------------------------*/
/*----------------------- End File ConcurrentPool.h ------------------------*/
/*--------------------------------------------------------------------------*/