86template <
typename T,
typename A>
89 value_type*
const value = make_value(x);
97template <
typename T,
typename A>
100 value_type*
const value = make_value(std::move(x));
108template <
typename T,
typename A>
109template <
class... Args>
112 value_type*
const value = make_value(std::forward<Args>(args)...);
121template <
typename T,
typename A>
126 pointer_t head = head_.load(std::memory_order_acquire);
127 pointer_t tail = tail_.load(std::memory_order_acquire);
128 pointer_t next = head->next.load(std::memory_order_acquire);
129 if (head == head_.load(std::memory_order_acquire))
131 if (head.get() == tail.get())
137 pointer_t new_tail(next.get(), tail.nextTag());
138 tail_.compare_exchange_weak(tail, new_tail);
152 value_type* value = next->value.load(std::memory_order_acquire);
154 pointer_t new_head(next.get(), head.nextTag());
155 if (head_.compare_exchange_strong(head, new_head))
159 x = std::move(*value);
164 free_node(head.get());
168 free_node(head.get());
178template <
typename T,
typename A>
179template <
class... Args>
180typename lock_free_queue<T, A>::value_type*
181lock_free_queue<T, A>::make_value(Args&&... args)
183 void* p = value_allocator_.allocate();
186 return new (p)
value_type{ std::forward<Args>(args)... };
190 value_allocator_.deallocate(p);
197template <
typename T,
typename A>
198void lock_free_queue<T, A>::free_value(value_type* value)
200 value->~value_type();
201 value_allocator_.deallocate(value);
206template <
typename T,
typename A>
207void lock_free_queue<T, A>::push_value(value_type* value)
212 node = make_node(value);
222 tail = tail_.load(std::memory_order_acquire);
223 pointer_t
next = tail->next.load(std::memory_order_acquire);
224 if (tail == tail_.load(std::memory_order_acquire))
228 pointer_t new_next(node,
next.nextTag());
229 if (tail->next.compare_exchange_weak(next, new_next))
236 pointer_t new_tail(
next.get(), tail.nextTag());
237 tail_.compare_exchange_weak(tail, new_tail);
241 pointer_t new_tail(node, tail.nextTag());
242 tail_.compare_exchange_strong(tail, new_tail);
247template <
typename T,
typename A>
248typename lock_free_queue<T, A>::node_t*
249lock_free_queue<T, A>::make_node(value_type* value)
251 void* p = node_allocator_.allocate();
254 return new (p) node_t(value);
258 node_allocator_.deallocate(p);
265template <
typename T,
typename A>
266void lock_free_queue<T, A>::free_node(node_t* node)
269 node_allocator_.deallocate(node);