Struct heapless::spsc::Queue

source ·
pub struct Queue<T, N, U = usize, C = MultiCore>where
    N: ArrayLength<T>,
    U: Uxx,
    C: XCore,
{ /* private fields */ }
Expand description

A statically allocated single producer single consumer queue with a capacity of N elements

IMPORTANT: To get better performance use a capacity that is a power of 2 (e.g. U16, U32, etc.).

By default spsc::Queue will use usize integers to hold the indices to its head and tail. For small queues usize indices may be overkill. However, spsc::Queue’s index type is generic and can be changed to u8 or u16 to reduce its footprint. The easiest to construct a spsc::Queue with a smaller index type is to use the u8 and u16 constructors.

IMPORTANT: spsc::Queue<_, _, u8> has a maximum capacity of 255 elements; spsc::Queue<_, _, u16> has a maximum capacity of 65535 elements.

spsc::Queue also comes in a single core variant. This variant can be created using the following constructors: u8_sc, u16_sc, usize_sc and new_sc. This variant is unsafe to create because the programmer must make sure that the queue’s consumer and producer endpoints (if split) are kept on a single core for their entire lifetime.

Examples

use heapless::spsc::Queue;
use heapless::consts::*;

let mut rb: Queue<u8, U4> = Queue::new();

assert!(rb.enqueue(0).is_ok());
assert!(rb.enqueue(1).is_ok());
assert!(rb.enqueue(2).is_ok());
assert!(rb.enqueue(3).is_ok());
assert!(rb.enqueue(4).is_err()); // full

assert_eq!(rb.dequeue(), Some(0));

Single producer single consumer mode

use heapless::spsc::Queue;
use heapless::consts::*;

// static mut RB: Queue<Event, U4> = Queue::new(); // requires feature `const-fn`

static mut RB: Option<Queue<Event, U4>>  = None;

enum Event { A, B }

fn main() {
    unsafe { RB = Some(Queue::new()) };
    // NOTE(unsafe) beware of aliasing the `consumer` end point
    let mut consumer = unsafe { RB.as_mut().unwrap().split().1 };

    loop {
        // `dequeue` is a lockless operation
        match consumer.dequeue() {
            Some(Event::A) => { /* .. */ },
            Some(Event::B) => { /* .. */ },
            None => { /* sleep */},
        }
    }
}

// this is a different execution context that can preempt `main`
fn interrupt_handler() {
    // NOTE(unsafe) beware of aliasing the `producer` end point
    let mut producer = unsafe { RB.as_mut().unwrap().split().0 };

    // ..

    if condition {
        producer.enqueue(Event::A).ok().unwrap();
    } else {
        producer.enqueue(Event::B).ok().unwrap();
    }

    // ..
}

Implementations§

Splits a statically allocated queue into producer and consumer end points

Returns the maximum number of elements the queue can hold

Returns true if the queue has a length of 0

Iterates from the front of the queue to the back

Returns an iterator that allows modifying each value.

Creates an empty queue with a fixed capacity of N

Creates an empty queue with a fixed capacity of N (single core variant)

Returns the item in the front of the queue, or None if the queue is empty

Adds an item to the end of the queue

Returns back the item if the queue is full

Adds an item to the end of the queue, without checking if it’s full

Unsafety

If the queue is full this operation will leak a value (T’s destructor won’t run on the value that got overwritten by item), and will allow the dequeue operation to create a copy of item, which could result in T’s destructor running on item twice.

Returns the number of elements in the queue

Trait Implementations§

Executes the destructor for this type. Read more
The type of the elements being iterated over.
Which kind of iterator are we turning this into?
Creates an iterator from a value. Read more
The type of the elements being iterated over.
Which kind of iterator are we turning this into?
Creates an iterator from a value. Read more

Auto Trait Implementations§

Blanket Implementations§

Gets the TypeId of self. Read more
Immutably borrows from an owned value. Read more
Mutably borrows from an owned value. Read more

Returns the argument unchanged.

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Should always be Self
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.