Kernel: Move current and idle thread to Processor

This commit is contained in:
Bananymous 2024-03-08 23:24:18 +02:00
parent e636dce919
commit 2420886c2c
5 changed files with 49 additions and 37 deletions

View File

@ -5,6 +5,7 @@
#include <kernel/Arch.h> #include <kernel/Arch.h>
#include <kernel/GDT.h> #include <kernel/GDT.h>
#include <kernel/IDT.h> #include <kernel/IDT.h>
#include <kernel/SchedulerQueue.h>
namespace Kernel namespace Kernel
{ {
@ -27,6 +28,7 @@ namespace Kernel
public: public:
static Processor& create(ProcessorID id); static Processor& create(ProcessorID id);
static Processor& initialize(); static Processor& initialize();
static void allocate_idle_thread();
static ProcessorID current_id() { return read_gs_sized<ProcessorID>(offsetof(Processor, m_id)); } static ProcessorID current_id() { return read_gs_sized<ProcessorID>(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* 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 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<Thread*>(read_gs_ptr(offsetof(Processor, m_idle_thread))); }
static SchedulerQueue::Node* get_current_thread() { return reinterpret_cast<SchedulerQueue::Node*>(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: private:
Processor() = default; Processor() = default;
~Processor() { ASSERT_NOT_REACHED(); } ~Processor() { ASSERT_NOT_REACHED(); }
@ -112,6 +118,9 @@ namespace Kernel
GDT* m_gdt { nullptr }; GDT* m_gdt { nullptr };
IDT* m_idt { nullptr }; IDT* m_idt { nullptr };
Thread* m_idle_thread { nullptr };
SchedulerQueue::Node* m_current_thread { nullptr };
void* m_current_page_table { nullptr }; void* m_current_page_table { nullptr };
friend class BAN::Array<Processor, 0xFF>; friend class BAN::Array<Processor, 0xFF>;

View File

@ -38,7 +38,7 @@ namespace Kernel
private: private:
Scheduler() = default; 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(); [[nodiscard]] bool save_current_thread();
void advance_current_thread(); void advance_current_thread();
@ -54,9 +54,6 @@ namespace Kernel
SchedulerQueue m_active_threads; SchedulerQueue m_active_threads;
SchedulerQueue m_blocking_threads; SchedulerQueue m_blocking_threads;
Thread* m_idle_thread { nullptr };
SchedulerQueue::Node* m_current_thread { nullptr };
friend class Process; friend class Process;
}; };

View File

@ -1,7 +1,6 @@
#include <kernel/Memory/kmalloc.h> #include <kernel/Memory/kmalloc.h>
#include <kernel/Processor.h> #include <kernel/Processor.h>
#include <kernel/Thread.h>
#include <kernel/Debug.h>
namespace Kernel namespace Kernel
{ {
@ -67,4 +66,11 @@ namespace Kernel
return processor; 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);
}
} }

View File

@ -24,10 +24,9 @@ namespace Kernel
BAN::ErrorOr<void> Scheduler::initialize() BAN::ErrorOr<void> Scheduler::initialize()
{ {
ASSERT(s_instance == nullptr); ASSERT(s_instance == nullptr);
Scheduler* scheduler = new Scheduler(); s_instance = new Scheduler();
ASSERT(scheduler); ASSERT(s_instance);
scheduler->m_idle_thread = TRY(Thread::create_kernel([](void*) { for (;;) asm volatile("hlt"); }, nullptr, nullptr)); Processor::allocate_idle_thread();
s_instance = scheduler;
return {}; return {};
} }
@ -49,7 +48,8 @@ namespace Kernel
Thread& Scheduler::current_thread() 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() pid_t Scheduler::current_tid()
@ -83,7 +83,7 @@ namespace Kernel
void Scheduler::reschedule_if_idling() void Scheduler::reschedule_if_idling()
{ {
auto state = m_lock.lock(); 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); return m_lock.unlock(state);
if (save_current_thread()) if (save_current_thread())
return Processor::set_interrupt_state(state); return Processor::set_interrupt_state(state);
@ -114,12 +114,12 @@ namespace Kernel
{ {
ASSERT(m_lock.current_processor_has_lock()); ASSERT(m_lock.current_processor_has_lock());
if (m_current_thread) if (auto* current = Processor::get_current_thread())
m_active_threads.push_back(m_current_thread); m_active_threads.push_back(current);
m_current_thread = nullptr; Processor::set_current_thread(nullptr);
if (!m_active_threads.empty()) 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 // NOTE: this is declared always inline, so we don't corrupt the stack
@ -153,13 +153,12 @@ namespace Kernel
load_temp_stack(); load_temp_stack();
PageTable::kernel().load(); PageTable::kernel().load();
Thread* thread = m_current_thread->thread; auto* current = Processor::get_current_thread();
ASSERT(current);
ASSERT(thread->has_process()); delete &current->thread->process();
delete &thread->process(); delete current->thread;
delete thread; delete current;
delete m_current_thread; Processor::set_current_thread(nullptr);
m_current_thread = nullptr;
advance_current_thread(); advance_current_thread();
execute_current_thread_locked(); execute_current_thread_locked();
@ -210,14 +209,14 @@ namespace Kernel
while (current->state() == Thread::State::Terminated) while (current->state() == Thread::State::Terminated)
{ {
Thread* thread = m_current_thread->thread; auto* node = Processor::get_current_thread();
if (thread->has_process()) if (node->thread->has_process())
if (thread->process().on_thread_exit(*thread)) if (node->thread->process().on_thread_exit(*node->thread))
break; break;
delete thread; delete node->thread;
delete m_current_thread; delete node;
m_current_thread = nullptr; Processor::set_current_thread(nullptr);
advance_current_thread(); advance_current_thread();
current = &current_thread(); current = &current_thread();
@ -249,16 +248,18 @@ namespace Kernel
ASSERT_NOT_REACHED(); 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()); ASSERT(m_lock.current_processor_has_lock());
if (save_current_thread()) if (save_current_thread())
return; return;
m_current_thread->wake_time = wake_time; auto* current = Processor::get_current_thread();
m_blocking_threads.add_with_wake_time(m_current_thread); current->semaphore = semaphore;
m_current_thread = nullptr; current->wake_time = wake_time;
m_blocking_threads.add_with_wake_time(current);
Processor::set_current_thread(nullptr);
advance_current_thread(); advance_current_thread();
execute_current_thread_locked(); execute_current_thread_locked();
@ -268,16 +269,14 @@ namespace Kernel
void Scheduler::set_current_thread_sleeping(uint64_t wake_time) void Scheduler::set_current_thread_sleeping(uint64_t wake_time)
{ {
auto state = m_lock.lock(); auto state = m_lock.lock();
m_current_thread->semaphore = nullptr; set_current_thread_sleeping_impl(nullptr, wake_time);
set_current_thread_sleeping_impl(wake_time);
Processor::set_interrupt_state(state); Processor::set_interrupt_state(state);
} }
void Scheduler::block_current_thread(Semaphore* semaphore, uint64_t wake_time) void Scheduler::block_current_thread(Semaphore* semaphore, uint64_t wake_time)
{ {
auto state = m_lock.lock(); auto state = m_lock.lock();
m_current_thread->semaphore = semaphore; set_current_thread_sleeping_impl(semaphore, wake_time);
set_current_thread_sleeping_impl(wake_time);
Processor::set_interrupt_state(state); Processor::set_interrupt_state(state);
} }

View File

@ -213,6 +213,7 @@ extern "C" void ap_main()
Processor::initialize(); Processor::initialize();
PageTable::kernel().initial_load(); PageTable::kernel().initial_load();
Processor::allocate_idle_thread();
dprintln("ap{} initialized", Processor::current_id()); dprintln("ap{} initialized", Processor::current_id());