[][src]Module heapless::mpmc

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.

This example is not tested
#![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
  • N denotes the number of interruptions. On Cortex-M, an interruption consists of an interrupt handler preempting the would-be atomic section of the enqueue / dequeue operation. Note that it does not matter if the higher priority handler uses the queue or not.
  • All execution times are in clock cycles. 1 clock cycle = 125 ns.
  • Execution time is dependent of mem::size_of::<T>(). Both operations include one memcpy(T) in their successful path.
  • The optimization level is indicated in parentheses.
  • The numbers reported correspond to the successful path (i.e. Some is returned by dequeue and Ok is returned by enqueue).

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