diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/key.rs | 25 | ||||
| -rw-r--r-- | src/lib.rs | 3 | ||||
| -rw-r--r-- | src/lockable.rs | 4 | ||||
| -rw-r--r-- | src/mutex.rs | 76 |
4 files changed, 22 insertions, 86 deletions
@@ -22,12 +22,6 @@ static KEY: Lazy<ThreadLocal<AtomicLock>> = Lazy::new(ThreadLocal::new); /// [`ThreadKey::lock`]. If the `ThreadKey` is dropped, it can be reobtained. pub type ThreadKey = Key<'static>; -/// A dumb lock that's just a wrapper for an [`AtomicBool`]. -#[derive(Debug, Default)] -pub struct AtomicLock { - is_locked: AtomicBool, -} - pub struct Key<'a> { phantom: PhantomData<*const ()>, // implement !Send and !Sync lock: &'a AtomicLock, @@ -76,20 +70,13 @@ impl ThreadKey { } } -impl AtomicLock { - /// Create a new unlocked `AtomicLock`. - #[must_use] - pub const fn new() -> Self { - Self { - is_locked: AtomicBool::new(false), - } - } - - /// Checks whether this `Lock` is currently locked. - pub fn is_locked(&self) -> bool { - self.is_locked.load(Ordering::Relaxed) - } +/// A dumb lock that's just a wrapper for an [`AtomicBool`]. +#[derive(Debug, Default)] +struct AtomicLock { + is_locked: AtomicBool, +} +impl AtomicLock { /// Attempt to lock the `AtomicLock`. /// /// If the lock is already locked, then this'll return false. If it is @@ -11,4 +11,5 @@ pub mod mutex; pub use guard::LockGuard; pub use key::{Key, ThreadKey}; pub use lockable::Lockable; -pub use mutex::Mutex; +pub use mutex::ParkingMutex as Mutex; +pub use mutex::SpinLock; diff --git a/src/lockable.rs b/src/lockable.rs index cda4e13..5e6d614 100644 --- a/src/lockable.rs +++ b/src/lockable.rs @@ -1,10 +1,12 @@ use std::mem::MaybeUninit; -use crate::mutex::{Mutex, MutexRef, RawMutex}; +use crate::mutex::{Mutex, MutexRef}; +use lock_api::RawMutex; mod sealed { #[allow(clippy::wildcard_imports)] use super::*; + pub trait Sealed {} impl<'a, T, R: RawMutex + 'a> Sealed for Mutex<T, R> {} impl<T: Sealed> Sealed for &T {} diff --git a/src/mutex.rs b/src/mutex.rs index 28e1786..f395055 100644 --- a/src/mutex.rs +++ b/src/mutex.rs @@ -1,72 +1,18 @@ use std::cell::UnsafeCell; use std::ops::{Deref, DerefMut}; -use crate::key::{AtomicLock, Keyable}; +use lock_api::RawMutex; -/// A spinning mutex -pub type SpinLock<T> = Mutex<T, RawSpin>; - -/// Implements a raw C-like mutex. -/// -/// # Safety -/// -/// It cannot be possible to lock the mutex when it is already locked. -pub unsafe trait RawMutex { - /// The initial value for an unlocked mutex - const INIT: Self; - - /// Lock the mutex, blocking until the lock is acquired - fn lock(&self); - - /// Attempt to lock the mutex without blocking. - /// - /// Returns `true` if successful, `false` otherwise. - fn try_lock(&self) -> bool; - - /// Checks whether the mutex is currently locked or not - fn is_locked(&self) -> bool; - - /// Unlock the mutex. - /// - /// # Safety - /// - /// The lock must be acquired in the current context. - unsafe fn unlock(&self); -} +use crate::key::Keyable; -/// A raw mutex which just spins -pub struct RawSpin { - lock: AtomicLock, -} - -unsafe impl RawMutex for RawSpin { - const INIT: Self = Self { - lock: AtomicLock::new(), - }; - - fn lock(&self) { - loop { - std::hint::spin_loop(); - - if let Some(key) = self.lock.try_lock() { - std::mem::forget(key); - return; - } - } - } - - fn try_lock(&self) -> bool { - self.lock.try_lock().is_some() - } +/// A spinning mutex +pub type SpinLock<T> = Mutex<T, spin::Mutex<()>>; - fn is_locked(&self) -> bool { - self.lock.is_locked() - } +/// A parking lot mutex +pub type ParkingMutex<T> = Mutex<T, parking_lot::RawMutex>; - unsafe fn unlock(&self) { - self.lock.force_unlock(); - } -} +/// A standard library mutex +pub type StdMutex<T> = Mutex<T, antidote::Mutex<()>>; /// A mutual exclusion primitive useful for protecting shared data, which /// cannot deadlock. @@ -82,7 +28,7 @@ unsafe impl RawMutex for RawSpin { /// /// [`lock`]: `Mutex::lock` /// [`try_lock`]: `Mutex::try_lock` -pub struct Mutex<T: ?Sized, R> { +pub struct Mutex<T: ?Sized, R: RawMutex> { raw: R, value: UnsafeCell<T>, } @@ -125,7 +71,7 @@ impl<'a, T: ?Sized + 'a, R: RawMutex> DerefMut for MutexRef<'a, T, R> { /// /// [`lock`]: `Mutex::lock` /// [`try_lock`]: `Mutex::try_lock` -pub struct MutexGuard<'a, T: ?Sized + 'a, Key: Keyable, R: RawMutex = RawSpin> { +pub struct MutexGuard<'a, T: ?Sized + 'a, Key: Keyable, R: RawMutex> { mutex: MutexRef<'a, T, R>, _thread_key: Key, } @@ -290,5 +236,5 @@ impl<T: ?Sized, R: RawMutex> Mutex<T, R> { } } -unsafe impl<R: Send, T: ?Sized + Send> Send for Mutex<T, R> {} +unsafe impl<R: RawMutex + Send, T: ?Sized + Send> Send for Mutex<T, R> {} unsafe impl<R: RawMutex + Sync, T: ?Sized + Send> Sync for Mutex<T, R> {} |
