Logger System 1.0.0
High-performance C++20 thread-safe logging system with asynchronous capabilities
Loading...
Searching...
No Matches
kcenon::logger::async::lockfree_spsc_queue< T, Size > Class Template Reference

Lock-free single-producer single-consumer queue. More...

#include <lockfree_queue.h>

Collaboration diagram for kcenon::logger::async::lockfree_spsc_queue< T, Size >:
Collaboration graph

Classes

struct  cell
 Cell structure with sequence number for ABA prevention. More...
 

Public Member Functions

 lockfree_spsc_queue ()
 Constructor.
 
 ~lockfree_spsc_queue ()
 Destructor.
 
bool enqueue (const T &item)
 Enqueue an item (producer side)
 
bool enqueue (T &&item)
 Enqueue an item using move semantics (producer side)
 
bool dequeue (T &item)
 Dequeue an item (consumer side)
 
bool empty () const
 Check if queue is empty.
 
bool full () const
 Check if queue is full.
 
size_t size () const
 Get approximate queue size.
 
constexpr size_t capacity () const
 Get queue capacity.
 

Private Member Functions

template<typename U >
bool enqueue_impl (U &&item)
 Implementation for enqueue operations.
 

Private Attributes

std::atomic< size_t > head_
 
std::atomic< size_t > tail_
 
std::array< cell, Size > cells_
 

Static Private Attributes

static constexpr size_t mask_ = Size - 1
 
static constexpr size_t cache_line_size = 64
 Cache line size for padding.
 

Detailed Description

template<typename T, size_t Size>
class kcenon::logger::async::lockfree_spsc_queue< T, Size >

Lock-free single-producer single-consumer queue.

Template Parameters
TType of elements to store
SizeQueue capacity (must be power of 2)

Definition at line 41 of file lockfree_queue.h.

Constructor & Destructor Documentation

◆ lockfree_spsc_queue()

template<typename T , size_t Size>
kcenon::logger::async::lockfree_spsc_queue< T, Size >::lockfree_spsc_queue ( )
inline

Constructor.

Definition at line 49 of file lockfree_queue.h.

50 : head_{0}
51 , tail_{0} {
52 // Initialize cell sequence numbers for ABA prevention
53 for (size_t i = 0; i < Size; ++i) {
54 cells_[i].sequence.store(i, std::memory_order_relaxed);
55 }
56 }

References kcenon::logger::async::lockfree_spsc_queue< T, Size >::cells_.

◆ ~lockfree_spsc_queue()

template<typename T , size_t Size>
kcenon::logger::async::lockfree_spsc_queue< T, Size >::~lockfree_spsc_queue ( )
inline

Destructor.

Definition at line 61 of file lockfree_queue.h.

61 {
62 T item;
63 while (dequeue(item)) {
64 // Clean up remaining items
65 }
66 }
bool dequeue(T &item)
Dequeue an item (consumer side)

References kcenon::logger::async::lockfree_spsc_queue< T, Size >::dequeue().

Here is the call graph for this function:

Member Function Documentation

◆ capacity()

template<typename T , size_t Size>
size_t kcenon::logger::async::lockfree_spsc_queue< T, Size >::capacity ( ) const
inlineconstexpr

Get queue capacity.

Returns
Maximum number of elements

Definition at line 143 of file lockfree_queue.h.

143 {
144 return Size;
145 }

◆ dequeue()

template<typename T , size_t Size>
bool kcenon::logger::async::lockfree_spsc_queue< T, Size >::dequeue ( T & item)
inline

Dequeue an item (consumer side)

Parameters
itemReference to store the dequeued item
Returns
true if successful, false if queue is empty

Definition at line 91 of file lockfree_queue.h.

91 {
92 const size_t pos = tail_.load(std::memory_order_relaxed);
93 auto& cell = cells_[pos & mask_];
94
95 const size_t seq = cell.sequence.load(std::memory_order_acquire);
96 const size_t expected_seq = pos + 1;
97
98 if (seq != expected_seq) {
99 return false; // Queue is empty
100 }
101
102 item = std::move(cell.data);
103 cell.sequence.store(pos + mask_ + 1, std::memory_order_release);
104 tail_.store(pos + 1, std::memory_order_relaxed);
105
106 return true;
107 }

References kcenon::logger::async::lockfree_spsc_queue< T, Size >::cells_, kcenon::logger::async::lockfree_spsc_queue< T, Size >::cell::data, kcenon::logger::async::lockfree_spsc_queue< T, Size >::mask_, kcenon::logger::async::lockfree_spsc_queue< T, Size >::cell::sequence, and kcenon::logger::async::lockfree_spsc_queue< T, Size >::tail_.

Referenced by kcenon::logger::async::lockfree_spsc_queue< T, Size >::~lockfree_spsc_queue().

Here is the caller graph for this function:

◆ empty()

template<typename T , size_t Size>
bool kcenon::logger::async::lockfree_spsc_queue< T, Size >::empty ( ) const
inline

Check if queue is empty.

Returns
true if empty

Definition at line 113 of file lockfree_queue.h.

113 {
114 const size_t head_pos = head_.load(std::memory_order_acquire);
115 const size_t tail_pos = tail_.load(std::memory_order_acquire);
116 return head_pos == tail_pos;
117 }

References kcenon::logger::async::lockfree_spsc_queue< T, Size >::head_, and kcenon::logger::async::lockfree_spsc_queue< T, Size >::tail_.

◆ enqueue() [1/2]

template<typename T , size_t Size>
bool kcenon::logger::async::lockfree_spsc_queue< T, Size >::enqueue ( const T & item)
inline

Enqueue an item (producer side)

Parameters
itemItem to enqueue
Returns
true if successful, false if queue is full

Definition at line 73 of file lockfree_queue.h.

73 {
74 return enqueue_impl(item);
75 }
bool enqueue_impl(U &&item)
Implementation for enqueue operations.

References kcenon::logger::async::lockfree_spsc_queue< T, Size >::enqueue_impl().

Here is the call graph for this function:

◆ enqueue() [2/2]

template<typename T , size_t Size>
bool kcenon::logger::async::lockfree_spsc_queue< T, Size >::enqueue ( T && item)
inline

Enqueue an item using move semantics (producer side)

Parameters
itemItem to enqueue
Returns
true if successful, false if queue is full

Definition at line 82 of file lockfree_queue.h.

82 {
83 return enqueue_impl(std::move(item));
84 }

References kcenon::logger::async::lockfree_spsc_queue< T, Size >::enqueue_impl().

Here is the call graph for this function:

◆ enqueue_impl()

template<typename T , size_t Size>
template<typename U >
bool kcenon::logger::async::lockfree_spsc_queue< T, Size >::enqueue_impl ( U && item)
inlineprivate

Implementation for enqueue operations.

Template Parameters
UUniversal reference type
Parameters
itemItem to enqueue
Returns
true if successful, false if queue is full

Definition at line 172 of file lockfree_queue.h.

172 {
173 const size_t pos = head_.load(std::memory_order_relaxed);
174 auto& cell = cells_[pos & mask_];
175
176 const size_t seq = cell.sequence.load(std::memory_order_acquire);
177 const size_t expected_seq = pos;
178
179 if (seq != expected_seq) {
180 return false; // Queue is full
181 }
182
183 cell.data = std::forward<U>(item);
184 cell.sequence.store(pos + 1, std::memory_order_release);
185 head_.store(pos + 1, std::memory_order_relaxed);
186
187 return true;
188 }

References kcenon::logger::async::lockfree_spsc_queue< T, Size >::cell::data, and kcenon::logger::async::lockfree_spsc_queue< T, Size >::cell::sequence.

Referenced by kcenon::logger::async::lockfree_spsc_queue< T, Size >::enqueue(), and kcenon::logger::async::lockfree_spsc_queue< T, Size >::enqueue().

Here is the caller graph for this function:

◆ full()

template<typename T , size_t Size>
bool kcenon::logger::async::lockfree_spsc_queue< T, Size >::full ( ) const
inline

Check if queue is full.

Returns
true if full

Definition at line 123 of file lockfree_queue.h.

123 {
124 const size_t head_pos = head_.load(std::memory_order_acquire);
125 const size_t tail_pos = tail_.load(std::memory_order_acquire);
126 return ((head_pos + 1) & mask_) == (tail_pos & mask_);
127 }

References kcenon::logger::async::lockfree_spsc_queue< T, Size >::head_, kcenon::logger::async::lockfree_spsc_queue< T, Size >::mask_, and kcenon::logger::async::lockfree_spsc_queue< T, Size >::tail_.

◆ size()

template<typename T , size_t Size>
size_t kcenon::logger::async::lockfree_spsc_queue< T, Size >::size ( ) const
inline

Get approximate queue size.

Returns
Approximate number of elements in queue

Definition at line 133 of file lockfree_queue.h.

133 {
134 const size_t head_pos = head_.load(std::memory_order_acquire);
135 const size_t tail_pos = tail_.load(std::memory_order_acquire);
136 return head_pos - tail_pos;
137 }

References kcenon::logger::async::lockfree_spsc_queue< T, Size >::head_, and kcenon::logger::async::lockfree_spsc_queue< T, Size >::tail_.

Member Data Documentation

◆ cache_line_size

template<typename T , size_t Size>
size_t kcenon::logger::async::lockfree_spsc_queue< T, Size >::cache_line_size = 64
staticconstexprprivate

Cache line size for padding.

Definition at line 153 of file lockfree_queue.h.

◆ cells_

◆ head_

◆ mask_

template<typename T , size_t Size>
size_t kcenon::logger::async::lockfree_spsc_queue< T, Size >::mask_ = Size - 1
staticconstexprprivate

◆ tail_


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