Tervel  1.0.0
A collection of wait-free containers and algorithms.
Public Member Functions | Private Member Functions | Private Attributes | List of all members
tervel::util::memory::rc::DescriptorPool Class Reference

Defines a pool of descriptor objects which is used to allocate descriptors and to store them while they are not safe to delete. More...

#include <descriptor_pool.h>

Public Member Functions

 DescriptorPool (PoolManager *manager, uint64_t pool_id, int prefill=TERVEL_MEM_RC_MIN_NODES)
 
 ~DescriptorPool ()
 
void reserve (size_t num_descriptors=TERVEL_MEM_RC_MIN_NODES)
 Allocates an extra num_descriptors elements to the pool. More...
 
template<typename DescrType , typename... Args >
DescrType * get_descriptor (Args &&...args)
 Constructs and returns a descriptor. More...
 
void free_descriptor (tervel::util::Descriptor *descr, bool dont_check=false)
 Once a user is done with a descriptor, they should free it with this method. More...
 

Private Member Functions

PoolElementget_from_pool (bool allocate_new=true)
 Gets a free element. More...
 
void send_safe_to_manager ()
 Sends the elements from the safe pool to the corresponding safe pool in this pool's manager. More...
 
void send_unsafe_to_manager ()
 Sends the elements from the unsafe pool to the corresponding unsafe pool in this pool's manager. More...
 
void offload ()
 Sends a subset of the elements to the managers pool. More...
 
void add_to_safe (tervel::util::Descriptor *descr)
 Releases the descriptor back to the safe pool. More...
 
void add_to_unsafe (tervel::util::Descriptor *descr)
 Releases the descriptor back to the unsafe pool. More...
 
void try_clear_unsafe_pool (bool dont_check=false)
 Try to move elements from the unsafe pool to the safe pool. More...
 
bool verify_pool_count (PoolElement *pool, uint64_t count)
 verifies that the length of the linked list matches the count More...
 
 DISALLOW_COPY_AND_ASSIGN (DescriptorPool)
 

Private Attributes

PoolManagermanager_
 This pool's manager. More...
 
uint64_t pool_id_
 The pool where excess elements are placed. More...
 
PoolElementsafe_pool_ {nullptr}
 A linked list of pool elements. More...
 
PoolElementunsafe_pool_ {nullptr}
 A linked list of pool elements. More...
 
uint64_t safe_pool_count_ {0}
 Two counters used to track the number of elements in the linked list. More...
 
uint64_t unsafe_pool_count_ {0}
 

Detailed Description

Defines a pool of descriptor objects which is used to allocate descriptors and to store them while they are not safe to delete.

The pool is represented as two linked lists of descriptors: one for safe elements and one for unsafe elements. The safe pool is known to only contain items owned by the thread owning the DescriptorPool object, and the unsafe pool contains items where other threads may still hold references to them.

Further, the pool object has a parent who is shared amongst other threads. When a pool is to be destroyed, it sends its remaining elements to the parent, relinquishing ownership of said elements. A top-level pool has a null parent. At the moment, it only makes sense to have a single top-level parent representing the central pool for all threads, and several local pools for each thread.

Constructor & Destructor Documentation

tervel::util::memory::rc::DescriptorPool::DescriptorPool ( PoolManager manager,
uint64_t  pool_id,
int  prefill = TERVEL_MEM_RC_MIN_NODES 
)
inline
tervel::util::memory::rc::DescriptorPool::~DescriptorPool ( )
inline

Member Function Documentation

void tervel::util::memory::rc::DescriptorPool::add_to_safe ( tervel::util::Descriptor descr)
private

Releases the descriptor back to the safe pool.

Caller relinquishes ownership of descriptor. It's expected that the given descriptor was taken from this pool to begin with.

Adding a descriptor to the safe pool calls its 'on_return_to_pool' method and its destructor.

void tervel::util::memory::rc::DescriptorPool::add_to_unsafe ( tervel::util::Descriptor descr)
private

Releases the descriptor back to the unsafe pool.

Caller relinquishes ownership of descriptor. It's expected that the given descriptor was taken from this pool to begin with.

See notes on add_to_safe()

tervel::util::memory::rc::DescriptorPool::DISALLOW_COPY_AND_ASSIGN ( DescriptorPool  )
private
void tervel::util::memory::rc::DescriptorPool::free_descriptor ( tervel::util::Descriptor descr,
bool  dont_check = false 
)

Once a user is done with a descriptor, they should free it with this method.

Parameters
descrThe descriptor to free.
dont_checkDon't check if the descriptor is being watched before freeing it. Use this flag if you know that no other thread has had access to this descriptor.
poolthe pool to use when freeing the descriptor.
template<typename DescrType , typename... Args >
DescrType * tervel::util::memory::rc::DescriptorPool::get_descriptor ( Args &&...  args)

Constructs and returns a descriptor.

Arguments are forwarded to the constructor of the given descriptor type. User should call free_descriptor on the returned pointer when they are done with it to avoid memory leaks.

PoolElement* tervel::util::memory::rc::DescriptorPool::get_from_pool ( bool  allocate_new = true)
private

Gets a free element.

The local pool is checked for one first, then the manager if there are no local ones, and if all else fails, a new one is allocated using new.

Parameters
allocate_newIf true and there are no free elements to retrieve from the pool, a new one is allocated. Otherwise, nullptr is returned.
void tervel::util::memory::rc::DescriptorPool::offload ( )
private

Sends a subset of the elements to the managers pool.

void tervel::util::memory::rc::DescriptorPool::reserve ( size_t  num_descriptors = TERVEL_MEM_RC_MIN_NODES)

Allocates an extra num_descriptors elements to the pool.

void tervel::util::memory::rc::DescriptorPool::send_safe_to_manager ( )
private

Sends the elements from the safe pool to the corresponding safe pool in this pool's manager.

void tervel::util::memory::rc::DescriptorPool::send_unsafe_to_manager ( )
private

Sends the elements from the unsafe pool to the corresponding unsafe pool in this pool's manager.

void tervel::util::memory::rc::DescriptorPool::try_clear_unsafe_pool ( bool  dont_check = false)
private

Try to move elements from the unsafe pool to the safe pool.

bool tervel::util::memory::rc::DescriptorPool::verify_pool_count ( PoolElement pool,
uint64_t  count 
)
private

verifies that the length of the linked list matches the count

Member Data Documentation

PoolManager* tervel::util::memory::rc::DescriptorPool::manager_
private

This pool's manager.

uint64_t tervel::util::memory::rc::DescriptorPool::pool_id_
private

The pool where excess elements are placed.

PoolElement* tervel::util::memory::rc::DescriptorPool::safe_pool_ {nullptr}
private

A linked list of pool elements.

One can be assured that no thread will try to access the descriptor of any element in this pool. They can't be freed as some threads may still have access to the element itself and may try to increment the refrence count.

uint64_t tervel::util::memory::rc::DescriptorPool::safe_pool_count_ {0}
private

Two counters used to track the number of elements in the linked list.

this facilitates the detection of when there are too many elements.

PoolElement* tervel::util::memory::rc::DescriptorPool::unsafe_pool_ {nullptr}
private

A linked list of pool elements.

Elements get released to this pool when they're no longer needed, but some threads may still try to access the descriptor in the element. After some time has passed, items generally move from this pool to the safe_pool_

uint64_t tervel::util::memory::rc::DescriptorPool::unsafe_pool_count_ {0}
private

The documentation for this class was generated from the following file: