Skip to content

Commit

Permalink
Merge pull request #13 from hermit-os/still
Browse files Browse the repository at this point in the history
feat: add one-shot mutex
  • Loading branch information
mkroening authored Apr 4, 2024
2 parents 2359fca + 59f3051 commit 820af24
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 12 deletions.
4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@ generic_once_cell = "0.1"
interrupts = "0.1"
interrupt-mutex = "0.1"
lock_api = "0.4"
one-shot-mutex = "0.1.1"
spinning_top = "0.3"

[dev-dependencies]
rand = "0.8"

[features]
all-one-shot = []
41 changes: 29 additions & 12 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,17 +70,20 @@
//!
//! This crate provides a lot of type definitions for ease of use:
//!
//! | [`RawMutex`] | Base | With [`RawInterruptMutex`] |
//! | ------------------ | -------------------- | ----------------------------- |
//! | `R` | [`Mutex`] | [`InterruptMutex`] |
//! | [`RawSpinMutex`] | | [`RawInterruptSpinMutex`] |
//! | | [`SpinMutex`] | [`InterruptSpinMutex`] |
//! | | [`SpinMutexGuard`] | [`InterruptSpinMutexGuard`] |
//! | | [`OnceCell`] | [`InterruptOnceCell`] |
//! | | [`Lazy`] | [`InterruptLazy`] |
//! | [`RawTicketMutex`] | | [`RawInterruptTicketMutex`] |
//! | | [`TicketMutex`] | [`InterruptTicketMutex`] |
//! | | [`TicketMutexGuard`] | [`InterruptTicketMutexGuard`] |
//! | [`RawMutex`] | Base | With [`RawInterruptMutex`] |
//! | ------------------- | --------------------- | ------------------------------ |
//! | `R` | [`Mutex`] | [`InterruptMutex`] |
//! | [`RawSpinMutex`] | | [`RawInterruptSpinMutex`] |
//! | | [`SpinMutex`] | [`InterruptSpinMutex`] |
//! | | [`SpinMutexGuard`] | [`InterruptSpinMutexGuard`] |
//! | | [`OnceCell`] | [`InterruptOnceCell`] |
//! | | [`Lazy`] | [`InterruptLazy`] |
//! | [`RawOneShotMutex`] | | [`RawInterruptOneShotMutex`] |
//! | | [`OneShotMutex`] | [`InterruptOneShotMutex`] |
//! | | [`OneShotMutexGuard`] | [`InterruptOneShotMutexGuard`] |
//! | [`RawTicketMutex`] | | [`RawInterruptTicketMutex`] |
//! | | [`TicketMutex`] | [`InterruptTicketMutex`] |
//! | | [`TicketMutexGuard`] | [`InterruptTicketMutexGuard`] |
//!
//! [`RawMutex`]: lock_api::RawMutex
//! [`Mutex`]: lock_api::Mutex
Expand All @@ -89,6 +92,7 @@
#![warn(unsafe_op_in_unsafe_fn)]

pub(crate) mod mutex;
#[cfg(not(feature = "all-one-shot"))]
pub(crate) mod rwlock {
/// A simple spinning, read-preferring readers-writer lock with exponential backoff.
pub type RawRwSpinLock = spinning_top::RawRwSpinlock<spinning_top::relax::Backoff>;
Expand All @@ -106,16 +110,29 @@ pub(crate) mod rwlock {
/// A [`lock_api::RwLockWriteGuard`] based on [`RawRwSpinLock`].
pub type RwSpinLockWriteGuard<'a, T> = lock_api::RwLockWriteGuard<'a, RawRwSpinLock, T>;
}
#[cfg(feature = "all-one-shot")]
pub(crate) mod rwlock {
pub use one_shot_mutex::{
OneShotRwLock as RwSpinLock, OneShotRwLockReadGuard as RwSpinLockReadGuard,
OneShotRwLockUpgradableReadGuard as RwSpinLockUpgradableReadGuard,
OneShotRwLockWriteGuard as RwSpinLockWriteGuard, RawOneShotRwLock as RawRwSpinLock,
};
}

pub use exclusive_cell::{CallOnce, CallOnceError, ExclusiveCell};
pub use interrupt_mutex::{InterruptMutex, InterruptMutexGuard, RawInterruptMutex};
pub use interrupts::without as without_interrupts;
pub use mutex::spin::{RawSpinMutex, SpinMutex, SpinMutexGuard};
pub use mutex::ticket::{RawTicketMutex, TicketMutex, TicketMutexGuard};
pub use mutex::{
InterruptSpinMutex, InterruptSpinMutexGuard, InterruptTicketMutex, InterruptTicketMutexGuard,
InterruptOneShotMutex, InterruptOneShotMutexGuard, InterruptSpinMutex, InterruptSpinMutexGuard,
InterruptTicketMutex, InterruptTicketMutexGuard, RawInterruptOneShotMutex,
RawInterruptSpinMutex, RawInterruptTicketMutex,
};
pub use one_shot_mutex::{
OneShotMutex, OneShotMutexGuard, OneShotRwLock, OneShotRwLockReadGuard,
OneShotRwLockUpgradableReadGuard, OneShotRwLockWriteGuard, RawOneShotMutex, RawOneShotRwLock,
};
pub use rwlock::{
RawRwSpinLock, RwSpinLock, RwSpinLockReadGuard, RwSpinLockUpgradableReadGuard,
RwSpinLockWriteGuard,
Expand Down
26 changes: 26 additions & 0 deletions src/mutex/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#[cfg(not(feature = "all-one-shot"))]
pub(crate) mod spin {
/// A simple spinlock with exponential backoff.
pub type RawSpinMutex = spinning_top::RawSpinlock<spinning_top::relax::Backoff>;
Expand All @@ -8,12 +9,37 @@ pub(crate) mod spin {
/// A [`lock_api::MutexGuard`] based on [`RawSpinMutex`].
pub type SpinMutexGuard<'a, T> = lock_api::MutexGuard<'a, RawSpinMutex, T>;
}
#[cfg(feature = "all-one-shot")]
pub(crate) mod spin {
pub use one_shot_mutex::{
OneShotMutex as SpinMutex, OneShotMutexGuard as SpinMutexGuard,
RawOneShotMutex as RawSpinMutex,
};
}
#[cfg(not(feature = "all-one-shot"))]
pub(crate) mod ticket;
#[cfg(feature = "all-one-shot")]
pub(crate) mod ticket {
pub use one_shot_mutex::{
OneShotMutex as TicketMutex, OneShotMutexGuard as TicketMutexGuard,
RawOneShotMutex as RawTicketMutex,
};
}

use interrupt_mutex::RawInterruptMutex;
use one_shot_mutex::RawOneShotMutex;
use spin::RawSpinMutex;
use ticket::RawTicketMutex;

/// An interrupt-safe [`RawOneShotMutex`].
pub type RawInterruptOneShotMutex = RawInterruptMutex<RawOneShotMutex>;

/// A [`lock_api::Mutex`] based on [`RawInterruptOneShotMutex`].
pub type InterruptOneShotMutex<T> = lock_api::Mutex<RawInterruptOneShotMutex, T>;

/// A [`lock_api::MutexGuard`] based on [`RawInterruptOneShotMutex`].
pub type InterruptOneShotMutexGuard<'a, T> = lock_api::MutexGuard<'a, RawInterruptOneShotMutex, T>;

/// An interrupt-safe [`RawSpinMutex`].
pub type RawInterruptSpinMutex = RawInterruptMutex<RawSpinMutex>;

Expand Down

0 comments on commit 820af24

Please sign in to comment.