From 2420886c2cc745e41a33715e068a148157eb6469 Mon Sep 17 00:00:00 2001 From: Bananymous Date: Fri, 8 Mar 2024 23:24:18 +0200 Subject: [PATCH] Kernel: Move current and idle thread to Processor --- kernel/include/kernel/Processor.h | 9 +++++ kernel/include/kernel/Scheduler.h | 5 +-- kernel/kernel/Processor.cpp | 10 ++++- kernel/kernel/Scheduler.cpp | 61 +++++++++++++++---------------- kernel/kernel/kernel.cpp | 1 + 5 files changed, 49 insertions(+), 37 deletions(-) diff --git a/kernel/include/kernel/Processor.h b/kernel/include/kernel/Processor.h index 0faeaf4a..fe039349 100644 --- a/kernel/include/kernel/Processor.h +++ b/kernel/include/kernel/Processor.h @@ -5,6 +5,7 @@ #include #include #include +#include namespace Kernel { @@ -27,6 +28,7 @@ namespace Kernel public: static Processor& create(ProcessorID id); static Processor& initialize(); + static void allocate_idle_thread(); static ProcessorID current_id() { return read_gs_sized(offsetof(Processor, m_id)); } @@ -62,6 +64,10 @@ namespace Kernel static void* get_current_page_table() { return read_gs_ptr(offsetof(Processor, m_current_page_table)); } static void set_current_page_table(void* page_table) { write_gs_ptr(offsetof(Processor, m_current_page_table), page_table); } + static Thread* idle_thread() { return reinterpret_cast(read_gs_ptr(offsetof(Processor, m_idle_thread))); } + static SchedulerQueue::Node* get_current_thread() { return reinterpret_cast(read_gs_ptr(offsetof(Processor, m_current_thread))); } + static void set_current_thread(SchedulerQueue::Node* thread) { write_gs_ptr(offsetof(Processor, m_current_thread), thread); } + private: Processor() = default; ~Processor() { ASSERT_NOT_REACHED(); } @@ -112,6 +118,9 @@ namespace Kernel GDT* m_gdt { nullptr }; IDT* m_idt { nullptr }; + Thread* m_idle_thread { nullptr }; + SchedulerQueue::Node* m_current_thread { nullptr }; + void* m_current_page_table { nullptr }; friend class BAN::Array; diff --git a/kernel/include/kernel/Scheduler.h b/kernel/include/kernel/Scheduler.h index 95afc0da..06ea0803 100644 --- a/kernel/include/kernel/Scheduler.h +++ b/kernel/include/kernel/Scheduler.h @@ -38,7 +38,7 @@ namespace Kernel private: Scheduler() = default; - void set_current_thread_sleeping_impl(uint64_t wake_time); + void set_current_thread_sleeping_impl(Semaphore* semaphore, uint64_t wake_time); [[nodiscard]] bool save_current_thread(); void advance_current_thread(); @@ -54,9 +54,6 @@ namespace Kernel SchedulerQueue m_active_threads; SchedulerQueue m_blocking_threads; - Thread* m_idle_thread { nullptr }; - SchedulerQueue::Node* m_current_thread { nullptr }; - friend class Process; }; diff --git a/kernel/kernel/Processor.cpp b/kernel/kernel/Processor.cpp index 886bf07d..f9ef0ff7 100644 --- a/kernel/kernel/Processor.cpp +++ b/kernel/kernel/Processor.cpp @@ -1,7 +1,6 @@ #include #include - -#include +#include namespace Kernel { @@ -67,4 +66,11 @@ namespace Kernel return processor; } + void Processor::allocate_idle_thread() + { + ASSERT(idle_thread() == nullptr); + auto* idle_thread = MUST(Thread::create_kernel([](void*) { for (;;) asm volatile("hlt"); }, nullptr, nullptr)); + write_gs_ptr(offsetof(Processor, m_idle_thread), idle_thread); + } + } diff --git a/kernel/kernel/Scheduler.cpp b/kernel/kernel/Scheduler.cpp index 7535b15b..3a3ad914 100644 --- a/kernel/kernel/Scheduler.cpp +++ b/kernel/kernel/Scheduler.cpp @@ -24,10 +24,9 @@ namespace Kernel BAN::ErrorOr Scheduler::initialize() { ASSERT(s_instance == nullptr); - Scheduler* scheduler = new Scheduler(); - ASSERT(scheduler); - scheduler->m_idle_thread = TRY(Thread::create_kernel([](void*) { for (;;) asm volatile("hlt"); }, nullptr, nullptr)); - s_instance = scheduler; + s_instance = new Scheduler(); + ASSERT(s_instance); + Processor::allocate_idle_thread(); return {}; } @@ -49,7 +48,8 @@ namespace Kernel Thread& Scheduler::current_thread() { - return m_current_thread ? *m_current_thread->thread : *m_idle_thread; + auto* current = Processor::get_current_thread(); + return current ? *current->thread : *Processor::idle_thread(); } pid_t Scheduler::current_tid() @@ -83,7 +83,7 @@ namespace Kernel void Scheduler::reschedule_if_idling() { auto state = m_lock.lock(); - if (m_active_threads.empty() || m_current_thread) + if (m_active_threads.empty() || Processor::get_current_thread()) return m_lock.unlock(state); if (save_current_thread()) return Processor::set_interrupt_state(state); @@ -114,12 +114,12 @@ namespace Kernel { ASSERT(m_lock.current_processor_has_lock()); - if (m_current_thread) - m_active_threads.push_back(m_current_thread); - m_current_thread = nullptr; + if (auto* current = Processor::get_current_thread()) + m_active_threads.push_back(current); + Processor::set_current_thread(nullptr); if (!m_active_threads.empty()) - m_current_thread = m_active_threads.pop_front(); + Processor::set_current_thread(m_active_threads.pop_front()); } // NOTE: this is declared always inline, so we don't corrupt the stack @@ -153,13 +153,12 @@ namespace Kernel load_temp_stack(); PageTable::kernel().load(); - Thread* thread = m_current_thread->thread; - - ASSERT(thread->has_process()); - delete &thread->process(); - delete thread; - delete m_current_thread; - m_current_thread = nullptr; + auto* current = Processor::get_current_thread(); + ASSERT(current); + delete ¤t->thread->process(); + delete current->thread; + delete current; + Processor::set_current_thread(nullptr); advance_current_thread(); execute_current_thread_locked(); @@ -210,14 +209,14 @@ namespace Kernel while (current->state() == Thread::State::Terminated) { - Thread* thread = m_current_thread->thread; - if (thread->has_process()) - if (thread->process().on_thread_exit(*thread)) + auto* node = Processor::get_current_thread(); + if (node->thread->has_process()) + if (node->thread->process().on_thread_exit(*node->thread)) break; - delete thread; - delete m_current_thread; - m_current_thread = nullptr; + delete node->thread; + delete node; + Processor::set_current_thread(nullptr); advance_current_thread(); current = ¤t_thread(); @@ -249,16 +248,18 @@ namespace Kernel ASSERT_NOT_REACHED(); } - void Scheduler::set_current_thread_sleeping_impl(uint64_t wake_time) + void Scheduler::set_current_thread_sleeping_impl(Semaphore* semaphore, uint64_t wake_time) { ASSERT(m_lock.current_processor_has_lock()); if (save_current_thread()) return; - m_current_thread->wake_time = wake_time; - m_blocking_threads.add_with_wake_time(m_current_thread); - m_current_thread = nullptr; + auto* current = Processor::get_current_thread(); + current->semaphore = semaphore; + current->wake_time = wake_time; + m_blocking_threads.add_with_wake_time(current); + Processor::set_current_thread(nullptr); advance_current_thread(); execute_current_thread_locked(); @@ -268,16 +269,14 @@ namespace Kernel void Scheduler::set_current_thread_sleeping(uint64_t wake_time) { auto state = m_lock.lock(); - m_current_thread->semaphore = nullptr; - set_current_thread_sleeping_impl(wake_time); + set_current_thread_sleeping_impl(nullptr, wake_time); Processor::set_interrupt_state(state); } void Scheduler::block_current_thread(Semaphore* semaphore, uint64_t wake_time) { auto state = m_lock.lock(); - m_current_thread->semaphore = semaphore; - set_current_thread_sleeping_impl(wake_time); + set_current_thread_sleeping_impl(semaphore, wake_time); Processor::set_interrupt_state(state); } diff --git a/kernel/kernel/kernel.cpp b/kernel/kernel/kernel.cpp index 500f785e..007b3246 100644 --- a/kernel/kernel/kernel.cpp +++ b/kernel/kernel/kernel.cpp @@ -213,6 +213,7 @@ extern "C" void ap_main() Processor::initialize(); PageTable::kernel().initial_load(); + Processor::allocate_idle_thread(); dprintln("ap{} initialized", Processor::current_id());