3 releases (breaking)
0.3.0 | Dec 15, 2024 |
---|---|
0.2.0 | Dec 8, 2024 |
0.1.0 | Dec 6, 2024 |
#282 in Concurrency
386 downloads per month
39KB
846 lines
This crate implements three lock-free structures for object transfers:
- an
AtomicSlot<T>
type - small one-shot SPSC channels
- fully-featured MPMC channels
All of these structures are synchronized without any locks and without spinning/yielding.
This crate is compatible with no_std
targets, except for the _blocking
methods.
AtomicSlot<T>
You can atomically swap the contents of this slot from any thread.
Think of it as Mutex<Option<Box<T>>>
without any actual locking.
One shot SPSC channels
let (tx, rx) = async_fifo::slot::oneshot();
let item = "Hello, world!";
tx.send(Box::new(item));
let _task = async {
assert_eq!(*rx.await, item);
};
Very simple single-use channels with a sync and async API, blocking/non-blocking.
This builds on AtomicSlot<T>
, so the item has to be boxed.
Most useful for the transfer of return values in the context of remote procedure calling, as "reply pipes".
Fully-featured MPMC Channels
let (tx, [mut rx1, mut rx2]) = async_fifo::fifo::new();
let item = "Hello, world!";
tx.send(item);
assert_eq!(rx2.try_recv(), Some(item));
// producers can be cloned
let _tx2 = tx.clone();
// asynchronous use
let _task = async {
loop {
println!("Received: {:?}", rx1.recv().await);
}
};
These channels have the following characteristics:
- Multi-Producer / Multi-Consumer (MPMC) with every item routed to exactly one consumer
- Asynchronous and synchronous API, both blocking and non-blocking
- Strict delivery order: these channels have strong FIFO guarantees
- Batch production and consumption (both atomic)
- Send operations are guaranteed to succeed immediately without any sort of yielding/blocking
- Producers can be cloned (but not consumers)
Internal Details
Fifos internally own a chain of blocks.
- blocks have a number of item slots (32 by default)
- they are allocated and appended to the chain by producers
- they are then populated by producers and consumed by consumers
- fully consumed first blocks get recycled and appended again at the end of the chain (when no one is visiting them anymore)
- the fifo has atomic cursors to track which block slots are available for production and consumption