An efficient, single-producer single-consumer (SPSC) lock-free ring buffer for Rust.
- Lock-free: Uses atomic operations for thread-safe access without mutexes.
- no_std: Compatible with bare-metal and embedded environments.
- Async Support:
- Embassy: First-class support for
embassy-rsvia theembassyfeature. - Tokio: Support for
tokiovia thetokiofeature.
- Embassy: First-class support for
- Static Initialization: Can be initialized in
staticcontexts.
use loopq::Buffer;
fn main() {
let buffer = Buffer::<1024>::new();
let mut producer = buffer.producer();
let mut consumer = buffer.consumer();
// Write data
let mut w = producer.writable_bytes();
w[0] = 42;
w.commit(1);
// Read data
let r = consumer.readable_bytes();
assert_eq!(r[0], 42);
r.consume(1);
}Enable the tokio feature in your Cargo.toml.
use loopq::tokio::AsyncBuffer;
#[tokio::main]
async fn main() {
let buffer = AsyncBuffer::<1024>::new();
let mut producer = buffer.producer();
let mut consumer = buffer.consumer();
// Producer
tokio::spawn(async move {
let mut w = producer.writable_bytes().await; // Blocks if full
w[0] = 42;
w.commit(1);
});
// Consumer
let r = consumer.readable_bytes().await; // Blocks if empty
assert_eq!(r[0], 42);
r.consume(1);
r.consume(1);
}loopq is designed for no_std environments and can be statically initialized.
use loopq::Buffer;
static BUFFER: Buffer<1024> = Buffer::new();
fn main() {
// Access the static buffer directly
let mut producer = BUFFER.producer();
let mut consumer = BUFFER.consumer();
// Use producer and consumer as normal
let mut w = producer.writable_bytes();
w[0] = 1;
w.commit(1);
}Licensed under either of
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
at your option.