11 releases
0.3.3 | Aug 28, 2023 |
---|---|
0.3.2 | Aug 22, 2023 |
0.2.1 | Aug 20, 2023 |
0.1.4 | Aug 19, 2023 |
#765 in Embedded development
20KB
202 lines
fring
("fast ring") is a fast, lightweight circular buffer, designed
for embedded systems and other no_std targets. The memory footprint
is the buffer itself plus two usize
indices, and that's it. The
buffer allows a single producer and a single consumer, which may
operate concurrently. Memory safety and thread safety are enforced at
compile time; the buffer is lock-free at runtime. The buffer length
is required to be a power of two, and the only arithmetic operations
used by buffer operations are addition/subtraction and bitwise-and.
Compared to other Rust ring buffers (such as
bbqueue), fring
is
less flexible, but offers reduced storage and computational overhead.
lib.rs
:
Fast ring buffer intended for no_std targets.
fring
("fast ring") is a fast and lightweight circular buffer, designed
for embedded systems and other no_std targets. ("Circular buffer" means
it is a FIFO queue, stored as an array, and the data wraps back to the
beginning of the array once it reaches the end.) The memory footprint of
a fring::Buffer
is the buffer itself plus two usize
indices.
The buffer allows a single producer and a single consumer, which may operate concurrently. Memory safety and thread safety are enforced at compile time; the buffer is lock-free at runtime. The buffer length is required to be a power of two, and the only arithmetic operations used by buffer operations are addition/subtraction and bitwise and.
The only way to use a Buffer
is to split it into a Producer
and a
Consumer
. Then one may call Producer.write()
and Consumer.read()
,
or various other methods which are provided by Producer
and Consumer
.
Example of safe threaded use:
fn main() {
let mut buffer = fring::Buffer::<N>::new();
let (producer, consumer) = buffer.split();
std::thread::scope(|s| {
s.spawn(|| {
make_data(producer);
});
use_data(consumer);
});
}
Example of static use (requires unsafe
):
static BUFFER: fring::Buffer<N> = fring::Buffer::new();
fn interrupt_handler() {
// UNSAFE: this is safe because this is the only place we ever
// call BUFFER.producer(), and interrupt_handler() is not reentrant
let producer = unsafe { BUFFER.producer() };
write_data(producer);
}
fn main() {
// UNSAFE: this is safe because this is the only place we ever
// call BUFFER.consumer(), and main() is not reentrant
let consumer = unsafe { BUFFER.consumer() };
use_data(consumer);
}