Skip to content

Commit

Permalink
refact!: add 2nd relax param for barging mutex (#15)
Browse files Browse the repository at this point in the history
  • Loading branch information
pedromfedricci authored Jul 28, 2024
1 parent dbde0cc commit 51ac2c6
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 94 deletions.
2 changes: 1 addition & 1 deletion examples/barging.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::sync::Arc;
use std::thread;

// Requires that the `barging` feature is enabled.
use mcslock::barging::spins::Mutex;
use mcslock::barging::spins::backoff::Mutex;

fn main() {
const N: usize = 10;
Expand Down
39 changes: 22 additions & 17 deletions src/barging/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,16 @@
//! [`lock`] and [`try_lock`]. Guards are also accessible as the closure argument
//! for [`lock_with`] and [`try_lock_with`] methods.
//!
//! The Mutex is generic over the relax strategy. User may choose a strategy
//! as long as it implements the [`Relax`] trait. There is a number of strategies
//! provided by the [`relax`] module. Each submodule provides type aliases for
//! [`Mutex`] and [`MutexGuard`] associated with one relax strategy. See their
//! documentation for more information.
//! This Mutex is generic over the two layers of relax strategies. User may
//! choose a strategy as long as it implements the [`Relax`] trait. The shared
//! lock relax strategy is associated with the `Rs` generic paramater. The
//! handoff relax strategy is then associated with the `Rq` generic parameter.
//! Backoff relax strategies are usually prefered for shared lock contention,
//! while non-backoff relax strategies are usually prefered for handoffs.
//!
//! There is a number of strategies provided by the [`relax`] module. Each
//! submodule provides type aliases for [`Mutex`] and [`MutexGuard`] associated
//! with one relax strategy. See their documentation for more information.
//!
//! [lock_api]: https://crates.io/crates/lock_api
//! [`lock`]: Mutex::lock
Expand Down Expand Up @@ -47,17 +52,17 @@ pub mod spins {
/// let guard = mutex.lock();
/// assert_eq!(*guard, 0);
/// ```
pub type Mutex<T> = mutex::Mutex<T, Spin>;
pub type Mutex<T> = mutex::Mutex<T, Spin, Spin>;

/// A `barging` MCS guard that implements the [`Spin`] relax strategy.
pub type MutexGuard<'a, T> = mutex::MutexGuard<'a, T, Spin>;
pub type MutexGuard<'a, T> = mutex::MutexGuard<'a, T, Spin, Spin>;

/// A `barging` MCS lock alias that, during lock contention, will perform
/// exponential backoff while signaling the processor that it is running a
/// busy-wait spin-loop.
pub mod backoff {
use super::mutex;
use crate::relax::SpinBackoff;
use crate::relax::{Spin, SpinBackoff};

/// A `barging` MCS lock that implements the [`SpinBackoff`] relax
/// strategy.
Expand All @@ -71,11 +76,11 @@ pub mod spins {
/// let guard = mutex.lock();
/// assert_eq!(*guard, 0);
/// ```
pub type Mutex<T> = mutex::Mutex<T, SpinBackoff>;
pub type Mutex<T> = mutex::Mutex<T, SpinBackoff, Spin>;

/// A `barging` MCS guard that implements the [`SpinBackoff`] relax
/// strategy.
pub type MutexGuard<'a, T> = mutex::MutexGuard<'a, T, SpinBackoff>;
pub type MutexGuard<'a, T> = mutex::MutexGuard<'a, T, SpinBackoff, Spin>;
}
}

Expand All @@ -98,18 +103,18 @@ pub mod yields {
/// let guard = mutex.lock();
/// assert_eq!(*guard, 0);
/// ```
pub type Mutex<T> = mutex::Mutex<T, Yield>;
pub type Mutex<T> = mutex::Mutex<T, Yield, Yield>;

/// A `barging` MCS guard that implements the [`Yield`] relax strategy.
pub type MutexGuard<'a, T> = mutex::MutexGuard<'a, T, Yield>;
pub type MutexGuard<'a, T> = mutex::MutexGuard<'a, T, Yield, Yield>;

/// A `barging` MCS lock alias that, during lock contention, will perform
/// exponential backoff while spinning up to a threshold, then yields back
/// to the OS scheduler.
#[cfg(feature = "yield")]
pub mod backoff {
use super::mutex;
use crate::relax::YieldBackoff;
use crate::relax::{Yield, YieldBackoff};

/// A `barging` MCS lock that implements the [`YieldBackoff`] relax
/// strategy.
Expand All @@ -123,11 +128,11 @@ pub mod yields {
/// let guard = mutex.lock();
/// assert_eq!(*guard, 0);
/// ```
pub type Mutex<T> = mutex::Mutex<T, YieldBackoff>;
pub type Mutex<T> = mutex::Mutex<T, YieldBackoff, Yield>;

/// A `barging` MCS guard that implements the [`YieldBackoff`] relax
/// strategy.
pub type MutexGuard<'a, T> = mutex::MutexGuard<'a, T, YieldBackoff>;
pub type MutexGuard<'a, T> = mutex::MutexGuard<'a, T, YieldBackoff, Yield>;
}
}

Expand All @@ -148,8 +153,8 @@ pub mod loops {
/// let guard = mutex.lock();
/// assert_eq!(*guard, 0);
/// ```
pub type Mutex<T> = mutex::Mutex<T, Loop>;
pub type Mutex<T> = mutex::Mutex<T, Loop, Loop>;

/// A `barging` MCS guard that implements the [`Loop`] relax strategy.
pub type MutexGuard<'a, T> = mutex::MutexGuard<'a, T, Loop>;
pub type MutexGuard<'a, T> = mutex::MutexGuard<'a, T, Loop, Loop>;
}
Loading

0 comments on commit 51ac2c6

Please sign in to comment.