pub mod arceos {
pub use ax_api as api;
pub mod guard {
pub use ax_runtime::sync::{IrqSaveGuard, PreemptGuard, PreemptIrqSaveGuard};
}
#[doc(no_inline)]
pub use ax_api::modules;
#[doc(no_inline)]
pub use ax_driver as driver;
#[doc(no_inline)]
pub use ax_percpu as percpu;
pub mod sync {
pub use ax_runtime::sync::*;
#[repr(transparent)]
pub struct IrqSafeMutex<T: ?Sized>(SpinLock<T>);
impl<T> IrqSafeMutex<T> {
#[track_caller]
pub const fn new(value: T) -> Self {
Self(SpinLock::new(value))
}
#[track_caller]
pub fn lock(&self) -> IrqSafeMutexGuard<'_, T> {
self.0.lock_irqsave()
}
#[track_caller]
pub fn try_lock(&self) -> Option<IrqSafeMutexGuard<'_, T>> {
self.0.try_lock_irqsave()
}
}
impl<T: Default> Default for IrqSafeMutex<T> {
fn default() -> Self {
Self::new(T::default())
}
}
impl<T: core::fmt::Debug> core::fmt::Debug for IrqSafeMutex<T> {
fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
self.0.fmt(formatter)
}
}
pub type IrqSafeMutexGuard<'a, T> = SpinLockIrqSaveGuard<'a, T>;
pub type NoPreemptMutex<T> = SpinLock<T>;
pub type NoPreemptMutexGuard<'a, T> = SpinLockGuard<'a, T>;
pub type RawSpinLock<T> = SpinLock<T>;
}
}
#[cfg(feature = "std-compat")]
pub mod libc_compat;
#[cfg(all(test, feature = "host-test"))]
mod tests {
use super::arceos::sync::{IrqSafeMutex, NoPreemptMutex, RawSpinLock};
static IRQ_SAFE: IrqSafeMutex<usize> = IrqSafeMutex::new(0);
static NO_PREEMPT: NoPreemptMutex<usize> = NoPreemptMutex::new(0);
static RAW: RawSpinLock<usize> = RawSpinLock::new(0);
#[test]
fn special_locks_support_const_initialization_and_try_lock() {
*IRQ_SAFE.lock() += 1;
*NO_PREEMPT.lock() += 1;
*unsafe { RAW.lock_raw() } += 1;
assert_eq!(*IRQ_SAFE.try_lock().unwrap(), 1);
assert_eq!(*NO_PREEMPT.try_lock().unwrap(), 1);
assert_eq!(*unsafe { RAW.try_lock_raw() }.unwrap(), 1);
}
}