mn_atomic_queue.hpp
Go to the documentation of this file.
1 /*
2 *This file is part of the Mini Thread Library (https://github.com/RoseLeBlood/MiniThread ).
3 *Copyright (c) 2018 Amber-Sophia Schroeck
4 *
5 *The Mini Thread Library is free software; you can redistribute it and/or modify
6 *it under the terms of the GNU Lesser General Public License as published by
7 *the Free Software Foundation, version 3, or (at your option) any later version.
8 
9 *The Mini Thread Library is distributed in the hope that it will be useful, but
10 *WITHOUT ANY WARRANTY; without even the implied warranty of
11 *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 *General Public License for more details.
13 *
14 *You should have received a copy of the GNU Lesser General Public
15 *License along with the Mini Thread Library; if not, see
16 *<https://www.gnu.org/licenses/>.
17 */
18 #ifndef __MINLIB_ATOMIC_QUEUE_H__
19 #define __MINLIB_ATOMIC_QUEUE_H__
20 
21 #include "../mn_atomic.hpp"
22 
23 namespace mn {
24  namespace container {
25 
32  template <class T, mn::size_t TMAXITEMS >
34  public:
35  struct node {
38  };
39  public:
40  using value_type = T;
41  using reference = T&;
42  using lreference = T&&;
43  using pointer = node*;
44 
45  using const_value_type = const T;
46  using const_reference = const T&;
47 
49 
51  : m_atHead(), m_curItems(0) { }
52 
53  basic_atomic_queue(const self_type& other) = delete;
54  basic_atomic_queue(const self_type&& other) = delete;
55 
60  bool push(reference _Element) noexcept {
61  if(full()) return false;
62 
63  node * n = new node;
64  n->data = _Element;
65 
66  node* stale_head = m_atHead.load(memory_order::Release);
67  m_curItems++;
68 
69  do {
70  n->next = stale_head;
71  } while (!m_atHead.compare_exchange_weak(stale_head, n, memory_order::Release));
72 
73  return true;
74  }
75 
76  pointer pop_all(void) noexcept {
77  T* last = m_atHead.exchange(0, memory_order::Consume), * first = nullptr;
78  while(last) {
79  T * tmp = last;
80  last = last->next;
81  tmp->next = first;
82  first = tmp;
83  }
84  return first;
85  }
89  constexpr void clear() noexcept {
90  m_queue.clear();
91  }
97  constexpr bool empty() noexcept {
98  return m_curItems.load() == 0;
99  }
100 
101  constexpr bool full() noexcept {
102  return m_curItems.load() == TMAXITEMS;
103  }
108  constexpr mn::size_t length() noexcept {
109  return TMAXITEMS;
110  }
115  constexpr mn::size_t size() noexcept {
116  return m_curItems.load();
117  }
118 
123  constexpr mn::size_t left() noexcept {
124  if(full()) return 0;
125  return TMAXITEMS - m_curItems.load();
126  }
127 
128  void swap(const self_type& other) {
129  mn::swap(m_atHead, other.m_atHead);
131  }
132 
133  self_type& operator = (const self_type& other) {
134  m_atHead = other.m_atHead;
135  m_curItems = other.m_curItems;
136 
137  return *this;
138  }
139  protected:
142  };
143 
144  template <class T, mn::size_t TMAXITEMS = 64>
146  }
147 }
148 
149 #endif // __MINLIB_ATOMIC_QUEUE_H__
A basic lockfree atomic queue.
Definition: mn_atomic_queue.hpp:33
constexpr mn::size_t size() noexcept
Definition: mn_atomic_queue.hpp:115
pointer pop_all(void) noexcept
Definition: mn_atomic_queue.hpp:76
self_type & operator=(const self_type &other)
Definition: mn_atomic_queue.hpp:133
constexpr bool empty() noexcept
Check, if queue is empty.
Definition: mn_atomic_queue.hpp:97
basic_atomic_queue(const self_type &&other)=delete
void swap(const self_type &other)
Definition: mn_atomic_queue.hpp:128
constexpr bool full() noexcept
Definition: mn_atomic_queue.hpp:101
basic_atomic_queue()
Definition: mn_atomic_queue.hpp:50
constexpr mn::size_t left() noexcept
Definition: mn_atomic_queue.hpp:123
T && lreference
Definition: mn_atomic_queue.hpp:42
constexpr mn::size_t length() noexcept
How many items can queue.
Definition: mn_atomic_queue.hpp:108
T value_type
Definition: mn_atomic_queue.hpp:40
T & reference
Definition: mn_atomic_queue.hpp:41
mn::_atomic< pointer > m_atHead
Definition: mn_atomic_queue.hpp:140
mn::atomic_size_t m_curItems
Definition: mn_atomic_queue.hpp:141
bool push(reference _Element) noexcept
Push a element to the queue.
Definition: mn_atomic_queue.hpp:60
T data
Definition: mn_atomic_queue.hpp:36
const T const_value_type
Definition: mn_atomic_queue.hpp:45
basic_atomic_queue(const self_type &other)=delete
node * next
Definition: mn_atomic_queue.hpp:37
constexpr void clear() noexcept
Clear the queue.
Definition: mn_atomic_queue.hpp:89
const T & const_reference
Definition: mn_atomic_queue.hpp:46
Definition: mn_atomic_queue.hpp:35
basic_node< T > node
Node type witch allocated in global heap.
Definition: mn_node.hpp:266
struct mn::memory::detail::ptr_difference T
Definition: mn_atomic_singleton.hpp:38
Definition: mn_allocator_typetraits.hpp:25
void swap(TAssignable &a, TAssignable &b)
Definition: mn_algorithm.hpp:312
MN_THREAD_CONFIG_SIZE_TYPE size_t
Definition: mn_def.hpp:48