Thread System 0.3.1
High-performance C++20 thread pool with work stealing and DAG scheduling
Loading...
Searching...
No Matches
kcenon::thread::detail::lockfree_job_queue::node_pool Class Reference

Lock-free node freelist (Treiber stack) for node recycling. More...

Collaboration diagram for kcenon::thread::detail::lockfree_job_queue::node_pool:
Collaboration graph

Public Member Functions

 node_pool ()=default
 
 ~node_pool ()
 
 node_pool (const node_pool &)=delete
 
node_pooloperator= (const node_pool &)=delete
 
nodeacquire (std::unique_ptr< job > &&job_data)
 Acquire a node from the pool, or allocate a new one.
 
void release (node *n)
 Return a retired node to the pool for reuse.
 

Private Attributes

std::atomic< node * > free_list_ {nullptr}
 

Detailed Description

Lock-free node freelist (Treiber stack) for node recycling.

Reduces heap allocations by reusing retired queue nodes. Nodes are returned to the pool via hazard pointer reclamation callbacks and acquired on enqueue instead of calling new.

Shared via shared_ptr so retire callbacks remain valid after queue destruction (the hazard pointer domain is a process-wide singleton and may invoke deleters after the queue is destroyed).

Definition at line 238 of file lockfree_job_queue.h.

Constructor & Destructor Documentation

◆ node_pool() [1/2]

kcenon::thread::detail::lockfree_job_queue::node_pool::node_pool ( )
default

◆ ~node_pool()

kcenon::thread::detail::lockfree_job_queue::node_pool::~node_pool ( )
inline

Definition at line 242 of file lockfree_job_queue.h.

242 {
243 // Drain freelist and delete all pooled nodes
244 node* head = free_list_.load(std::memory_order_relaxed);
245 while (head) {
246 node* next = head->next.load(std::memory_order_relaxed);
247 delete head;
248 head = next;
249 }
250 }

References free_list_, and kcenon::thread::detail::lockfree_job_queue::node::next.

◆ node_pool() [2/2]

kcenon::thread::detail::lockfree_job_queue::node_pool::node_pool ( const node_pool & )
delete

Member Function Documentation

◆ acquire()

node * kcenon::thread::detail::lockfree_job_queue::node_pool::acquire ( std::unique_ptr< job > && job_data)
inline

Acquire a node from the pool, or allocate a new one.

Parameters
job_dataJob to store in the node
Returns
Pointer to a ready-to-use node

Definition at line 261 of file lockfree_job_queue.h.

261 {
262 node* head = free_list_.load(std::memory_order_acquire);
263 while (head) {
264 if (free_list_.compare_exchange_weak(
265 head, head->next.load(std::memory_order_relaxed),
266 std::memory_order_acq_rel,
267 std::memory_order_acquire)) {
268 // Reuse pooled node — reset fields
269 head->data = std::move(job_data);
270 head->next.store(nullptr, std::memory_order_relaxed);
271 return head;
272 }
273 // head is updated by CAS on failure, retry
274 }
275 // Pool empty — allocate fresh node
276 return new node(std::move(job_data));
277 }

References kcenon::thread::detail::lockfree_job_queue::node::data, free_list_, and kcenon::thread::detail::lockfree_job_queue::node::next.

◆ operator=()

node_pool & kcenon::thread::detail::lockfree_job_queue::node_pool::operator= ( const node_pool & )
delete

◆ release()

void kcenon::thread::detail::lockfree_job_queue::node_pool::release ( node * n)
inline

Return a retired node to the pool for reuse.

Parameters
nNode to recycle (must have been fully retired by HP scan)

Definition at line 283 of file lockfree_job_queue.h.

283 {
284 if (!n) return;
285 // Clear payload before pooling
286 n->data.reset();
287 node* old_head = free_list_.load(std::memory_order_relaxed);
288 do {
289 n->next.store(old_head, std::memory_order_relaxed);
290 } while (!free_list_.compare_exchange_weak(
291 old_head, n,
292 std::memory_order_release,
293 std::memory_order_relaxed));
294 }

References kcenon::thread::detail::lockfree_job_queue::node::data, free_list_, and kcenon::thread::detail::lockfree_job_queue::node::next.

Member Data Documentation

◆ free_list_

std::atomic<node*> kcenon::thread::detail::lockfree_job_queue::node_pool::free_list_ {nullptr}
private

Definition at line 297 of file lockfree_job_queue.h.

297{nullptr};

Referenced by acquire(), release(), and ~node_pool().


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