Expand description

Lock-free SPSC FIFO ring buffer with direct access to inner data.

Features

  • Lock-free operations - they succeed or fail immediately without blocking or waiting.
  • Arbitrary item type (not only Copy).
  • Items can be inserted and removed one by one or many at once.
  • Thread-safe direct access to the internal ring buffer memory.
  • Read and Write implementation.
  • Can be used without std and even without alloc (using only statically-allocated memory).

Usage

At first you need to create the ring buffer itself. HeapRb is recommended but you may choose another one.

After the ring buffer is created it may be splitted into pair of Producer and Consumer. Producer is used to insert items to the ring buffer, Consumer - to remove items from it. For SharedRb and its derivatives they can be used in different threads.

Types

There are several types of ring buffers provided:

  • LocalRb. Only for single-threaded use.
  • SharedRb. Can be shared between threads. Its derivatives:
    • HeapRb. Contents are stored in dynamic memory. Recommended for use in most cases.
    • StaticRb. Contents can be stored in statically-allocated memory.

Performance

SharedRb needs to synchronize CPU cache between CPU cores. This synchronization has some overhead. To avoid multiple unnecessary synchronizations you may use postponed mode of operation (see description for Producer and Consumer) or methods that operates many items at once (Producer::push_slice/Producer::push_iter, Consumer::pop_slice, etc.).

For single-threaded usage LocalRb is recommended because it is faster than SharedRb due to absence of CPU cache synchronization.

Benchmarks

You may see typical performance of different methods in benchmarks:

cargo +nightly bench --features bench

Nightly toolchain is required.

Examples

Simple

use ringbuf::HeapRb;

let rb = HeapRb::<i32>::new(2);
let (mut prod, mut cons) = rb.split();

prod.push(0).unwrap();
prod.push(1).unwrap();
assert_eq!(prod.push(2), Err(2));

assert_eq!(cons.pop(), Some(0));

prod.push(2).unwrap();

assert_eq!(cons.pop(), Some(1));
assert_eq!(cons.pop(), Some(2));
assert_eq!(cons.pop(), None);

No heap

use ringbuf::StaticRb;

const RB_SIZE: usize = 1;
let mut rb = StaticRb::<i32, RB_SIZE>::default();
let (mut prod, mut cons) = rb.split_ref();

assert_eq!(prod.push(123), Ok(()));
assert_eq!(prod.push(321), Err(321));

assert_eq!(cons.pop(), Some(123));
assert_eq!(cons.pop(), None);

Re-exports

pub use consumer::Consumer;
pub use producer::Producer;

Modules

Consumer and additional types.

Producer and additional types.

Ring buffer traits and implementations.

Structs

Ring buffer for using in single thread.

Ring buffer that could be shared between threads.

Functions

Moves at most count items from the src consumer to the dst producer.

Type Definitions

Heap-allocated ring buffer.

Stack-allocated ring buffer with static capacity.