Skip to content
A (WIP) SPSC, lockless, no_std, thread safe, queue, based on BipBuffers
Branch: master
Clone or download
Latest commit b1b07fc Mar 3, 2019
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
bbqtest Don't always print Feb 1, 2019
ci
core
.gitignore
.travis.yml Move tests to a shell script Jan 13, 2019
LICENSE-APACHE Add license files Jan 2, 2019
LICENSE-MIT Add license files Jan 2, 2019
README.md
tsan-blacklist.txt Always run tsan on nightly Jan 13, 2019

README.md

BBQueue

Documentation Testing

BBQueue, short for "BipBuffer Queue", is a (work in progress) Single Producer Single Consumer, lockless, no_std, thread safe, queue, based on BipBuffers. It is written in the Rust Programming Language.

It 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.

See The Documentation for more details

Using in a single threaded context

use bbqueue::{BBQueue, bbq};

fn main() {
    // Create a statically allocated instance
    let bbq = bbq!(1024).unwrap();

    // Obtain a write grant of size 128 bytes
    let mut wgr = bbq.grant(128).unwrap();

    // Fill the buffer with data
    wgr.copy_from_slice(&[0xAFu8; 128]);

    // Commit the write, to make the data available to be read
    bbq.commit(wgr.len(), wgr);

    // Obtain a read grant of all available and contiguous bytes
    let rgr = bbq.read().unwrap();

    for i in 0..128 {
        assert_eq!(rgr[i], 0xAFu8);
    }

    // Release the bytes, allowing the space
    // to be re-used for writing
    bbq.release(rgr.len(), rgr);
}

Using in a multi-threaded environment (or with interrupts, etc.)

use bbqueue::{BBQueue, bbq};
use std::thread::spawn;

fn main() {
    // Create a statically allocated instance
    let bbq = bbq!(1024).unwrap();
    let (mut tx, mut rx) = bbq.split();

    let txt = spawn(move || {
        for tx_i in 0..128 {
            'inner: loop {
                match tx.grant(4) {
                    Ok(mut gr) => {
                        gr.copy_from_slice(&[tx_i as u8; 4]);
                        tx.commit(4, gr);
                        break 'inner;
                    }
                    _ => {}
                }
            }
        }
    });

    let rxt = spawn(move || {
        for rx_i in 0..128 {
            'inner: loop {
                match rx.read() {
                    Ok(gr) => {
                        if gr.len() < 4 {
                            rx.release(0, gr);
                            continue 'inner;
                        }

                        assert_eq!(&gr[..4], &[rx_i as u8; 4]);
                        rx.release(4, gr);
                        break 'inner;
                    }
                    _ => {}
                }
            }
        }
    });

    txt.join().unwrap();
    rxt.join().unwrap();
}

The bbqueue crate is located in core/, and tests are located in bbqtest/.

Features

Feature Name On by default? Description
std No Enables convenience methods for allocating on the Heap, instead of statically
cortex-m No Provides a convenience macro for safely allocating in a critical section on Cortex-M devices

License

Licensed under either of

at your option.

Contribution

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.

You can’t perform that action at this time.