summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBotahamec <botahamec@outlook.com>2022-10-28 22:20:05 -0400
committerBotahamec <botahamec@outlook.com>2022-10-28 22:20:05 -0400
commit0b49b056981f4c5bcbdbb7fada1a8379e0793c86 (patch)
treef0f03db59a7286a421aafad31c062ed1edd64885 /src
parentd00df37bc92fccaa39e69bf886f9c8cd5522817b (diff)
Implemented SpinLock
Diffstat (limited to 'src')
-rw-r--r--src/lib.rs7
-rw-r--r--src/lock.rs7
-rw-r--r--src/mutex.rs33
3 files changed, 44 insertions, 3 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 615086d..2358ba2 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,6 +1,7 @@
#![warn(clippy::pedantic)]
#![warn(clippy::nursery)]
#![allow(clippy::module_name_repetitions)]
+#![allow(clippy::declare_interior_mutable_const)]
use std::any::type_name;
use std::fmt::{self, Debug};
@@ -10,11 +11,13 @@ use once_cell::sync::Lazy;
use thread_local::ThreadLocal;
mod lock;
-pub mod mutex;
+mod mutex;
use lock::{Key, Lock};
+use mutex::RawSpin;
-pub use mutex::Mutex;
+pub use mutex::{Mutex, MutexGuard};
+pub type SpinLock<T> = Mutex<RawSpin, T>;
static KEY: Lazy<ThreadLocal<Lock>> = Lazy::new(ThreadLocal::new);
diff --git a/src/lock.rs b/src/lock.rs
index c69ce21..101a061 100644
--- a/src/lock.rs
+++ b/src/lock.rs
@@ -38,6 +38,11 @@ impl Lock {
}
}
+ /// Checks whether this `Lock` is currently locked.
+ pub fn is_locked(&self) -> bool {
+ self.is_locked.load(Ordering::Relaxed)
+ }
+
/// Attempt to lock the `Lock`.
///
/// If the lock is already locked, then this'll return false. If it is
@@ -56,7 +61,7 @@ impl Lock {
///
/// This should only be called if the key to the lock has been "lost". That
/// means the program no longer has a reference to the key.
- unsafe fn force_unlock(&self) {
+ pub unsafe fn force_unlock(&self) {
self.is_locked.store(false, Ordering::Release);
}
diff --git a/src/mutex.rs b/src/mutex.rs
index a152eda..6c2e254 100644
--- a/src/mutex.rs
+++ b/src/mutex.rs
@@ -1,6 +1,7 @@
use std::cell::UnsafeCell;
use std::ops::{Deref, DerefMut};
+use crate::lock::Lock;
use crate::ThreadKey;
/// Implements a raw C-like mutex.
@@ -31,6 +32,38 @@ pub unsafe trait RawMutex {
unsafe fn unlock(&self);
}
+/// A raw mutex which just spins
+pub struct RawSpin {
+ lock: Lock,
+}
+
+unsafe impl RawMutex for RawSpin {
+ const INIT: Self = Self { lock: Lock::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()
+ }
+
+ fn is_locked(&self) -> bool {
+ self.lock.is_locked()
+ }
+
+ unsafe fn unlock(&self) {
+ self.lock.force_unlock();
+ }
+}
+
/// A mutual exclusion primitive useful for protecting shared data, which
/// cannot deadlock.
///