#![no_std]
mod arch;
#[crate_interface::def_interface]
pub trait KernelGuardIf {
fn enable_preempt();
fn disable_preempt();
}
pub trait BaseGuard {
type State: Clone + Copy;
fn acquire() -> Self::State;
fn release(state: Self::State);
}
pub struct NoOp;
cfg_if::cfg_if! {
if #[cfg(any(target_os = "none", doc))] {
pub struct IrqSave(usize);
pub struct NoPreempt;
pub struct NoPreemptIrqSave(usize);
} else {
pub type IrqSave = NoOp;
pub type NoPreempt = NoOp;
pub type NoPreemptIrqSave = NoOp;
}
}
impl BaseGuard for NoOp {
type State = ();
fn acquire() -> Self::State {}
fn release(_state: Self::State) {}
}
impl NoOp {
pub const fn new() -> Self {
Self
}
}
impl Drop for NoOp {
fn drop(&mut self) {}
}
#[cfg(any(target_os = "none", doc))]
mod imp {
use super::*;
impl BaseGuard for IrqSave {
type State = usize;
#[inline]
fn acquire() -> Self::State {
super::arch::local_irq_save_and_disable()
}
#[inline]
fn release(state: Self::State) {
super::arch::local_irq_restore(state);
}
}
impl BaseGuard for NoPreempt {
type State = ();
fn acquire() -> Self::State {
#[cfg(feature = "preempt")]
crate_interface::call_interface!(KernelGuardIf::disable_preempt);
}
fn release(_state: Self::State) {
#[cfg(feature = "preempt")]
crate_interface::call_interface!(KernelGuardIf::enable_preempt);
}
}
impl BaseGuard for NoPreemptIrqSave {
type State = usize;
fn acquire() -> Self::State {
#[cfg(feature = "preempt")]
crate_interface::call_interface!(KernelGuardIf::disable_preempt);
super::arch::local_irq_save_and_disable()
}
fn release(state: Self::State) {
super::arch::local_irq_restore(state);
#[cfg(feature = "preempt")]
crate_interface::call_interface!(KernelGuardIf::enable_preempt);
}
}
impl IrqSave {
pub fn new() -> Self {
Self(Self::acquire())
}
}
impl Drop for IrqSave {
fn drop(&mut self) {
Self::release(self.0)
}
}
impl Default for IrqSave {
fn default() -> Self {
Self::new()
}
}
impl NoPreempt {
pub fn new() -> Self {
Self::acquire();
Self
}
}
impl Drop for NoPreempt {
fn drop(&mut self) {
Self::release(())
}
}
impl Default for NoPreempt {
fn default() -> Self {
Self::new()
}
}
impl NoPreemptIrqSave {
pub fn new() -> Self {
Self(Self::acquire())
}
}
impl Drop for NoPreemptIrqSave {
fn drop(&mut self) {
Self::release(self.0)
}
}
impl Default for NoPreemptIrqSave {
fn default() -> Self {
Self::new()
}
}
}