[tools] Add j6threads gdb command

The j6threads command shows the current thread, ready threads, and
blocked threads for a given CPU.

To support this, TCB structs gained a pointer to their thread (instead
of trying to do offset magic) and threads gained a pointer to their
creator. Also removed thread::from_tcb() now that the TCB has a pointer.
This commit is contained in:
Justin C. Miller
2022-01-15 17:39:25 -08:00
parent 7bb6b21c65
commit 2dd78beb92
5 changed files with 115 additions and 46 deletions

View File

@@ -9,7 +9,9 @@
#include "idt.h"
#include "log.h"
#include "msr.h"
#include "objects/thread.h"
#include "objects/vm_area.h"
#include "scheduler.h"
#include "syscall.h"
#include "tss.h"
@@ -60,10 +62,6 @@ cpu_early_init(cpu_data *cpu)
// Install the GS base pointint to the cpu_data
wrmsr(msr::ia32_gs_base, reinterpret_cast<uintptr_t>(cpu));
// Set the initial process as the kernel "process"
extern process &g_kernel_process;
cpu->process = &g_kernel_process;
}
void
@@ -74,6 +72,18 @@ cpu_init(cpu_data *cpu, bool bsp)
cpu_early_init(cpu);
}
// Set the initial process as the kernel "process"
extern process &g_kernel_process;
cpu->process = &g_kernel_process;
thread *idle = thread::create_idle_thread(
g_kernel_process,
scheduler::max_priority,
cpu->rsp0);
cpu->thread = idle;
cpu->tcb = idle->tcb();
// Set up the syscall MSRs
syscall_enable();

View File

@@ -24,12 +24,14 @@ thread::thread(process &parent, uint8_t pri, uintptr_t rsp0) :
{
parent.space().initialize_tcb(m_tcb);
m_tcb.priority = pri;
m_tcb.thread = this;
if (!rsp0)
setup_kernel_stack();
else
m_tcb.rsp0 = rsp0;
m_creator = current_cpu().thread;
m_self_handle = parent.add_handle(this);
}
@@ -38,14 +40,6 @@ thread::~thread()
g_kernel_stacks.return_section(m_tcb.kernel_stack);
}
thread *
thread::from_tcb(TCB *tcb)
{
static ptrdiff_t offset =
-1 * static_cast<ptrdiff_t>(offsetof(thread, m_tcb));
return reinterpret_cast<thread*>(util::offset_pointer(tcb, offset));
}
thread & thread::current() { return *current_cpu().thread; }
inline void schedule_if_current(thread *t) { if (t == current_cpu().thread) scheduler::get().schedule(); }

View File

@@ -18,6 +18,9 @@ struct TCB
uintptr_t rsp3;
uintptr_t rflags3;
uintptr_t pml4;
// End of area used by asembly
thread* thread;
uint8_t priority;
// note: 3 bytes padding
@@ -46,9 +49,6 @@ public:
none = 0x00
};
/// Get the pointer to the thread object containing this TCB
static thread * from_tcb(TCB *tcb);
/// Destructor
virtual ~thread();
@@ -175,6 +175,7 @@ private:
tcb_node m_tcb;
process &m_parent;
thread *m_creator;
state m_state;
wait_type m_wait_type;

View File

@@ -97,16 +97,8 @@ scheduler::start()
{
util::scoped_lock lock {queue.lock};
process *kp = &process::kernel_process();
thread *idle = thread::create_idle_thread(*kp, max_priority, cpu.rsp0);
auto *tcb = idle->tcb();
cpu.process = kp;
cpu.thread = idle;
cpu.tcb = tcb;
queue.current = tcb;
thread *idle = cpu.thread;
queue.current = idle->tcb();
}
cpu.apic->enable_timer(isr::isrTimer, false);
@@ -130,7 +122,7 @@ void scheduler::prune(run_queue &queue, uint64_t now)
// move them to the appropriate lists.
auto *tcb = queue.blocked.front();
while (tcb) {
thread *th = thread::from_tcb(tcb);
thread *th = tcb->thread;
uint8_t priority = tcb->priority;
bool ready = th->has_state(thread::state::ready);
@@ -171,7 +163,7 @@ scheduler::check_promotions(run_queue &queue, uint64_t now)
{
for (auto &pri_list : queue.ready) {
for (auto *tcb : pri_list) {
const thread *th = thread::from_tcb(queue.current);
const thread *th = queue.current->thread;
const bool constant = th->has_state(thread::state::constant);
if (constant)
continue;
@@ -266,7 +258,7 @@ scheduler::schedule()
queue.lock.acquire(&waiter);
queue.current->time_left = remaining;
thread *th = thread::from_tcb(queue.current);
thread *th = queue.current->thread;
uint8_t priority = queue.current->priority;
const bool constant = th->has_state(thread::state::constant);
@@ -313,7 +305,7 @@ scheduler::schedule()
return;
}
thread *next_thread = thread::from_tcb(next);
thread *next_thread = next->thread;
cpu.thread = next_thread;
cpu.process = &next_thread->parent();