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

Lock-free synchronization policy using Michael-Scott algorithm. More...

#include <sync_policies.h>

Collaboration diagram for kcenon::thread::policies::lockfree_sync_policy:
Collaboration graph

Classes

struct  node
 

Public Types

using policy_tag = sync_policy_tag
 

Public Member Functions

 lockfree_sync_policy ()
 Construct lock-free sync policy.
 
 ~lockfree_sync_policy ()
 Destructor.
 
 lockfree_sync_policy (const lockfree_sync_policy &)=delete
 
lockfree_sync_policyoperator= (const lockfree_sync_policy &)=delete
 
 lockfree_sync_policy (lockfree_sync_policy &&)=delete
 
lockfree_sync_policyoperator= (lockfree_sync_policy &&)=delete
 
auto enqueue (std::unique_ptr< job > &&value) -> common::VoidResult
 Enqueue a job (wait-free)
 
auto dequeue () -> common::Result< std::unique_ptr< job > >
 Dequeue a job (lock-free)
 
auto try_dequeue () -> common::Result< std::unique_ptr< job > >
 Try to dequeue a job (non-blocking, same as dequeue for lock-free)
 
auto empty () const -> bool
 Check if queue appears empty (approximate)
 
auto size () const -> std::size_t
 Get approximate queue size.
 
auto clear () -> void
 Clear queue (best effort for lock-free)
 
auto stop () -> void
 Stop the queue (sets shutdown flag)
 
auto is_stopped () const -> bool
 Check if queue is stopped.
 
auto set_notify (bool) -> void
 Set notify flag (no-op for lock-free)
 

Static Public Member Functions

static constexpr auto get_capabilities () -> queue_capabilities
 Queue capabilities for lock-free sync policy.
 

Private Attributes

std::atomic< node * > head_
 
std::atomic< node * > tail_
 
std::atomic< bool > shutdown_
 
std::atomic< std::size_t > approximate_size_
 

Detailed Description

Lock-free synchronization policy using Michael-Scott algorithm.

Provides high-throughput operations without locking. Size and empty checks are approximate.

Thread Safety

  • All operations are thread-safe using atomic operations
  • No blocking - uses spin-wait pattern

Performance Characteristics

  • Enqueue: O(1), wait-free
  • Dequeue: O(1), lock-free

Definition at line 211 of file sync_policies.h.

Member Typedef Documentation

◆ policy_tag

Constructor & Destructor Documentation

◆ lockfree_sync_policy() [1/3]

kcenon::thread::policies::lockfree_sync_policy::lockfree_sync_policy ( )
inline

Construct lock-free sync policy.

Definition at line 233 of file sync_policies.h.

233 : shutdown_(false), approximate_size_(0) {
234 auto dummy = new node(nullptr);
235 head_.store(dummy, std::memory_order_relaxed);
236 tail_.store(dummy, std::memory_order_relaxed);
237 }

References head_, and tail_.

◆ ~lockfree_sync_policy()

kcenon::thread::policies::lockfree_sync_policy::~lockfree_sync_policy ( )
inline

Destructor.

Definition at line 242 of file sync_policies.h.

242 {
243 shutdown_.store(true, std::memory_order_release);
244
245 // Drain remaining nodes
246 node* current = head_.load(std::memory_order_acquire);
247 while (current != nullptr) {
248 node* next = current->next.load(std::memory_order_acquire);
249 delete current;
250 current = next;
251 }
252 }

References head_, kcenon::thread::policies::lockfree_sync_policy::node::next, and shutdown_.

◆ lockfree_sync_policy() [2/3]

kcenon::thread::policies::lockfree_sync_policy::lockfree_sync_policy ( const lockfree_sync_policy & )
delete

◆ lockfree_sync_policy() [3/3]

kcenon::thread::policies::lockfree_sync_policy::lockfree_sync_policy ( lockfree_sync_policy && )
delete

Member Function Documentation

◆ clear()

