8 releases
0.1.9 | May 6, 2023 |
---|---|
0.1.8 | Jan 6, 2023 |
0.1.7 | Mar 21, 2022 |
0.1.6 | Aug 27, 2020 |
0.1.3 | Apr 30, 2018 |
#934 in Concurrency
138 downloads per month
Used in apis
46KB
1.5K
SLoC
unbounded_spsc
An "unbounded" extension of
bounded_spsc_queue
.
This crate provides an unbounded SPSC queue with asynchronous sends, using
bounded_spsc_queue
for the
internal queue. This provides better performance and cache coherence than the
linked-list queue used in the standard std::sync::mpsc::channel
.
Besides being bounded, bounded_spsc_queue
itself only provides spin-wait for
blocking recv
(blocking when buffer is empty), so the blocking-wait code
found in the standard library is adapted here to provide a more CPU-friendly
blocking mechanism, both with and without timeout. This code is essentially
lock-free; there are no mutexes or condvars involved.
Note that bounded_spsc_queue
does not support zero-size message types (such
as unit type ()
), and will crash with an unspecified error; here we check for
zero-size and panic!
with an error message.
Sends are always asynchronous; if the underlying buffer is full, a new buffer
is created that is twice the size of the previous buffer, and sent to the
consumer by means of a standard asynchronous mpsc
channel. Currently there
are no mechanisms for specifying initial capacity (hard-coded to 128) or
shrinking.
Synchronous send (blocking when buffer is full) is not provided here: for that
use either bounded_spsc_queue
directly (spin-wait) or a standard
std::sync::mpsc::sync_channel
(block-waiting; uses a vector-backed buffer
internally).
Also taken from the standard library is the (unstable) implementation of the
select!
macro and related functionality that allows waiting on multiple
receivers. As noted in the original implementation, this code is sub-optimal
since it involves some allocations, and does not implement any kind of
"fairness" protocol-- see https://github.com/rust-lang/rust/issues/27800.
Dependencies
~255KB