|
Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
|
Unbounded lock-free multi-producer/single-consumer queue. More...
#include <tpl_mpsc_queue.H>
Classes | |
| struct | Node |
Public Member Functions | |
| MpscQueue () noexcept | |
| Construct an empty queue. | |
| ~MpscQueue () | |
| Destroy the queue, releasing any still-queued nodes. | |
| MpscQueue (const MpscQueue &)=delete | |
| Deleted copy constructor: the queue owns heap nodes with internal atomics that cannot be safely duplicated. | |
| MpscQueue & | operator= (const MpscQueue &)=delete |
| Deleted copy assignment operator. | |
| MpscQueue (MpscQueue &&)=delete | |
| Deleted move constructor: producers may hold a reference to a fixed queue address; see the class-level thread-safety note. | |
| MpscQueue & | operator= (MpscQueue &&)=delete |
| Deleted move assignment operator. | |
| void | push (const T &value) |
Push a copy of value onto the queue. | |
| void | push (T &&value) |
Push value onto the queue, moving it in. | |
| template<typename... Args> | |
| void | emplace (Args &&... args) |
| Construct a new element in place at the back of the queue. | |
| bool | try_pop (T &out) |
Attempt to pop the front element into out. | |
| std::optional< T > | try_pop () |
| Attempt to pop the front element. | |
| bool | is_empty () const noexcept |
| Advisory check for whether the queue currently has no elements. | |
Private Member Functions | |
| void | push_node (Node *n) noexcept |
Publish n as the new last node. | |
| Node * | pop_node () noexcept |
Consumer-only: detach and return the front node, or nullptr. | |
Private Attributes | |
| std::atomic< Node * > | head_ |
| Node * | tail_ |
| Node | stub_ |
Unbounded lock-free multi-producer/single-consumer queue.
See the file-level documentation in tpl_mpsc_queue.H for the full algorithm description, thread-safety contract, progress guarantees, and memory-ordering rationale.
| T | Type of the elements stored in the queue. Must be move- or copy-constructible; move-only types are supported. |
Definition at line 127 of file tpl_mpsc_queue.H.
|
inlinenoexcept |
Construct an empty queue.
| Nothing. |
Definition at line 207 of file tpl_mpsc_queue.H.
|
inline |
Destroy the queue, releasing any still-queued nodes.
Definition at line 214 of file tpl_mpsc_queue.H.
References Aleph::next(), Aleph::MpscQueue< T >::Node::next, Aleph::MpscQueue< T >::stub_, and Aleph::MpscQueue< T >::tail_.
Deleted copy constructor: the queue owns heap nodes with internal atomics that cannot be safely duplicated.
Deleted move constructor: producers may hold a reference to a fixed queue address; see the class-level thread-safety note.
|
inline |
Construct a new element in place at the back of the queue.
| Args | Constructor argument types. |
| args | Arguments forwarded to T's constructor. |
| Whatever | constructing T(std::forward<Args>(args)...) throws, or std::bad_alloc from allocating the node. If construction throws, the partially-built node is destroyed and nothing is enqueued. |
Definition at line 278 of file tpl_mpsc_queue.H.
References Aleph::blossom_maximum_cardinality_matching(), and Aleph::MpscQueue< T >::push_node().
Referenced by Aleph::MpscQueue< T >::push(), Aleph::MpscQueue< T >::push(), TEST(), TEST(), TEST(), TEST(), and TEST().
|
inlinenoexcept |
Advisory check for whether the queue currently has no elements.
true if the queue looked empty at the moment of the call. | Nothing. |
try_pop. Advisory under concurrent pushes: a producer may complete a push immediately after this returns true. Like try_pop, this can also report true during the narrow window where a push's exchange has completed but its store has not. Definition at line 341 of file tpl_mpsc_queue.H.
References Aleph::and, Aleph::MpscQueue< T >::Node::next, Aleph::MpscQueue< T >::stub_, and Aleph::MpscQueue< T >::tail_.
Referenced by TEST(), TEST(), TEST(), TEST(), TEST(), and TEST().
|
delete |
Deleted copy assignment operator.
|
delete |
Deleted move assignment operator.
|
inlineprivatenoexcept |
Consumer-only: detach and return the front node, or nullptr.
Implements Vyukov's pop exactly: on success, the returned node owns the dequeued value and is no longer reachable from the queue (the caller must destroy it once it is done reading ->value). Returning nullptr means either the queue is genuinely empty, or a producer's push_node was caught between its exchange and its store – both look identical to the consumer, and the documented contract is to treat that rare race as a transient "nothing to pop yet".
Definition at line 165 of file tpl_mpsc_queue.H.
References Aleph::MpscQueue< T >::head_, Aleph::next(), Aleph::MpscQueue< T >::Node::next, Aleph::MpscQueue< T >::push_node(), Aleph::MpscQueue< T >::stub_, and Aleph::MpscQueue< T >::tail_.
Referenced by Aleph::MpscQueue< T >::try_pop(), and Aleph::MpscQueue< T >::try_pop().
Push a copy of value onto the queue.
| value | The value to enqueue (copied). |
| Whatever | T's copy constructor throws, or std::bad_alloc. If construction throws, nothing is enqueued and the queue is left exactly as it was before the call. |
Definition at line 252 of file tpl_mpsc_queue.H.
References Aleph::MpscQueue< T >::emplace(), and value.
Referenced by TEST(), TEST(), TEST(), TEST(), TEST(), TEST(), and TEST().
Push value onto the queue, moving it in.
| value | The value to enqueue (moved from). |
| Whatever | T's move constructor throws, or std::bad_alloc. If construction throws, value is left in the state T's move constructor leaves a throwing source in, and nothing is enqueued. |
Definition at line 264 of file tpl_mpsc_queue.H.
References Aleph::MpscQueue< T >::emplace(), and value.
Publish n as the new last node.
Safe to call from any producer thread, and internally (single-threaded) to recycle &stub_.
Definition at line 148 of file tpl_mpsc_queue.H.
References Aleph::MpscQueue< T >::head_, and Aleph::MpscQueue< T >::Node::next.
Referenced by Aleph::MpscQueue< T >::emplace(), and Aleph::MpscQueue< T >::pop_node().
|
inline |
Attempt to pop the front element.
std::optional, or std::nullopt if the queue looked empty (see the class-level note on the narrow producer-race window). | Whatever | moving T into the returned std::optional throws. If it throws, the node has already been unlinked from the queue; the element is lost. The node itself is still freed (via RAII) even if the move throws. |
try_pop/is_empty call, nor from more than one thread. Definition at line 322 of file tpl_mpsc_queue.H.
References Aleph::MpscQueue< T >::pop_node().
Attempt to pop the front element into out.
| [out] | out | Reference receiving the dequeued value (move-assigned). |
true if an element was dequeued, false if the queue looked empty (see the class-level note on the narrow producer-race window that can also yield false transiently). | Whatever | T's move assignment throws. If it throws, the node has already been unlinked from the queue; the element is lost (this matches the "no defined recovery from a throwing move
assignment" convention used elsewhere in Aleph's queues). The node itself is still freed (via RAII) even if the move throws. |
try_pop/is_empty call, nor from more than one thread. Definition at line 298 of file tpl_mpsc_queue.H.
References out, and Aleph::MpscQueue< T >::pop_node().
Referenced by TEST(), TEST(), TEST(), TEST(), TEST(), TEST(), TEST(), and TEST().
|
private |
Definition at line 142 of file tpl_mpsc_queue.H.
Referenced by Aleph::MpscQueue< T >::pop_node(), and Aleph::MpscQueue< T >::push_node().
|
private |
Definition at line 144 of file tpl_mpsc_queue.H.
Referenced by Aleph::MpscQueue< T >::~MpscQueue(), Aleph::MpscQueue< T >::is_empty(), and Aleph::MpscQueue< T >::pop_node().
|
private |
Definition at line 143 of file tpl_mpsc_queue.H.
Referenced by Aleph::MpscQueue< T >::~MpscQueue(), Aleph::MpscQueue< T >::is_empty(), and Aleph::MpscQueue< T >::pop_node().