summaryrefslogtreecommitdiffstats
path: root/tokio/src/loom
diff options
context:
space:
mode:
authorDavid Kellum <dek-oss@gravitext.com>2020-01-24 10:02:19 -0800
committerCarl Lerche <me@carllerche.com>2020-01-24 10:02:19 -0800
commite35038ed79f31ed31050dbb4e16b8714014a63a4 (patch)
tree1537e27ccfb6161fef8958e82aaed8b10cde2f07 /tokio/src/loom
parentf9ddb93604a830d106475bd4c4cae436fafcc0da (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.rs21
-rw-r--r--tokio/src/loom/std/sync/pl_wrappers.rs79
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.
+}