Skip to content

Commit

Permalink
Add spinlock implementation without std::thread::sleep
Browse files Browse the repository at this point in the history
  • Loading branch information
white-axe committed Dec 21, 2023
1 parent fcf3849 commit e428500
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 10 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- `spin-plain` feature that switches the locking implementation to a plain spinlock without `std::thread::sleep`

### Removed

### Changed
Expand Down
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ exclude = [
[features]
# Use a spinlock internally (may be faster on some platforms)
spin = []
# Use a spinlock internally without `std::thread::sleep` (for platforms that don't support blocking)
spin-plain = []
select = []
async = ["futures-sink", "futures-core"]
eventual-fairness = ["select", "nanorand"]
Expand Down
26 changes: 16 additions & 10 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ use std::{
fmt,
};

#[cfg(feature = "spin")]
#[cfg(any(feature = "spin", feature = "spin-plain"))]
use spin1::{Mutex as Spinlock, MutexGuard as SpinlockGuard};
use crate::signal::{Signal, SyncSignal};

Expand Down Expand Up @@ -257,13 +257,13 @@ enum TryRecvTimeoutError {
}

// TODO: Investigate some sort of invalidation flag for timeouts
#[cfg(feature = "spin")]
#[cfg(any(feature = "spin", feature = "spin-plain"))]
struct Hook<T, S: ?Sized>(Option<Spinlock<Option<T>>>, S);

#[cfg(not(feature = "spin"))]
#[cfg(not(any(feature = "spin", feature = "spin-plain")))]
struct Hook<T, S: ?Sized>(Option<Mutex<Option<T>>>, S);

#[cfg(feature = "spin")]
#[cfg(any(feature = "spin", feature = "spin-plain"))]
impl<T, S: ?Sized + Signal> Hook<T, S> {
pub fn slot(msg: Option<T>, signal: S) -> Arc<Self>
where
Expand All @@ -277,7 +277,7 @@ impl<T, S: ?Sized + Signal> Hook<T, S> {
}
}

#[cfg(not(feature = "spin"))]
#[cfg(not(any(feature = "spin", feature = "spin-plain")))]
impl<T, S: ?Sized + Signal> Hook<T, S> {
pub fn slot(msg: Option<T>, signal: S) -> Arc<Self>
where
Expand Down Expand Up @@ -392,7 +392,7 @@ impl<T> Hook<T, SyncSignal> {
}
}

#[cfg(feature = "spin")]
#[cfg(all(feature = "spin", not(feature = "spin-plain")))]
#[inline]
fn wait_lock<T>(lock: &Spinlock<T>) -> SpinlockGuard<T> {
let mut i = 4;
Expand All @@ -409,18 +409,24 @@ fn wait_lock<T>(lock: &Spinlock<T>) -> SpinlockGuard<T> {
}
}

#[cfg(not(feature = "spin"))]
#[cfg(feature = "spin-plain")]
#[inline]
fn wait_lock<T>(lock: &Spinlock<T>) -> SpinlockGuard<T> {
lock.lock()
}

#[cfg(not(any(feature = "spin", feature = "spin-plain")))]
#[inline]
fn wait_lock<'a, T>(lock: &'a Mutex<T>) -> MutexGuard<'a, T> {
lock.lock().unwrap()
}

#[cfg(not(feature = "spin"))]
#[cfg(not(any(feature = "spin", feature = "spin-plain")))]
use std::sync::{Mutex, MutexGuard};

#[cfg(feature = "spin")]
#[cfg(any(feature = "spin", feature = "spin-plain"))]
type ChanLock<T> = Spinlock<T>;
#[cfg(not(feature = "spin"))]
#[cfg(not(any(feature = "spin", feature = "spin-plain")))]
type ChanLock<T> = Mutex<T>;


Expand Down

0 comments on commit e428500

Please sign in to comment.