hardware 0.0.9

A no_std bare-metal hardware abstraction layer — all port I/O, memory and swap allocations are guarded at runtime. Do not consider this dependency stable before x.1.x
Documentation
use super::command::Command;
use core::sync::atomic::{AtomicU16, Ordering};

const MAX_QUEUE_DEPTH: usize = 32;

pub struct CommandQueue {
    entries: [Option<Command>; MAX_QUEUE_DEPTH],
    head: usize,
    tail: usize,
    count: usize,
}

static INFLIGHT: AtomicU16 = AtomicU16::new(0);

impl Default for CommandQueue {
    fn default() -> Self {
        Self::new()
    }
}

impl CommandQueue {
    pub const fn new() -> Self {
        const NONE: Option<Command> = None;
        CommandQueue {
            entries: [NONE; MAX_QUEUE_DEPTH],
            head: 0,
            tail: 0,
            count: 0,
        }
    }

    pub fn submit(&mut self, cmd: Command) -> bool {
        if self.count >= MAX_QUEUE_DEPTH {
            return false;
        }
        self.entries[self.tail] = Some(cmd);
        self.tail = (self.tail + 1) % MAX_QUEUE_DEPTH;
        self.count += 1;
        INFLIGHT.fetch_add(1, Ordering::AcqRel);
        true
    }

    pub fn dequeue(&mut self) -> Option<Command> {
        if self.count == 0 {
            return None;
        }
        let cmd = self.entries[self.head].take();
        self.head = (self.head + 1) % MAX_QUEUE_DEPTH;
        self.count -= 1;
        if cmd.is_some() {
            INFLIGHT.fetch_sub(1, Ordering::AcqRel);
        }
        cmd
    }

    pub fn is_empty(&self) -> bool {
        self.count == 0
    }

    pub fn is_full(&self) -> bool {
        self.count >= MAX_QUEUE_DEPTH
    }

    pub fn depth(&self) -> usize {
        self.count
    }
}

pub fn inflight_count() -> u16 {
    INFLIGHT.load(Ordering::Acquire)
}