CppCommon  1.0.4.1
C++ Common Library
mpsc_linked_queue.inl
Go to the documentation of this file.
1 
9 namespace CppCommon {
10 
11 template<typename T>
12 inline MPSCLinkedQueue<T>::MPSCLinkedQueue() : _head(new Node), _tail(_head.load(std::memory_order_relaxed))
13 {
14  memset(_pad0, 0, sizeof(cache_line_pad));
15  memset(_pad1, 0, sizeof(cache_line_pad));
16  memset(_pad2, 0, sizeof(cache_line_pad));
17 
18  // Linked queue is initialized with a fake node as a head node
19  Node* front = _head.load(std::memory_order_relaxed);
20  front->next.store(nullptr, std::memory_order_relaxed);
21 }
22 
23 template<typename T>
25 {
26  // Remove all nodes from the linked queue
27  T item;
28  while (Dequeue(item)) {}
29 
30  // Remove the last fake node
31  Node* front = _head.load(std::memory_order_relaxed);
32  delete front;
33 }
34 
35 template<typename T>
36 inline bool MPSCLinkedQueue<T>::Enqueue(const T& item)
37 {
38  T temp = item;
39  return Enqueue(std::forward<T>(temp));
40 }
41 
42 template<typename T>
43 inline bool MPSCLinkedQueue<T>::Enqueue(T&& item)
44 {
45  // Create new head node
46  Node* node = new Node;
47  if (node == nullptr)
48  return false;
49 
50  // Fill new head node with the given value
51  node->value = std::move(item);
52  node->next.store(nullptr, std::memory_order_relaxed);
53 
54  // Insert new head node into the queue and linked it with the previous one
55  Node* prev_head = _head.exchange(node, std::memory_order_acq_rel);
56  prev_head->next.store(node, std::memory_order_release);
57 
58  return true;
59 }
60 
61 template<typename T>
62 inline bool MPSCLinkedQueue<T>::Dequeue(T& item)
63 {
64  Node* tail = _tail.load(std::memory_order_relaxed);
65  Node* next = tail->next.load(std::memory_order_acquire);
66 
67  // Check if the linked queue is empty
68  if (next == nullptr)
69  return false;
70 
71  // Get the item value
72  item = std::move(next->value);
73 
74  // Update tail node with a next one
75  _tail.store(next, std::memory_order_release);
76 
77  // Remove the previous tail node
78  delete tail;
79 
80  return true;
81 }
82 
83 } // namespace CppCommon
bool Enqueue(const T &item)
Enqueue an item into the linked queue (multiple producers threads method)
bool Dequeue(T &item)
Dequeue an item from the linked queue (single consumer thread method)
C++ Common project definitions.
Definition: token_bucket.h:15