mirror of
https://github.com/RGBCube/serenity
synced 2025-07-24 22:17:42 +00:00
Kernel: Show more (b)locking info when dumping the process list
This commit is contained in:
parent
47af812a23
commit
2bf5052608
2 changed files with 49 additions and 5 deletions
|
@ -564,6 +564,17 @@ void dump_thread_list(bool with_stack_traces)
|
||||||
thread.times_scheduled());
|
thread.times_scheduled());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (thread.state() == Thread::State::Blocked && thread.blocking_mutex()) {
|
||||||
|
dmesgln(" Blocking on Mutex {:#x} ({})", thread.blocking_mutex(), thread.blocking_mutex()->name());
|
||||||
|
}
|
||||||
|
if (thread.state() == Thread::State::Blocked && thread.blocker()) {
|
||||||
|
dmesgln(" Blocking on Blocker {:#x}", thread.blocker());
|
||||||
|
}
|
||||||
|
#if LOCK_DEBUG
|
||||||
|
thread.for_each_held_lock([](auto const& entry) {
|
||||||
|
dmesgln(" Holding lock {:#x} ({}) at {}", entry.lock, entry.lock->name(), entry.lock_location);
|
||||||
|
});
|
||||||
|
#endif
|
||||||
if (with_stack_traces) {
|
if (with_stack_traces) {
|
||||||
auto trace_or_error = thread.backtrace();
|
auto trace_or_error = thread.backtrace();
|
||||||
if (!trace_or_error.is_error()) {
|
if (!trace_or_error.is_error()) {
|
||||||
|
|
|
@ -1154,6 +1154,22 @@ public:
|
||||||
|
|
||||||
ErrorOr<NonnullOwnPtr<KString>> backtrace();
|
ErrorOr<NonnullOwnPtr<KString>> backtrace();
|
||||||
|
|
||||||
|
Blocker const* blocker() const { return m_blocker; };
|
||||||
|
Kernel::Mutex const* blocking_mutex() const { return m_blocking_mutex; }
|
||||||
|
|
||||||
|
#if LOCK_DEBUG
|
||||||
|
struct HoldingLockInfo {
|
||||||
|
Mutex* lock;
|
||||||
|
LockLocation lock_location;
|
||||||
|
unsigned count;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<IteratorFunction<HoldingLockInfo const&> Callback>
|
||||||
|
void for_each_held_lock(Callback);
|
||||||
|
template<VoidFunction<HoldingLockInfo const&> Callback>
|
||||||
|
void for_each_held_lock(Callback);
|
||||||
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Thread(NonnullLockRefPtr<Process>, NonnullOwnPtr<Memory::Region>, NonnullLockRefPtr<Timer>, NonnullOwnPtr<KString>);
|
Thread(NonnullLockRefPtr<Process>, NonnullOwnPtr<Memory::Region>, NonnullLockRefPtr<Timer>, NonnullOwnPtr<KString>);
|
||||||
|
|
||||||
|
@ -1266,11 +1282,6 @@ private:
|
||||||
IntrusiveListNode<Thread> m_big_lock_blocked_threads_list_node;
|
IntrusiveListNode<Thread> m_big_lock_blocked_threads_list_node;
|
||||||
|
|
||||||
#if LOCK_DEBUG
|
#if LOCK_DEBUG
|
||||||
struct HoldingLockInfo {
|
|
||||||
Mutex* lock;
|
|
||||||
LockLocation lock_location;
|
|
||||||
unsigned count;
|
|
||||||
};
|
|
||||||
Atomic<u32> m_holding_locks { 0 };
|
Atomic<u32> m_holding_locks { 0 };
|
||||||
Spinlock m_holding_locks_lock { LockRank::None };
|
Spinlock m_holding_locks_lock { LockRank::None };
|
||||||
Vector<HoldingLockInfo> m_holding_locks_list;
|
Vector<HoldingLockInfo> m_holding_locks_list;
|
||||||
|
@ -1386,6 +1397,28 @@ inline IterationDecision Thread::for_each_in_state(State state, Callback callbac
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if LOCK_DEBUG
|
||||||
|
template<IteratorFunction<Thread::HoldingLockInfo const&> Callback>
|
||||||
|
inline void Thread::for_each_held_lock(Callback callback)
|
||||||
|
{
|
||||||
|
SpinlockLocker list_lock(m_holding_locks_lock);
|
||||||
|
|
||||||
|
for (auto const& lock_info : m_holding_locks_list) {
|
||||||
|
if (callback(lock_info) == IterationDecision::Break)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<VoidFunction<Thread::HoldingLockInfo const&> Callback>
|
||||||
|
inline void Thread::for_each_held_lock(Callback callback)
|
||||||
|
{
|
||||||
|
for_each_held_lock([&](auto const& lock_info) {
|
||||||
|
callback(lock_info);
|
||||||
|
return IterationDecision::Continue;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue