Crates.io | bbqueue-ng |
lib.rs | bbqueue-ng |
version | 0.101.1 |
source | src |
created_at | 2020-11-26 11:20:51.537067 |
updated_at | 2021-01-02 22:21:45.45502 |
description | A SPSC, lockless, no_std, thread safe, queue, based on BipBuffers |
homepage | |
repository | https://github.com/jamesmunns/bbqueue |
max_upload_size | |
id | 316666 |
size | 62,374 |
NOTE: This is the experimental next-generation version of bbqueue. This version generally doesn't respect semver, and may have incorrect documentation. If you want something more stable, use the regular version of bbqueue
!
BBQueue, short for "BipBuffer Queue", is a Single Producer Single Consumer, lockless, no_std, thread safe, queue, based on BipBuffers. For more info on the design of the lock-free algorithm used by bbqueue, see this blog post.
For a 90 minute guided tour of BBQueue, you can also view this guide on YouTube.
BBQueue is designed (primarily) to be a First-In, First-Out queue for use with DMA on embedded systems.
While Circular/Ring Buffers allow you to send data between two threads (or from an interrupt to main code), you must push the data one piece at a time. With BBQueue, you instead are granted a block of contiguous memory, which can be filled (or emptied) by a DMA engine.
// Create a buffer with six elements
let bb: BBBuffer<6> = BBBuffer::new();
let (mut prod, mut cons) = bb.try_split().unwrap();
// Request space for one byte
let mut wgr = prod.grant_exact(1).unwrap();
// Set the data
wgr[0] = 123;
assert_eq!(wgr.len(), 1);
// Make the data ready for consuming
wgr.commit(1);
// Read all available bytes
let rgr = cons.read().unwrap();
assert_eq!(rgr[0], 123);
// Release the space for later writes
rgr.release(1);
use bbqueue_ng::BBBuffer;
// Create a buffer with six elements
static BB: BBBuffer<6> = BBBuffer::new();
fn main() {
// Split the bbqueue into producer and consumer halves.
// These halves can be sent to different threads or to
// an interrupt handler for thread safe SPSC usage
let (mut prod, mut cons) = BB.try_split().unwrap();
// Request space for one byte
let mut wgr = prod.grant_exact(1).unwrap();
// Set the data
wgr[0] = 123;
assert_eq!(wgr.len(), 1);
// Make the data ready for consuming
wgr.commit(1);
// Read all available bytes
let rgr = cons.read().unwrap();
assert_eq!(rgr[0], 123);
// Release the space for later writes
rgr.release(1);
// The buffer cannot be split twice
assert!(BB.try_split().is_err());
}
By default BBQueue uses atomic operations which are available on most platforms. However on some (mostly embedded) platforms atomic support is limited and with the default features you will get a compiler error about missing atomic methods.
This crate contains special support for Cortex-M0(+) targets with the thumbv6
feature. By
enabling the feature, unsupported atomic operations will be replaced with critical sections
implemented by disabling interrupts. The critical sections are very short, a few instructions at
most, so they should make no difference to most applications.
Licensed under either of
Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.