Tervel
1.0.0
A collection of wait-free containers and algorithms.
|
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 | |
PoolElement * | get_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 | |
PoolManager * | manager_ |
This pool's manager. More... | |
uint64_t | pool_id_ |
The pool where excess elements are placed. More... | |
PoolElement * | safe_pool_ {nullptr} |
A linked list of pool elements. More... | |
PoolElement * | unsafe_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} |
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.
|
inline |
|
inline |
|
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.
|
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()
|
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.
descr | The descriptor to free. |
dont_check | Don'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. |
pool | the pool to use when freeing the descriptor. |
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.
|
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.
allocate_new | If true and there are no free elements to retrieve from the pool, a new one is allocated. Otherwise, nullptr is returned. |
|
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.
|
private |
Sends the elements from the safe pool to the corresponding safe pool in this pool's manager.
|
private |
Sends the elements from the unsafe pool to the corresponding unsafe pool in this pool's manager.
|
private |
Try to move elements from the unsafe pool to the safe pool.
|
private |
verifies that the length of the linked list matches the count
|
private |
This pool's manager.
|
private |
The pool where excess elements are placed.
|
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.
|
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.
|
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_
|
private |