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. 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.
Example of 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 (no_std) use:
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
- A
Buffer<N>consists of a[u8; N]array along with twousizeindices into the array.Nmust be a power of two. (If you need more flexibility with sizing, consider using abbqueue::BBBufferinstead.) ABuffer<N>can holdNbytes of data and guarantees FIFO ordering. The only way to use aBufferis to split it into aProducerand aConsumer, which may then be passed to different threads or contexts. - A
Consumeris a smart pointer to aBuffer, which is endowed with the right to remove data from the buffer. Only oneConsumermay exist at one time for any given buffer. Requesting aReadRegionfrom aConsumeris the only way to read data out of aBuffer. - A
Produceris a smart pointer to aBuffer, which is endowed with the right to add data into the buffer. Only oneProducermay exist at one time for any given buffer. Requesting aWriteRegionfrom aProduceris the only way to insert data into aBuffer. - A
ReadRegionis a smart pointer to a specific region of data in aBuffer. TheReadRegionderefs to[u8]and may generally be used in the same way as a slice (e.g.r[i],r.len()). When aReadRegionis dropped, it updates the associatedBufferto indicate that the its memory region may now be overwritten. If aReadRegionis forgotten instead of dropped, the buffer will not be updated and its memory will be read again by the next read from the buffer. - A
WriteRegionis a smart pointer to a specific region of data in aBuffer. TheWriteRegionderefs to[u8]and may generally be used in the same way as a slice (e.g.w[i],w.len()). When aWriteRegionis dropped, it updates the associatedBufferto indicate that its memory region now contains data which is ready to be read. If aWriteRegionis forgotten instead of dropped, the buffer will not be updated and its memory will be overwritten by the next write to the buffer.