[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.
This commit is contained in:
2020-07-19 17:01:15 -07:00
parent ef5c333030
commit c3abe035c8
5 changed files with 20 additions and 12 deletions

View File

@@ -16,10 +16,17 @@ thread::thread(process &parent, uint8_t pri) :
TCB *tcbp = tcb(); TCB *tcbp = tcb();
tcbp->pml4 = parent.pml4(); tcbp->pml4 = parent.pml4();
tcbp->priority = pri; tcbp->priority = pri;
tcbp->thread_data = this;
set_state(state::ready); set_state(state::ready);
} }
thread *
thread::from_tcb(TCB *tcb)
{
static ptrdiff_t offset =
-1 * static_cast<ptrdiff_t>(offsetof(thread, m_tcb));
return reinterpret_cast<thread*>(kutil::offset_pointer(tcb, offset));
}
void void
thread::wait_on_signals(kobject *obj, j6_signal_t signals) thread::wait_on_signals(kobject *obj, j6_signal_t signals)
{ {

View File

@@ -27,8 +27,6 @@ struct TCB
uint32_t time_left; uint32_t time_left;
uint64_t last_ran; uint64_t last_ran;
thread *thread_data;
}; };
using tcb_list = kutil::linked_list<TCB>; using tcb_list = kutil::linked_list<TCB>;
@@ -47,6 +45,9 @@ public:
none = 0x00 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. /// Get the `ready` state of the thread.
/// \returns True if the thread is ready to execute. /// \returns True if the thread is ready to execute.
inline bool ready() const { return has_state(state::ready); } inline bool ready() const { return has_state(state::ready); }

View File

@@ -116,7 +116,7 @@ load_process_image(const void *image_start, size_t bytes, TCB *tcb)
// process code and load it // process code and load it
page_manager *pager = page_manager::get(); 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); 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. // move them to the appropriate lists.
auto *tcb = m_blocked.front(); auto *tcb = m_blocked.front();
while (tcb) { while (tcb) {
thread *th = tcb->thread_data; thread *th = thread::from_tcb(tcb);
uint8_t priority = tcb->priority; uint8_t priority = tcb->priority;
bool ready = th->has_state(thread::state::ready); 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 &pri_list : m_runlists) {
for (auto *tcb : pri_list) { 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); const bool constant = th->has_state(thread::state::constant);
if (constant) if (constant)
continue; continue;
@@ -345,7 +345,7 @@ scheduler::schedule()
uint8_t priority = m_current->priority; uint8_t priority = m_current->priority;
uint32_t remaining = m_apic->stop_timer(); uint32_t remaining = m_apic->stop_timer();
m_current->time_left = remaining; 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); const bool constant = th->has_state(thread::state::constant);
if (remaining == 0) { if (remaining == 0) {

View File

@@ -11,7 +11,7 @@ object_noop()
{ {
auto &s = scheduler::get(); auto &s = scheduler::get();
TCB *tcb = s.current(); 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()); log::debug(logs::syscall, "Thread %llx called noop syscall.", th->koid());
return j6_status_ok; return j6_status_ok;
} }

View File

@@ -11,7 +11,7 @@ process_exit(int64_t status)
{ {
auto &s = scheduler::get(); auto &s = scheduler::get();
TCB *tcb = s.current(); 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); log::debug(logs::syscall, "Thread %llx exiting with code %d", th->koid(), status);
th->exit(status); th->exit(status);
@@ -67,7 +67,7 @@ process_log(const char *message)
auto &s = scheduler::get(); auto &s = scheduler::get();
TCB *tcb = s.current(); 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); log::info(logs::syscall, "Message[%llx]: %s", th->koid(), message);
return j6_status_ok; return j6_status_ok;
} }
@@ -80,7 +80,7 @@ process_pause()
{ {
auto &s = scheduler::get(); auto &s = scheduler::get();
TCB *tcb = s.current(); TCB *tcb = s.current();
thread *th = tcb->thread_data; thread *th = thread::from_tcb(tcb);
th->wait_on_signals(th, -1ull); th->wait_on_signals(th, -1ull);
s.schedule(); s.schedule();
return j6_status_ok; return j6_status_ok;
@@ -91,7 +91,7 @@ process_sleep(uint64_t til)
{ {
auto &s = scheduler::get(); auto &s = scheduler::get();
TCB *tcb = s.current(); 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); log::debug(logs::syscall, "Thread %llx sleeping until %llu", th->koid(), til);
th->wait_on_time(til); th->wait_on_time(til);