#线程安全 #队列 #无锁 #DMA #SPSC #缓冲区 #内存

无std bbqueue-sync

A SPSC, 无锁,无std,线程安全,基于 BipBuffers 的队列

1 个不稳定版本

0.5.1 2022年5月5日

#1653嵌入式开发

MIT/Apache

63KB
696 行代码(不包括注释)

BBQueue

Documentation

BBQueue,简称“双缓冲队列”,是一个单生产者单消费者、无锁、无std、线程安全的队列,基于 BipBuffers。有关 bbqueue 所使用的无锁算法的设计信息,请参阅 这篇博客文章

您还可以在 YouTube 上观看这个 BBQueue 导览(90 分钟)。

BBQueue 设计(主要)用于嵌入式系统上的 DMA 使用的先进先出队列。

虽然循环/环形缓冲区允许你在两个线程(或从中断到主代码)之间发送数据,但你必须逐个推送数据。使用 BBQueue,你将获得一段连续的内存块,该内存块可以由 DMA 引擎填充(或清空)。

本地使用

// 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::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());
}

“bbqueue”软件包位于 core/ 中,测试位于 bbqtest/

功能

默认情况下,BBQueue 使用大多数平台都有的原子操作。然而,在某些(主要是嵌入式)平台上,原子支持有限,并且在使用默认功能时,您将收到有关缺少原子方法的编译器错误。

许可证

许可协议为以下之一:

任选其一。

贡献

除非您明确说明,否则您提交的任何有意包含在作品中的贡献(根据 Apache-2.0 许可证定义),均应按上述方式双许可,不附加任何额外条款或条件。

依赖关系

~0–340KB