From 788b2d64c66a0741717b638a03baead77856268e Mon Sep 17 00:00:00 2001 From: Tom Date: Sat, 4 Jul 2020 15:55:20 -0600 Subject: [PATCH] Kernel: Require a reason to be passed to Thread::wait_on The Lock class still permits no reason, but for everything else require a reason to be passed to Thread::wait_on. This makes it easier to diagnose why a Thread is in Queued state. --- Kernel/Devices/PATAChannel.cpp | 2 +- Kernel/Devices/SB16.cpp | 2 +- Kernel/Lock.cpp | 2 +- Kernel/Net/E1000NetworkAdapter.cpp | 2 +- Kernel/Net/NetworkTask.cpp | 2 +- Kernel/Process.cpp | 2 +- Kernel/Random.cpp | 2 +- Kernel/Scheduler.cpp | 2 +- Kernel/Tasks/FinalizerTask.cpp | 2 +- Kernel/Thread.cpp | 4 +++- Kernel/Thread.h | 8 +++++++- 11 files changed, 19 insertions(+), 11 deletions(-) diff --git a/Kernel/Devices/PATAChannel.cpp b/Kernel/Devices/PATAChannel.cpp index 877412741c..e380acd2e6 100644 --- a/Kernel/Devices/PATAChannel.cpp +++ b/Kernel/Devices/PATAChannel.cpp @@ -177,7 +177,7 @@ static void print_ide_status(u8 status) void PATAChannel::wait_for_irq() { - Thread::current()->wait_on(m_irq_queue); + Thread::current()->wait_on(m_irq_queue, "PATAChannel"); disable_irq(); } diff --git a/Kernel/Devices/SB16.cpp b/Kernel/Devices/SB16.cpp index f5e4ff390d..b37ec2a988 100644 --- a/Kernel/Devices/SB16.cpp +++ b/Kernel/Devices/SB16.cpp @@ -222,7 +222,7 @@ void SB16::handle_irq(const RegisterState&) void SB16::wait_for_irq() { - Thread::current()->wait_on(m_irq_queue); + Thread::current()->wait_on(m_irq_queue, "SB16"); disable_irq(); } diff --git a/Kernel/Lock.cpp b/Kernel/Lock.cpp index 05d516d672..132158c92e 100644 --- a/Kernel/Lock.cpp +++ b/Kernel/Lock.cpp @@ -67,7 +67,7 @@ void Lock::lock(Mode mode) return; } timeval* timeout = nullptr; - current_thread->wait_on(m_queue, timeout, &m_lock, m_holder, m_name); + current_thread->wait_on(m_queue, m_name, timeout, &m_lock, m_holder); } else if (Processor::current().in_critical()) { // If we're in a critical section and trying to lock, no context // switch will happen, so yield. diff --git a/Kernel/Net/E1000NetworkAdapter.cpp b/Kernel/Net/E1000NetworkAdapter.cpp index fc6a8058d8..f761c6fa8a 100644 --- a/Kernel/Net/E1000NetworkAdapter.cpp +++ b/Kernel/Net/E1000NetworkAdapter.cpp @@ -416,7 +416,7 @@ void E1000NetworkAdapter::send_raw(const u8* data, size_t length) sti(); break; } - Thread::current()->wait_on(m_wait_queue); + Thread::current()->wait_on(m_wait_queue, "E1000NetworkAdapter"); } #ifdef E1000_DEBUG klog() << "E1000: Sent packet, status is now " << String::format("%b", descriptor.status) << "!"; diff --git a/Kernel/Net/NetworkTask.cpp b/Kernel/Net/NetworkTask.cpp index 64863903b6..eb827b6d62 100644 --- a/Kernel/Net/NetworkTask.cpp +++ b/Kernel/Net/NetworkTask.cpp @@ -113,7 +113,7 @@ void NetworkTask_main() for (;;) { size_t packet_size = dequeue_packet(buffer, buffer_size); if (!packet_size) { - Thread::current()->wait_on(packet_wait_queue); + Thread::current()->wait_on(packet_wait_queue, "NetworkTask"); continue; } if (packet_size < sizeof(EthernetFrameHeader)) { diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index 224e103b34..6e3a310da7 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -4846,7 +4846,7 @@ int Process::sys$futex(const Syscall::SC_futex_params* user_params) } // FIXME: This is supposed to be interruptible by a signal, but right now WaitQueue cannot be interrupted. - Thread::BlockResult result = Thread::current()->wait_on(wait_queue, optional_timeout); + Thread::BlockResult result = Thread::current()->wait_on(wait_queue, "Futex", optional_timeout); if (result == Thread::BlockResult::InterruptedByTimeout) { return -ETIMEDOUT; } diff --git a/Kernel/Random.cpp b/Kernel/Random.cpp index 681093f1e1..f024865a74 100644 --- a/Kernel/Random.cpp +++ b/Kernel/Random.cpp @@ -71,7 +71,7 @@ KernelRng::KernelRng() void KernelRng::wait_for_entropy() { if (!resource().is_ready()) { - Thread::current()->wait_on(m_seed_queue); + Thread::current()->wait_on(m_seed_queue, "KernelRng"); } } diff --git a/Kernel/Scheduler.cpp b/Kernel/Scheduler.cpp index 9d36b9eda7..d56c807605 100644 --- a/Kernel/Scheduler.cpp +++ b/Kernel/Scheduler.cpp @@ -402,7 +402,7 @@ bool Scheduler::pick_next() #ifdef SCHEDULER_RUNNABLE_DEBUG dbg() << "Non-runnables:"; Scheduler::for_each_nonrunnable([](Thread& thread) -> IterationDecision { - dbg() << " " << String::format("%-12s", thread.state_string()) << " " << thread << " @ " << String::format("%w", thread.tss().cs) << ":" << String::format("%x", thread.tss().eip); + dbg() << " " << String::format("%-12s", thread.state_string()) << " " << thread << " @ " << String::format("%w", thread.tss().cs) << ":" << String::format("%x", thread.tss().eip) << " Reason: " << (thread.wait_reason() ? thread.wait_reason() : "none"); return IterationDecision::Continue; }); diff --git a/Kernel/Tasks/FinalizerTask.cpp b/Kernel/Tasks/FinalizerTask.cpp index 8a3cb1b160..4830948e05 100644 --- a/Kernel/Tasks/FinalizerTask.cpp +++ b/Kernel/Tasks/FinalizerTask.cpp @@ -34,7 +34,7 @@ void FinalizerTask::spawn() Process::create_kernel_process(g_finalizer, "FinalizerTask", [] { Thread::current()->set_priority(THREAD_PRIORITY_LOW); for (;;) { - Thread::current()->wait_on(*g_finalizer_wait_queue); + Thread::current()->wait_on(*g_finalizer_wait_queue, "FinalizerTask"); bool expected = true; if (g_finalizer_has_work.compare_exchange_strong(expected, false, AK::MemoryOrder::memory_order_acq_rel)) diff --git a/Kernel/Thread.cpp b/Kernel/Thread.cpp index cfbe113783..4c774b848b 100644 --- a/Kernel/Thread.cpp +++ b/Kernel/Thread.cpp @@ -852,7 +852,7 @@ const LogStream& operator<<(const LogStream& stream, const Thread& value) return stream << value.process().name() << "(" << value.pid() << ":" << value.tid() << ")"; } -Thread::BlockResult Thread::wait_on(WaitQueue& queue, timeval* timeout, Atomic* lock, Thread* beneficiary, const char* reason) +Thread::BlockResult Thread::wait_on(WaitQueue& queue, const char* reason, timeval* timeout, Atomic* lock, Thread* beneficiary) { TimerId timer_id {}; u32 prev_crit; @@ -864,6 +864,7 @@ Thread::BlockResult Thread::wait_on(WaitQueue& queue, timeval* timeout, Atomic(state_string, move(condition)); } - BlockResult wait_on(WaitQueue& queue, timeval* timeout = nullptr, Atomic* lock = nullptr, Thread* beneficiary = nullptr, const char* reason = nullptr); + BlockResult wait_on(WaitQueue& queue, const char* reason, timeval* timeout = nullptr, Atomic* lock = nullptr, Thread* beneficiary = nullptr); void wake_from_queue(); void unblock(); @@ -433,6 +433,11 @@ public: m_ipv4_socket_write_bytes += bytes; } + const char* wait_reason() const + { + return m_wait_reason; + } + Thread* clone(Process&); template @@ -484,6 +489,7 @@ private: size_t m_thread_specific_region_size { 0 }; SignalActionData m_signal_action_data[32]; Blocker* m_blocker { nullptr }; + const char* m_wait_reason { nullptr }; bool m_is_joinable { true }; Thread* m_joiner { nullptr };