auto kcenon::thread::policies::lockfree_sync_policy::clear ( ) -> void
inline

Clear queue (best effort for lock-free)

Definition at line 363 of file sync_policies.h.

363 {
364 while (true) {
365 auto result = dequeue();
366 if (result.is_err()) {
367 break;
368 }
369 }
370 }
auto dequeue() -> common::Result< std::unique_ptr< job > >
Dequeue a job (lock-free)

References dequeue().

Here is the call graph for this function:

◆ dequeue()

auto kcenon::thread::policies::lockfree_sync_policy::dequeue ( ) -> common::Result<std::unique_ptr<job>>
inlinenodiscard

Dequeue a job (lock-free)

Returns
Result containing the job or error

Definition at line 304 of file sync_policies.h.

304 {
305 while (true) {
306 node* head = head_.load(std::memory_order_acquire);
307 node* tail = tail_.load(std::memory_order_acquire);
308 node* next = head->next.load(std::memory_order_acquire);
309
310 if (head == head_.load(std::memory_order_acquire)) {
311 if (head == tail) {
312 if (next == nullptr) {
313 return common::error_info{-121, "queue is empty", "thread_system"};
314 }
315 tail_.compare_exchange_weak(tail, next,
316 std::memory_order_release,
317 std::memory_order_relaxed);
318 } else {
319 if (next != nullptr) {
320 auto value = std::move(next->data);
321 if (head_.compare_exchange_weak(head, next,
322 std::memory_order_release,
323 std::memory_order_relaxed)) {
324 approximate_size_.fetch_sub(1, std::memory_order_relaxed);
325 delete head;
326 return value;
327 }
328 }
329 }
330 }
331 }
332 }

References approximate_size_, kcenon::thread::policies::lockfree_sync_policy::node::data, head_, kcenon::thread::policies::lockfree_sync_policy::node::next, and tail_.

Referenced by clear(), and try_dequeue().

Here is the caller graph for this function:

◆ empty()

auto kcenon::thread::policies::lockfree_sync_policy::empty ( ) const -> bool
inlinenodiscard

Check if queue appears empty (approximate)

Returns
true if queue appears empty

Definition at line 346 of file sync_policies.h.

346 {
347 node* head = head_.load(std::memory_order_acquire);
348 node* next = head->next.load(std::memory_order_acquire);
349 return next == nullptr;
350 }

References head_, and kcenon::thread::policies::lockfree_sync_policy::node::next.

◆ enqueue()

auto kcenon::thread::policies::lockfree_sync_policy::enqueue ( std::unique_ptr< job > && value) -> common::VoidResult
inlinenodiscard

Enqueue a job (wait-free)

Parameters
valueJob to enqueue
Returns
VoidResult indicating success or error

Definition at line 265 of file sync_policies.h.

265 {
266 if (!value) {
267 return common::error_info{-105, "cannot enqueue null job", "thread_system"};
268 }
269
270 if (shutdown_.load(std::memory_order_acquire)) {
271 return common::error_info{-122, "queue is shutting down", "thread_system"};
272 }
273
274 auto new_node = new node(std::move(value));
275
276 while (true) {
277 node* tail = tail_.load(std::memory_order_acquire);
278 node* next = tail->next.load(std::memory_order_acquire);
279
280 if (tail == tail_.load(std::memory_order_acquire)) {
281 if (next == nullptr) {
282 if (tail->next.compare_exchange_weak(next, new_node,
283 std::memory_order_release,
284 std::memory_order_relaxed)) {
285 tail_.compare_exchange_strong(tail, new_node,
286 std::memory_order_release,
287 std::memory_order_relaxed);
288 approximate_size_.fetch_add(1, std::memory_order_relaxed);
289 return common::ok();
290 }
291 } else {
292 tail_.compare_exchange_weak(tail, next,
293 std::memory_order_release,
294 std::memory_order_relaxed);
295 }
296 }
297 }
298 }

