Expand description
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);
}
Structs§
- Buffer
- A
Buffer<N>
consists of a[u8; N]
array along with twousize
indices into the array.N
must be a power of two. (If you need more flexibility with sizing, consider using abbqueue::BBBuffer
instead.) ABuffer<N>
can holdN
bytes of data and guarantees FIFO ordering. The only way to use aBuffer
is to split it into aProducer
and aConsumer
, which may then be passed to different threads or contexts. - Consumer
- A
Consumer
is a smart pointer to aBuffer
, which is endowed with the right to remove data from the buffer. Only oneConsumer
may exist at one time for any given buffer. The methods of aConsumer
are the only way to read data out of aBuffer
. - Producer
- A
Producer
is a smart pointer to aBuffer
, which is endowed with the right to add data into the buffer. Only oneProducer
may exist at one time for any given buffer. The methods of aProducer
are the only way to insert data into aBuffer
. - Region
- A
Region
is a smart pointer to a specific region of data in aBuffer
. TheRegion
derefs to[u8]
and may generally be used in the same way as a slice (e.g.region[i]
,region.len()
). When aRegion
is dropped, it updates the associatedBuffer
to indicate that this section of the buffer is finished being read or written. If aRegion
is forgotten instead of dropped, the buffer will not be updated and the same region will be re-issued by the next read/write.