From c3abe035c8171fbe0548286b1c371d940da83af6 Mon Sep 17 00:00:00 2001 From: "Justin C. Miller" Date: Sun, 19 Jul 2020 17:01:15 -0700 Subject: [PATCH] [kernel] Remove thread_data pointer from TCB The TCB is always stored at a constant offset within the thread object. So instead of carrying an extra pointer, just implement thread::from_tcb to get the thread. --- src/kernel/objects/thread.cpp | 9 ++++++++- src/kernel/objects/thread.h | 5 +++-- src/kernel/scheduler.cpp | 8 ++++---- src/kernel/syscalls/object.cpp | 2 +- src/kernel/syscalls/process.cpp | 8 ++++---- 5 files changed, 20 insertions(+), 12 deletions(-) diff --git a/src/kernel/objects/thread.cpp b/src/kernel/objects/thread.cpp index b492b8c..6b9e48f 100644 --- a/src/kernel/objects/thread.cpp +++ b/src/kernel/objects/thread.cpp @@ -16,10 +16,17 @@ thread::thread(process &parent, uint8_t pri) : TCB *tcbp = tcb(); tcbp->pml4 = parent.pml4(); tcbp->priority = pri; - tcbp->thread_data = this; set_state(state::ready); } +thread * +thread::from_tcb(TCB *tcb) +{ + static ptrdiff_t offset = + -1 * static_cast(offsetof(thread, m_tcb)); + return reinterpret_cast(kutil::offset_pointer(tcb, offset)); +} + void thread::wait_on_signals(kobject *obj, j6_signal_t signals) { diff --git a/src/kernel/objects/thread.h b/src/kernel/objects/thread.h index 325dca2..495897a 100644 --- a/src/kernel/objects/thread.h +++ b/src/kernel/objects/thread.h @@ -27,8 +27,6 @@ struct TCB uint32_t time_left; uint64_t last_ran; - - thread *thread_data; }; using tcb_list = kutil::linked_list; @@ -47,6 +45,9 @@ public: none = 0x00 }; + /// Get the pointer to the thread object containing this TCB + static thread * from_tcb(TCB *tcb); + /// Get the `ready` state of the thread. /// \returns True if the thread is ready to execute. inline bool ready() const { return has_state(state::ready); } diff --git a/src/kernel/scheduler.cpp b/src/kernel/scheduler.cpp index feeb82c..87e2960 100644 --- a/src/kernel/scheduler.cpp +++ b/src/kernel/scheduler.cpp @@ -116,7 +116,7 @@ load_process_image(const void *image_start, size_t bytes, TCB *tcb) // process code and load it page_manager *pager = page_manager::get(); - thread *th = tcb->thread_data; + thread *th = thread::from_tcb(tcb); log::debug(logs::loader, "Loading task! ELF: %016lx [%d]", image_start, bytes); @@ -279,7 +279,7 @@ void scheduler::prune(uint64_t now) // move them to the appropriate lists. auto *tcb = m_blocked.front(); while (tcb) { - thread *th = tcb->thread_data; + thread *th = thread::from_tcb(tcb); uint8_t priority = tcb->priority; bool ready = th->has_state(thread::state::ready); @@ -311,7 +311,7 @@ scheduler::check_promotions(uint64_t now) { for (auto &pri_list : m_runlists) { for (auto *tcb : pri_list) { - const thread *th = m_current->thread_data; + const thread *th = thread::from_tcb(m_current); const bool constant = th->has_state(thread::state::constant); if (constant) continue; @@ -345,7 +345,7 @@ scheduler::schedule() uint8_t priority = m_current->priority; uint32_t remaining = m_apic->stop_timer(); m_current->time_left = remaining; - thread *th = m_current->thread_data; + thread *th = thread::from_tcb(m_current); const bool constant = th->has_state(thread::state::constant); if (remaining == 0) { diff --git a/src/kernel/syscalls/object.cpp b/src/kernel/syscalls/object.cpp index d1572ab..73cc12d 100644 --- a/src/kernel/syscalls/object.cpp +++ b/src/kernel/syscalls/object.cpp @@ -11,7 +11,7 @@ object_noop() { auto &s = scheduler::get(); TCB *tcb = s.current(); - thread *th = tcb->thread_data; + thread *th = thread::from_tcb(tcb); log::debug(logs::syscall, "Thread %llx called noop syscall.", th->koid()); return j6_status_ok; } diff --git a/src/kernel/syscalls/process.cpp b/src/kernel/syscalls/process.cpp index 694c8db..fbbf294 100644 --- a/src/kernel/syscalls/process.cpp +++ b/src/kernel/syscalls/process.cpp @@ -11,7 +11,7 @@ process_exit(int64_t status) { auto &s = scheduler::get(); TCB *tcb = s.current(); - thread *th = tcb->thread_data; + thread *th = thread::from_tcb(tcb); log::debug(logs::syscall, "Thread %llx exiting with code %d", th->koid(), status); th->exit(status); @@ -67,7 +67,7 @@ process_log(const char *message) auto &s = scheduler::get(); TCB *tcb = s.current(); - thread *th = tcb->thread_data; + thread *th = thread::from_tcb(tcb); log::info(logs::syscall, "Message[%llx]: %s", th->koid(), message); return j6_status_ok; } @@ -80,7 +80,7 @@ process_pause() { auto &s = scheduler::get(); TCB *tcb = s.current(); - thread *th = tcb->thread_data; + thread *th = thread::from_tcb(tcb); th->wait_on_signals(th, -1ull); s.schedule(); return j6_status_ok; @@ -91,7 +91,7 @@ process_sleep(uint64_t til) { auto &s = scheduler::get(); TCB *tcb = s.current(); - thread *th = tcb->thread_data; + thread *th = thread::from_tcb(tcb); log::debug(logs::syscall, "Thread %llx sleeping until %llu", th->koid(), til); th->wait_on_time(til);