diff --git a/Cargo.toml b/Cargo.toml index 9c90185c32..f2ee362198 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -97,6 +97,7 @@ profiling = [] #TODO: remove when threading issues are fixed pti = [] drop_panic = [] +busy_panic = [] qemu_debug = [] serial_debug = [] system76_ec_debug = [] diff --git a/src/sync/ordered.rs b/src/sync/ordered.rs index 5734d8997a..2855680847 100644 --- a/src/sync/ordered.rs +++ b/src/sync/ordered.rs @@ -203,6 +203,9 @@ impl Default for Mutex { } } +#[cfg(feature = "busy_panic")] +const DEADLOCK_SPIN_CAP: usize = 1_000_000_000; + impl Mutex { /// Creates a new mutex in an unlocked state ready for use pub const fn new(val: T) -> Self { @@ -221,8 +224,25 @@ impl Mutex { &'a self, lock_token: LockToken<'a, LP>, ) -> MutexGuard<'a, L, T> { + #[cfg(feature = "busy_panic")] + let inner = { + let mut i = DEADLOCK_SPIN_CAP; + loop { + match self.inner.try_lock() { + Some(inner) => break inner, + None => { + i -= 1; + if i == 0 { + panic!("Deadlock may triggered") + } + } + } + } + }; + #[cfg(not(feature = "busy_panic"))] + let inner = self.inner.lock(); MutexGuard { - inner: self.inner.lock(), + inner, lock_token: LockToken::downgraded(lock_token), } } @@ -327,8 +347,25 @@ impl RwLock { &'a self, lock_token: LockToken<'a, LP>, ) -> RwLockWriteGuard<'a, L, T> { + #[cfg(feature = "busy_panic")] + let inner = { + let mut i = DEADLOCK_SPIN_CAP; + loop { + match self.inner.try_write() { + Some(inner) => break inner, + None => { + i -= 1; + if i == 0 { + panic!("Deadlock may triggered") + } + } + } + } + }; + #[cfg(not(feature = "busy_panic"))] + let inner = self.inner.write(); RwLockWriteGuard { - inner: self.inner.write(), + inner, lock_token: LockToken::downgraded(lock_token), } } @@ -346,8 +383,25 @@ impl RwLock { &'a self, lock_token: LockToken<'a, LP>, ) -> RwLockReadGuard<'a, L, T> { + #[cfg(feature = "busy_panic")] + let inner = { + let mut i = DEADLOCK_SPIN_CAP; + loop { + match self.inner.try_read() { + Some(inner) => break inner, + None => { + i -= 1; + if i == 0 { + panic!("Deadlock may triggered") + } + } + } + } + }; + #[cfg(not(feature = "busy_panic"))] + let inner = self.inner.read(); RwLockReadGuard { - inner: self.inner.read(), + inner, lock_token: LockToken::downgraded(lock_token), } }