CppCommon 1.0.5.0
C++ Common Library
Loading...
Searching...
No Matches
spsc_ring_queue.inl
Go to the documentation of this file.
1
9namespace CppCommon {
10
11template<typename T>
12inline SPSCRingQueue<T>::SPSCRingQueue(size_t capacity) : _capacity(capacity - 1), _mask(capacity - 1), _buffer(new T[capacity]), _head(0), _tail(0)
13{
14 assert((capacity > 1) && "Ring queue capacity must be greater than one!");
15 assert(((capacity & (capacity - 1)) == 0) && "Ring queue capacity must be a power of two!");
16
17 memset(_pad0, 0, sizeof(cache_line_pad));
18 memset(_pad1, 0, sizeof(cache_line_pad));
19 memset(_pad2, 0, sizeof(cache_line_pad));
20 memset(_pad3, 0, sizeof(cache_line_pad));
21}
22
23template<typename T>
24inline size_t SPSCRingQueue<T>::size() const noexcept
25{
26 const size_t head = _head.load(std::memory_order_acquire);
27 const size_t tail = _tail.load(std::memory_order_acquire);
28
29 return head - tail;
30}
31
32template<typename T>
33inline bool SPSCRingQueue<T>::Enqueue(const T& item)
34{
35 T temp = item;
36 return Enqueue(std::forward<T>(temp));
37}
38
39template<typename T>
40inline bool SPSCRingQueue<T>::Enqueue(T&& item)
41{
42 const size_t head = _head.load(std::memory_order_relaxed);
43 const size_t tail = _tail.load(std::memory_order_acquire);
44
45 // Check if the ring queue is full
46 if (((head - tail + 1) & _mask) == 0)
47 return false;
48
49 // Store the item value
50 _buffer[head & _mask] = std::move(item);
51
52 // Increase the head cursor
53 _head.store(head + 1, std::memory_order_release);
54
55 return true;
56}
57
58template<typename T>
59inline bool SPSCRingQueue<T>::Dequeue(T& item)
60{
61 const size_t tail = _tail.load(std::memory_order_relaxed);
62 const size_t head = _head.load(std::memory_order_acquire);
63
64 // Check if the ring queue is empty
65 if (((head - tail) & _mask) == 0)
66 return false;
67
68 // Get the item value
69 item = std::move(_buffer[tail & _mask]);
70
71 // Increase the tail cursor
72 _tail.store(tail + 1, std::memory_order_release);
73
74 return true;
75}
76
77} // namespace CppCommon
bool Enqueue(const T &item)
Enqueue an item into the ring queue (single producer thread method)
size_t size() const noexcept
Get ring queue size.
size_t capacity() const noexcept
Get ring queue capacity.
SPSCRingQueue(size_t capacity)
Default class constructor.
bool Dequeue(T &item)
Dequeue an item from the ring queue (single consumer thread method)
C++ Common project definitions.