Logger System 0.1.3
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 35 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 43 of file lockfree_queue.h.

44 : head_{0}
45 , tail_{0} {
46 // Initialize cell sequence numbers for ABA prevention
47 for (size_t i = 0; i < Size; ++i) {
48 cells_[i].sequence.store(i, std::memory_order_relaxed);
49 }
50 }

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 55 of file lockfree_queue.h.

55 {
56 T item;
57 while (dequeue(item)) {
58 // Clean up remaining items
59 }
60 }
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 137 of file lockfree_queue.h.

137 {
138 return Size;
139 }

◆ 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 85 of file lockfree_queue.h.

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

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 107 of file lockfree_queue.h.

107 {
108 const size_t head_pos = head_.load(std::memory_order_acquire);
109 const size_t tail_pos = tail_.load(std::memory_order_acquire);
110 return head_pos == tail_pos;
111 }

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 67 of file lockfree_queue.h.

67 {
68 return enqueue_impl(item);
69 }
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 76 of file lockfree_queue.h.

76 {
77 return enqueue_impl(std::move(item));
78 }

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 166 of file lockfree_queue.h.

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

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 117 of file lockfree_queue.h.

117 {
118 const size_t head_pos = head_.load(std::memory_order_acquire);
119 const size_t tail_pos = tail_.load(std::memory_order_acquire);
120 return ((head_pos + 1) & mask_) == (tail_pos & mask_);
121 }

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 127 of file lockfree_queue.h.

127 {
128 const size_t head_pos = head_.load(std::memory_order_acquire);
129 const size_t tail_pos = tail_.load(std::memory_order_acquire);
130 return head_pos - tail_pos;
131 }

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 147 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: