diff options
author | David Kellum <dek-oss@gravitext.com> | 2020-01-24 10:02:19 -0800 |
---|---|---|
committer | Carl Lerche <me@carllerche.com> | 2020-01-24 10:02:19 -0800 |
commit | e35038ed79f31ed31050dbb4e16b8714014a63a4 (patch) | |
tree | 1537e27ccfb6161fef8958e82aaed8b10cde2f07 /tokio/src/loom | |
parent | f9ddb93604a830d106475bd4c4cae436fafcc0da (diff) |
rt: add feature flag for using `parking_lot` internally (#2164)
`parking_lot` provides synchronization primitives that tend to be
more efficient than the ones in `std`. However, depending on
`parking_lot` pulls in a number of dependencies resulting
in additional compilation time.
Adding *optional* support for `parking_lot` allows the end user
to opt-in when the trade offs make sense for their case.
Diffstat (limited to 'tokio/src/loom')
-rw-r--r-- | tokio/src/loom/std/mod.rs | 21 | ||||
-rw-r--r-- | tokio/src/loom/std/sync/pl_wrappers.rs | 79 |
2 files changed, 99 insertions, 1 deletions
diff --git a/tokio/src/loom/std/mod.rs b/tokio/src/loom/std/mod.rs index e6faa3b1..d5e057e5 100644 --- a/tokio/src/loom/std/mod.rs +++ b/tokio/src/loom/std/mod.rs @@ -38,7 +38,26 @@ pub(crate) mod rand { } pub(crate) mod sync { - pub(crate) use std::sync::*; + pub(crate) use std::sync::Arc; + + #[cfg(feature = "parking_lot")] + mod pl_wrappers; + + // Below, make sure all the feature-influenced types are exported for + // internal use. Note however that some are not _currently_ named by + // consuming code. + + #[cfg(feature = "parking_lot")] + #[allow(unused_imports)] + pub(crate) use pl_wrappers::{Condvar, Mutex}; + + #[cfg(feature = "parking_lot")] + #[allow(unused_imports)] + pub(crate) use parking_lot::{MutexGuard, WaitTimeoutResult}; + + #[cfg(not(feature = "parking_lot"))] + #[allow(unused_imports)] + pub(crate) use std::sync::{Condvar, Mutex, MutexGuard, WaitTimeoutResult}; pub(crate) mod atomic { pub(crate) use crate::loom::std::atomic_u32::AtomicU32; diff --git a/tokio/src/loom/std/sync/pl_wrappers.rs b/tokio/src/loom/std/sync/pl_wrappers.rs new file mode 100644 index 00000000..3be8ba1c --- /dev/null +++ b/tokio/src/loom/std/sync/pl_wrappers.rs @@ -0,0 +1,79 @@ +//! A minimal adaption of the `parking_lot` synchronization primitives to the +//! equivalent `std::sync` types. +//! +//! This can be extended to additional types/methods as required. + +use std::sync::{LockResult, TryLockError, TryLockResult}; +use std::time::Duration; + +use parking_lot as pl; + +/// Adapter for `parking_lot::Mutex` to the `std::sync::Mutex` interface. +#[derive(Debug)] +pub(crate) struct Mutex<T: ?Sized>(pl::Mutex<T>); + +impl<T> Mutex<T> { + #[inline] + pub(crate) fn new(t: T) -> Mutex<T> { + Mutex(pl::Mutex::new(t)) + } + + #[inline] + pub(crate) fn lock(&self) -> LockResult<pl::MutexGuard<'_, T>> { + Ok(self.0.lock()) + } + + #[inline] + pub(crate) fn try_lock(&self) -> TryLockResult<pl::MutexGuard<'_, T>> { + match self.0.try_lock() { + Some(guard) => Ok(guard), + None => Err(TryLockError::WouldBlock), + } + } + + // Note: Additional methods `is_poisoned` and `into_inner`, can be + // provided here as needed. +} + +/// Adapter for `parking_lot::Condvar` to the `std::sync::Condvar` interface. +#[derive(Debug)] +pub(crate) struct Condvar(pl::Condvar); + +impl Condvar { + #[inline] + pub(crate) fn new() -> Condvar { + Condvar(pl::Condvar::new()) + } + + #[inline] + pub(crate) fn notify_one(&self) { + self.0.notify_one(); + } + + #[inline] + pub(crate) fn notify_all(&self) { + self.0.notify_all(); + } + + #[inline] + pub(crate) fn wait<'a, T>( + &self, + mut guard: pl::MutexGuard<'a, T>, + ) -> LockResult<pl::MutexGuard<'a, T>> { + self.0.wait(&mut guard); + Ok(guard) + } + + #[inline] + pub(crate) fn wait_timeout<'a, T>( + &self, + mut guard: pl::MutexGuard<'a, T>, + timeout: Duration, + ) -> LockResult<(pl::MutexGuard<'a, T>, pl::WaitTimeoutResult)> { + let wtr = self.0.wait_for(&mut guard, timeout); + Ok((guard, wtr)) + } + + // Note: Additional methods `wait_timeout_ms`, `wait_timeout_until`, + // `wait_until` can be provided here as needed. +} |