CppCommon  1.0.4.1
C++ Common Library
spsc_ring_queue.inl
Go to the documentation of this file.
1 
9 namespace CppCommon {
10 
11 template<typename T>
12 inline 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 
23 template<typename T>
24 inline 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 
32 template<typename T>
33 inline bool SPSCRingQueue<T>::Enqueue(const T& item)
34 {
35  T temp = item;
36  return Enqueue(std::forward<T>(temp));
37 }
38 
39 template<typename T>
40 inline 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 
58 template<typename T>
59 inline 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.
Definition: token_bucket.h:15