summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/key.rs25
-rw-r--r--src/lib.rs3
-rw-r--r--src/lockable.rs4
-rw-r--r--src/mutex.rs76
4 files changed, 22 insertions, 86 deletions
diff --git a/src/key.rs b/src/key.rs
index 92f3b99..0297bc1 100644
--- a/src/key.rs
+++ b/src/key.rs
@@ -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
diff --git a/src/lib.rs b/src/lib.rs
index 35f7bb4..3e09572 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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> {}