Module heapless::mpmc[][src]

A fixed capacity Multiple-Producer Multiple-Consumer (MPMC) lock-free queue

NOTE: This module is not available on targets that do not support CAS operations, e.g. ARMv6-M

Example

This queue can be constructed in “const context”. Placing it in a static variable lets all contexts (interrupts / threads / main) safely enqueue and dequeue items from it.

#![no_main]
#![no_std]

use panic_semihosting as _;

use cortex_m::{asm, peripheral::syst::SystClkSource};
use cortex_m_rt::{entry, exception};
use cortex_m_semihosting::hprintln;
use heapless::mpmc::Q2;

static Q: Q2<u8> = Q2::new();

#[entry]
fn main() -> ! {
    if let Some(p) = cortex_m::Peripherals::take() {
        let mut syst = p.SYST;

        // configures the system timer to trigger a SysTick exception every second
        syst.set_clock_source(SystClkSource::Core);
        syst.set_reload(12_000_000);
        syst.enable_counter();
        syst.enable_interrupt();
    }

    loop {
        if let Some(x) = Q.dequeue() {
            hprintln!("{}", x).ok();
        } else {
            asm::wfi();
        }
    }
}

#[exception]
fn SysTick() {
    static mut COUNT: u8 = 0;

    Q.enqueue(*COUNT).ok();
    *COUNT += 1;
}

Benchmark

Measured on a ARM Cortex-M3 core running at 8 MHz and with zero Flash wait cycles

NQ8::<u8>::enqueue().ok() (z)Q8::<u8>::dequeue() (z)
03435
15253
26971

Portability

This module is not exposed to architectures that lack the instructions to implement CAS loops. Those architectures include ARMv6-M (thumbv6m-none-eabi) and MSP430 (msp430-none-elf).

References

This is an implementation of Dmitry Vyukov’s “Bounded MPMC queue” minus the cache padding.

Structs

Q2

MPMC queue with a capacity for 2 elements

Q4

MPMC queue with a capacity for 4 elements

Q8

MPMC queue with a capacity for 8 elements

Q16

MPMC queue with a capacity for 16 elements

Q32

MPMC queue with a capacity for 32 elements

Q64

MPMC queue with a capacity for 64 elements