diff --git a/kernel/src/drivers/net/router.rs b/kernel/src/drivers/net/router.rs index 3824522..9621644 100644 --- a/kernel/src/drivers/net/router.rs +++ b/kernel/src/drivers/net/router.rs @@ -18,7 +18,7 @@ use crate::net::SOCKETS; use crate::sync::SpinNoIrqLock as Mutex; use super::super::{DeviceType, Driver, DRIVERS, NET_DRIVERS, SOCKET_ACTIVITY}; -use crate::consts::{KERNEL_OFFSET, MEMORY_END, MEMORY_OFFSET}; +use crate::consts::{KERNEL_OFFSET, MEMORY_OFFSET}; const AXI_STREAM_FIFO_ISR: *mut u32 = (KERNEL_OFFSET + 0x1820_0000) as *mut u32; const AXI_STREAM_FIFO_IER: *mut u32 = (KERNEL_OFFSET + 0x1820_0004) as *mut u32; diff --git a/kernel/src/sync/mutex.rs b/kernel/src/sync/mutex.rs index 8af1460..623bac5 100644 --- a/kernel/src/sync/mutex.rs +++ b/kernel/src/sync/mutex.rs @@ -28,6 +28,7 @@ use super::Condvar; use crate::arch::interrupt; +use crate::processor; use core::cell::UnsafeCell; use core::fmt; use core::ops::{Deref, DerefMut}; @@ -35,11 +36,12 @@ use core::sync::atomic::{AtomicBool, Ordering}; pub type SpinLock = Mutex; pub type SpinNoIrqLock = Mutex; -pub type ThreadLock = Mutex; +pub type SleepLock = Mutex; pub struct Mutex { lock: AtomicBool, support: S, + user: UnsafeCell<(usize, usize)>, // (cid, tid) data: UnsafeCell, } @@ -78,6 +80,7 @@ impl Mutex { lock: AtomicBool::new(false), data: UnsafeCell::new(user_data), support: S::new(), + user: UnsafeCell::new((0, 0)), } } @@ -93,11 +96,23 @@ impl Mutex { impl Mutex { fn obtain_lock(&self) { while self.lock.compare_and_swap(false, true, Ordering::Acquire) != false { + let mut try_count = 0; // Wait until the lock looks unlocked before retrying while self.lock.load(Ordering::Relaxed) { self.support.cpu_relax(); + try_count += 1; + if try_count == 0x100000 { + let (cid, tid) = unsafe { *self.user.get() }; + error!( + "Mutex: deadlock detected! locked by cpu {} thread {} @ {:?}", + cid, tid, self as *const Self + ); + } } } + let cid = crate::arch::cpu::id(); + let tid = processor().tid_option().unwrap_or(0); + unsafe { self.user.get().write((cid, tid)) }; } /// Locks the spinlock and returns a guard. diff --git a/kernel/src/sync/test.rs b/kernel/src/sync/test.rs index 3b7e1c7..76196e8 100644 --- a/kernel/src/sync/test.rs +++ b/kernel/src/sync/test.rs @@ -3,7 +3,7 @@ //! The code is borrowed from [RustDoc - Dining Philosophers](https://doc.rust-lang.org/1.6.0/book/dining-philosophers.html) use crate::sync::Condvar; -use crate::sync::ThreadLock as Mutex; +use crate::sync::SleepLock as Mutex; use crate::thread; use alloc::vec; use alloc::{sync::Arc, vec::Vec};