xenium
|
A bounded generic multi-producer/multi-consumer FIFO queue. More...
#include <vyukov_bounded_queue.hpp>
Public Member Functions | |
vyukov_bounded_queue (std::size_t size) | |
Constructs a new instance with the specified maximum size. More... | |
template<class... Args> | |
bool | try_push (Args &&... args) |
Tries to push a new element to the queue. More... | |
template<class... Args> | |
bool | try_push_strong (Args &&... args) |
Tries to push a new element to the queue. More... | |
template<class... Args> | |
bool | try_push_weak (Args &&... args) |
Tries to push a new element to the queue. More... | |
bool | try_pop (T &result) |
Tries to pop an element from the queue. More... | |
bool | try_pop_strong (T &result) |
Tries to pop an element from the queue as long as the queue is not empty. More... | |
bool | try_pop_weak (T &result) |
Tries to pop an element from the queue. More... | |
A bounded generic multi-producer/multi-consumer FIFO queue.
This implementation is based on the bounded MPMC queue proposed by Vyukov [Vy10]. It is fully generic and can handle any type T
, as long as it is default constructible and either copyable or movable.
Producers and consumers operate independently, but the operations are not lock-free, i.e., a try_pop
may have to wait for a pending try_push
operation to finish and vice versa.
The try_push_weak
and try_pop_weak
versions are lock-free, but may fail in situations were the non-weak versions would succeed. Consider the following situation: Thread T1 and thread T2 both push to the queue. T1 starts before T2, but T2 finishes faster. Now T2 tries to pop from the queue. The queue is not empty (T2 has previously pushed an element, and there are no other pop operations involved), but T1 has still not finished its push operation. However, because T1 has started its push before T2, this is the next item to be popped. In such a situation try_pop
would keep spinning until T1 has finished, while try_pop_weak
would immediately return false, even though the queue is not empty.
T | type of the stored elements. |
|
inlineexplicit |
Constructs a new instance with the specified maximum size.
size | max number of elements in the queue; must be a power of two greater one. |
|
inline |
Tries to pop an element from the queue.
If policy::default_to_weak
has been specified to be true, this method forwards to try_pop_weak
, otherwise it forwards to try_pop_strong
.
Progress guarantees: see try_pop_weak
/try_pop_strong
result | the value popped from the queue if the operation was successful |
true
if the operation was successful, otherwise false
|
inline |
Tries to pop an element from the queue as long as the queue is not empty.
In case a push operation is still pending try_pop
keeps spinning until the push has finished.
Progress guarantees: blocking
result | the value popped from the queue if the operation was successful |
true
if the operation was successful, otherwise false
|
inline |
Tries to pop an element from the queue.
This operation fails if the queue is empty or a push operation on the element to be popped is still pending.
Progress guarantees: lock-free
result | the value popped from the queue if the operation was successful |
true
if the operation was successful, otherwise false
|
inline |
Tries to push a new element to the queue.
If policy::default_to_weak
has been specified to be true, this method forwards to try_push_weak
, otherwise it forwards to try_push_strong
.
Progress guarantees: see try_push_weak
/try_push_strong
Args |
args |
true
if the operation was successful, otherwise false
|
inline |
Tries to push a new element to the queue.
Tries to reserve a cell for the new element as long as the number of elements does not exceed the specified size.
If the argument is of type T
, the element is either copy-assigned or move-assigned (depending on whether Args
is an l-value or r-value). Otherwise, a temporary T
instance is created using perfect-forwarding on the given arguments, which is then move-assigned.
Progress guarantees: blocking
Args |
args |
true
if the operation was successful, otherwise false
|
inline |
Tries to push a new element to the queue.
Tries to reserve a cell for the new element; fails if the queue is full or a pop operation on the element to be pushed to is still pending.
If the argument is of type T
, the element is either copy-assigned or move-assigned (depending on whether Args
is an l-value or r-value). Otherwise, a temporary T
instance is created using perfect-forwarding on the given arguments, which is then move-assigned.
Progress guarantees: lock-free
Args |
args |
true
if the operation was successful, otherwise false