References approximate_size_, kcenon::thread::policies::lockfree_sync_policy::node::next, shutdown_, and tail_.

◆ get_capabilities()

static constexpr auto kcenon::thread::policies::lockfree_sync_policy::get_capabilities ( ) -> queue_capabilities
inlinestaticnodiscardconstexpr

Queue capabilities for lock-free sync policy.

Definition at line 218 of file sync_policies.h.

218 {
219 return queue_capabilities{
220 .exact_size = false,
221 .atomic_empty_check = false,
222 .lock_free = true,
223 .wait_free = false,
224 .supports_batch = false,
225 .supports_blocking_wait = false,
226 .supports_stop = false
227 };
228 }

Referenced by kcenon::thread::policies::adaptive_sync_policy::get_capabilities().

Here is the caller graph for this function:

◆ is_stopped()

auto kcenon::thread::policies::lockfree_sync_policy::is_stopped ( ) const -> bool
inlinenodiscard

Check if queue is stopped.

Returns
true if stopped

Definition at line 383 of file sync_policies.h.

383 {
384 return shutdown_.load(std::memory_order_acquire);
385 }

References shutdown_.

◆ operator=() [1/2]

lockfree_sync_policy & kcenon::thread::policies::lockfree_sync_policy::operator= ( const lockfree_sync_policy & )
delete

◆ operator=() [2/2]

lockfree_sync_policy & kcenon::thread::policies::lockfree_sync_policy::operator= ( lockfree_sync_policy && )
delete

◆ set_notify()

auto kcenon::thread::policies::lockfree_sync_policy::set_notify ( bool ) -> void
inline

Set notify flag (no-op for lock-free)

Parameters
notifyIgnored

Definition at line 391 of file sync_policies.h.

391 {
392 // No-op: lock-free queue doesn't use condition variables
393 }

◆ size()

auto kcenon::thread::policies::lockfree_sync_policy::size ( ) const -> std::size_t
inlinenodiscard

Get approximate queue size.

Returns
Approximate number of jobs

Definition at line 356 of file sync_policies.h.

356 {
357 return approximate_size_.load(std::memory_order_relaxed);
358 }

References approximate_size_.

◆ stop()

auto kcenon::thread::policies::lockfree_sync_policy::stop ( ) -> void
inline

Stop the queue (sets shutdown flag)

Definition at line 375 of file sync_policies.h.

375 {
376 shutdown_.store(true, std::memory_order_release);
377 }

References shutdown_.

◆ try_dequeue()

auto kcenon::thread::policies::lockfree_sync_policy::try_dequeue ( ) -> common::Result<std::unique_ptr<job>>
inlinenodiscard

Try to dequeue a job (non-blocking, same as dequeue for lock-free)

Returns
Result containing the job or error

Definition at line 338 of file sync_policies.h.

338 {
339 return dequeue();
340 }

References dequeue().

Here is the call graph for this function:

Member Data Documentation

◆ approximate_size_

std::atomic<std::size_t> kcenon::thread::policies::lockfree_sync_policy::approximate_size_
mutableprivate

Definition at line 407 of file sync_policies.h.

Referenced by dequeue(), enqueue(), and size().

◆ head_

std::atomic<node*> kcenon::thread::policies::lockfree_sync_policy::head_
private

Definition at line 404 of file sync_policies.h.

Referenced by dequeue(), empty(), lockfree_sync_policy(), and ~lockfree_sync_policy().

◆ shutdown_

std::atomic<bool> kcenon::thread::policies::lockfree_sync_policy::shutdown_
private

Definition at line 406 of file sync_policies.h.

Referenced by enqueue(), is_stopped(), stop(), and ~lockfree_sync_policy().

◆ tail_

std::atomic<node*> kcenon::thread::policies::lockfree_sync_policy::tail_
private

Definition at line 405 of file sync_policies.h.

Referenced by dequeue(), enqueue(), and lockfree_sync_policy().


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