Skip to content

Commit

Permalink
Kernel: Require a reason to be passed to Thread::wait_on
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
tomuta authored and awesomekling committed Jul 6, 2020
1 parent 0c4b0c0 commit 788b2d6
Show file tree
Hide file tree
Showing 11 changed files with 19 additions and 11 deletions.
2 changes: 1 addition & 1 deletion Kernel/Devices/PATAChannel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}

Expand Down
2 changes: 1 addition & 1 deletion Kernel/Devices/SB16.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}

Expand Down
2 changes: 1 addition & 1 deletion Kernel/Lock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion Kernel/Net/E1000NetworkAdapter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) << "!";
Expand Down
2 changes: 1 addition & 1 deletion Kernel/Net/NetworkTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)) {
Expand Down
2 changes: 1 addition & 1 deletion Kernel/Process.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
2 changes: 1 addition & 1 deletion Kernel/Random.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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");
}
}

Expand Down
2 changes: 1 addition & 1 deletion Kernel/Scheduler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
});

Expand Down
2 changes: 1 addition & 1 deletion Kernel/Tasks/FinalizerTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
4 changes: 3 additions & 1 deletion Kernel/Thread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<bool>* lock, Thread* beneficiary, const char* reason)
Thread::BlockResult Thread::wait_on(WaitQueue& queue, const char* reason, timeval* timeout, Atomic<bool>* lock, Thread* beneficiary)
{
TimerId timer_id {};
u32 prev_crit;
Expand All @@ -864,6 +864,7 @@ Thread::BlockResult Thread::wait_on(WaitQueue& queue, timeval* timeout, Atomic<b
if (lock)
*lock = false;
set_state(State::Queued);
m_wait_reason = reason;
queue.enqueue(*Thread::current());


Expand Down Expand Up @@ -899,6 +900,7 @@ void Thread::wake_from_queue()
{
ScopedSpinLock lock(g_scheduler_lock);
ASSERT(state() == State::Queued);
m_wait_reason = nullptr;
if (this != Thread::current())
set_state(State::Runnable);
else
Expand Down
8 changes: 7 additions & 1 deletion Kernel/Thread.h
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,7 @@ class Thread {
return block<ConditionBlocker>(state_string, move(condition));
}

BlockResult wait_on(WaitQueue& queue, timeval* timeout = nullptr, Atomic<bool>* lock = nullptr, Thread* beneficiary = nullptr, const char* reason = nullptr);
BlockResult wait_on(WaitQueue& queue, const char* reason, timeval* timeout = nullptr, Atomic<bool>* lock = nullptr, Thread* beneficiary = nullptr);
void wake_from_queue();

void unblock();
Expand Down Expand Up @@ -433,6 +433,11 @@ class Thread {
m_ipv4_socket_write_bytes += bytes;
}

const char* wait_reason() const
{
return m_wait_reason;
}

Thread* clone(Process&);

template<typename Callback>
Expand Down Expand Up @@ -484,6 +489,7 @@ class Thread {
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 };
Expand Down

0 comments on commit 788b2d6

Please sign in to comment.