From 73b4c8b1af4c7da79048a50290f39571e05acd71 Mon Sep 17 00:00:00 2001 From: Bert Peters Date: Thu, 27 May 2021 21:04:49 +0200 Subject: [PATCH] Minimal parking_lot support --- Cargo.toml | 2 ++ src/lib.rs | 4 ++++ src/parkinglot.rs | 58 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+) create mode 100644 src/parkinglot.rs diff --git a/Cargo.toml b/Cargo.toml index 1182071..d48a6b4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,6 +14,7 @@ repository = "https://github.com/bertptrs/tracing-mutex" [dependencies] lazy_static = "1" lock_api = { version = "0.4", optional = true } +parking_lot = { version = "0.11", optional = true } [dev-dependencies] rand = "0.8" @@ -21,3 +22,4 @@ rand = "0.8" [features] # Feature names do not match crate names pending namespaced features. lockapi = ["lock_api"] +parkinglot = ["parking_lot", "lockapi"] diff --git a/src/lib.rs b/src/lib.rs index 64ded52..71c049e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -62,12 +62,16 @@ use std::sync::PoisonError; use lazy_static::lazy_static; #[cfg(feature = "lockapi")] pub use lock_api; +#[cfg(feature = "parkinglot")] +pub use parking_lot; use crate::graph::DiGraph; mod graph; #[cfg(feature = "lockapi")] pub mod lockapi; +#[cfg(feature = "lockapi")] +pub mod parkinglot; pub mod stdsync; /// Counter for Mutex IDs. Atomic avoids the need for locking. diff --git a/src/parkinglot.rs b/src/parkinglot.rs new file mode 100644 index 0000000..c02e0ea --- /dev/null +++ b/src/parkinglot.rs @@ -0,0 +1,58 @@ +use crate::lockapi::TracingWrapper; + +macro_rules! create_mutex_wrapper { + ($wrapped:ty, $tracing_name:ident, $debug_name:ident) => { + pub type $tracing_name = lock_api::Mutex, T>; + + #[cfg(debug_assertions)] + pub type $debug_name = $tracing_name; + #[cfg(not(debug_assertions))] + pub type $debug_name = lock_api::Mutex<$wrapped, T>; + }; +} + +create_mutex_wrapper!(parking_lot::RawFairMutex, TracingFairMutex, DebugFairMutex); +create_mutex_wrapper!(parking_lot::RawMutex, TracingMutex, DebugMutex); + +pub type TracingReentrantMutex = + lock_api::ReentrantMutex, parking_lot::RawThreadId, T>; +#[cfg(debug_assertions)] +pub type DebugReentrantMutex = TracingReentrantMutex; +#[cfg(not(debug_assertions))] +pub type DebugReentrantMutex = parking_lot::ReentrantMutex; + +#[cfg(test)] +mod tests { + use std::sync::Arc; + use std::thread; + + use super::*; + + #[test] + fn test_mutex_usage() { + let mutex = Arc::new(TracingMutex::new(())); + let local_lock = mutex.lock(); + drop(local_lock); + + thread::spawn(move || { + let _remote_lock = mutex.lock(); + }) + .join() + .unwrap(); + } + + #[test] + #[should_panic] + fn test_mutex_conflict() { + let mutexes = [ + TracingMutex::new(()), + TracingMutex::new(()), + TracingMutex::new(()), + ]; + + for i in 0..3 { + let _first_lock = mutexes[i].lock(); + let _second_lock = mutexes[(i + 1) % 3].lock(); + } + } +}