Kernel: Move current and idle thread to Processor
This commit is contained in:
parent
e636dce919
commit
2420886c2c
|
@ -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>;
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 ¤t->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 = ¤t_thread();
|
current = ¤t_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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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());
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue