mirror of
https://github.com/RGBCube/serenity
synced 2025-05-25 18:25:09 +00:00
Kernel: Add magic key combo (Alt+Shift+F12) to dump scheduler state
Pressing this combo will dump a list of all threads and their state to the debug console. This might be useful to figure out why the system is not responding.
This commit is contained in:
parent
685556ae84
commit
24dcd99e4b
3 changed files with 55 additions and 23 deletions
|
@ -53,6 +53,11 @@ void PS2KeyboardDevice::irq_handle_byte_read(u8 byte)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_modifiers == (Mod_Alt | Mod_Shift) && byte == 0x58) {
|
||||||
|
// Alt+Shift+F12 pressed, dump some kernel state to the debug console.
|
||||||
|
Scheduler::dump_scheduler_state();
|
||||||
|
}
|
||||||
|
|
||||||
dbgln_if(KEYBOARD_DEBUG, "Keyboard::irq_handle_byte_read: {:#02x} {}", ch, (pressed ? "down" : "up"));
|
dbgln_if(KEYBOARD_DEBUG, "Keyboard::irq_handle_byte_read: {:#02x} {}", ch, (pressed ? "down" : "up"));
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case 0x38:
|
case 0x38:
|
||||||
|
|
|
@ -79,6 +79,7 @@ static SpinLock<u8> g_ready_queues_lock;
|
||||||
static u32 g_ready_queues_mask;
|
static u32 g_ready_queues_mask;
|
||||||
static constexpr u32 g_ready_queue_buckets = sizeof(g_ready_queues_mask) * 8;
|
static constexpr u32 g_ready_queue_buckets = sizeof(g_ready_queues_mask) * 8;
|
||||||
READONLY_AFTER_INIT static ThreadReadyQueue* g_ready_queues; // g_ready_queue_buckets entries
|
READONLY_AFTER_INIT static ThreadReadyQueue* g_ready_queues; // g_ready_queue_buckets entries
|
||||||
|
static void dump_thread_list();
|
||||||
|
|
||||||
static inline u32 thread_priority_to_priority_index(u32 thread_priority)
|
static inline u32 thread_priority_to_priority_index(u32 thread_priority)
|
||||||
{
|
{
|
||||||
|
@ -235,29 +236,7 @@ bool Scheduler::pick_next()
|
||||||
}
|
}
|
||||||
|
|
||||||
if constexpr (SCHEDULER_RUNNABLE_DEBUG) {
|
if constexpr (SCHEDULER_RUNNABLE_DEBUG) {
|
||||||
dbgln("Scheduler thread list for processor {}:", Processor::id());
|
dump_thread_list();
|
||||||
Thread::for_each([&](Thread& thread) -> IterationDecision {
|
|
||||||
switch (thread.state()) {
|
|
||||||
case Thread::Dying:
|
|
||||||
dbgln(" {:12} {} @ {:04x}:{:08x} Finalizable: {}",
|
|
||||||
thread.state_string(),
|
|
||||||
thread,
|
|
||||||
thread.tss().cs,
|
|
||||||
thread.tss().eip,
|
|
||||||
thread.is_finalizable());
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
dbgln(" {:12} Pr:{:2} {} @ {:04x}:{:08x}",
|
|
||||||
thread.state_string(),
|
|
||||||
thread.priority(),
|
|
||||||
thread,
|
|
||||||
thread.tss().cs,
|
|
||||||
thread.tss().eip);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return IterationDecision::Continue;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto pending_beneficiary = scheduler_data.m_pending_beneficiary.strong_ref();
|
auto pending_beneficiary = scheduler_data.m_pending_beneficiary.strong_ref();
|
||||||
|
@ -633,4 +612,51 @@ void Scheduler::idle_loop(void*)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Scheduler::dump_scheduler_state()
|
||||||
|
{
|
||||||
|
dump_thread_list();
|
||||||
|
}
|
||||||
|
|
||||||
|
void dump_thread_list()
|
||||||
|
{
|
||||||
|
dbgln("Scheduler thread list for processor {}:", Processor::id());
|
||||||
|
|
||||||
|
auto get_cs = [](Thread& thread) -> u16 {
|
||||||
|
if (!thread.current_trap())
|
||||||
|
return thread.tss().cs;
|
||||||
|
return thread.get_register_dump_from_stack().cs;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto get_eip = [](Thread& thread) -> u32 {
|
||||||
|
if (!thread.current_trap())
|
||||||
|
return thread.tss().eip;
|
||||||
|
return thread.get_register_dump_from_stack().eip;
|
||||||
|
};
|
||||||
|
|
||||||
|
Thread::for_each([&](Thread& thread) -> IterationDecision {
|
||||||
|
switch (thread.state()) {
|
||||||
|
case Thread::Dying:
|
||||||
|
dbgln(" {:14} {:30} @ {:04x}:{:08x} Finalizable: {}, (nsched: {})",
|
||||||
|
thread.state_string(),
|
||||||
|
thread,
|
||||||
|
get_cs(thread),
|
||||||
|
get_eip(thread),
|
||||||
|
thread.is_finalizable(),
|
||||||
|
thread.times_scheduled());
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
dbgln(" {:14} Pr:{:2} {:30} @ {:04x}:{:08x} (nsched: {})",
|
||||||
|
thread.state_string(),
|
||||||
|
thread.priority(),
|
||||||
|
thread,
|
||||||
|
get_cs(thread),
|
||||||
|
get_eip(thread),
|
||||||
|
thread.times_scheduled());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return IterationDecision::Continue;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,6 +70,7 @@ public:
|
||||||
static Thread& pull_next_runnable_thread();
|
static Thread& pull_next_runnable_thread();
|
||||||
static bool dequeue_runnable_thread(Thread&, bool = false);
|
static bool dequeue_runnable_thread(Thread&, bool = false);
|
||||||
static void queue_runnable_thread(Thread&);
|
static void queue_runnable_thread(Thread&);
|
||||||
|
static void dump_scheduler_state();
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue