79 free_node(node.get());
82 free_node(head.get());
91template <
typename T,
typename A>
94 value_type*
const value = make_value(x);
102template <
typename T,
typename A>
105 value_type*
const value = make_value(std::move(x));
113template <
typename T,
typename A>
114template <
class... Args>
117 value_type*
const value = make_value(std::forward<Args>(args)...);
126template <
typename T,
typename A>
131 pointer_t head = head_.load(std::memory_order_acquire);
132 pointer_t tail = tail_.load(std::memory_order_acquire);
133 pointer_t next = head->next.load(std::memory_order_acquire);
134 if (head == head_.load(std::memory_order_acquire))
136 if (head.get() == tail.get())
142 pointer_t new_tail(next.get(), tail.nextTag());
143 tail_.compare_exchange_weak(tail, new_tail);
157 value_type* value = next->value.load(std::memory_order_acquire);
159 pointer_t new_head(next.get(), head.nextTag());
160 if (head_.compare_exchange_strong(head, new_head))
164 x = std::move(*value);
169 free_node(head.get());
173 free_node(head.get());
183template <
typename T,
typename A>
184template <
class... Args>
185typename lock_free_queue<T, A>::value_type*
186lock_free_queue<T, A>::make_value(Args&&... args)
188 void* p = value_allocator_.allocate();
191 return new (p)
value_type{ std::forward<Args>(args)... };
195 value_allocator_.deallocate(p);
202template <
typename T,
typename A>
203void lock_free_queue<T, A>::free_value(value_type* value)
205 value->~value_type();
206 value_allocator_.deallocate(value);
211template <
typename T,
typename A>
212void lock_free_queue<T, A>::push_value(value_type* value)
217 node = make_node(value);
227 tail = tail_.load(std::memory_order_acquire);
228 pointer_t
next = tail->next.load(std::memory_order_acquire);
229 if (tail == tail_.load(std::memory_order_acquire))
233 pointer_t new_next(node,
next.nextTag());
234 if (tail->next.compare_exchange_weak(next, new_next))
241 pointer_t new_tail(
next.get(), tail.nextTag());
242 tail_.compare_exchange_weak(tail, new_tail);
246 pointer_t new_tail(node, tail.nextTag());
247 tail_.compare_exchange_strong(tail, new_tail);
252template <
typename T,
typename A>
253typename lock_free_queue<T, A>::node_t*
254lock_free_queue<T, A>::make_node(value_type* value)
256 void* p = node_allocator_.allocate();
259 return new (p) node_t(value);
263 node_allocator_.deallocate(p);
270template <
typename T,
typename A>
271void lock_free_queue<T, A>::free_node(node_t* node)
274 node_allocator_.deallocate(node);