Kernel: Scheduler now uses the new LinkedList API for moving threads

Scheduler doesn't have to depend on the fact that allocations should
work when same amount of memory is just deallocated
This commit is contained in:
Bananymous 2024-02-01 14:22:08 +02:00
parent c4bf1641bd
commit c69efc040c
2 changed files with 52 additions and 60 deletions

View File

@ -44,34 +44,26 @@ namespace Kernel
BAN::ErrorOr<void> add_thread(Thread*); BAN::ErrorOr<void> add_thread(Thread*);
private: private:
struct ActiveThread struct SchedulerThread
{ {
ActiveThread(Thread* thread) : thread(thread) {} SchedulerThread(Thread* thread)
Thread* thread; : thread(thread)
uint64_t padding; {}
};
struct SleepingThread
{
SleepingThread(Thread* thread, uint64_t wake_time) : thread(thread), wake_time(wake_time) {}
Thread* thread; Thread* thread;
union
{
uint64_t wake_time; uint64_t wake_time;
};
struct BlockingThread
{
BlockingThread(Thread* thread, Semaphore* semaphore) : thread(thread), semaphore(semaphore) {}
Thread* thread;
Semaphore* semaphore; Semaphore* semaphore;
uint8_t padding[sizeof(uint64_t) - sizeof(Semaphore*)]; };
}; };
Thread* m_idle_thread { nullptr }; Thread* m_idle_thread { nullptr };
BAN::LinkedList<ActiveThread> m_active_threads; BAN::LinkedList<SchedulerThread> m_active_threads;
BAN::LinkedList<SleepingThread> m_sleeping_threads; BAN::LinkedList<SchedulerThread> m_sleeping_threads;
BAN::LinkedList<BlockingThread> m_blocking_threads; BAN::LinkedList<SchedulerThread> m_blocking_threads;
BAN::LinkedList<ActiveThread>::iterator m_current_thread; BAN::LinkedList<SchedulerThread>::iterator m_current_thread;
friend class Process; friend class Process;
}; };

View File

@ -5,7 +5,7 @@
#include <kernel/InterruptController.h> #include <kernel/InterruptController.h>
#include <kernel/Process.h> #include <kernel/Process.h>
#include <kernel/Scheduler.h> #include <kernel/Scheduler.h>
#include <kernel/Timer/PIT.h> #include <kernel/Timer/Timer.h>
#define SCHEDULER_VERIFY_STACK 1 #define SCHEDULER_VERIFY_STACK 1
#define SCHEDULER_VERIFY_INTERRUPT_STATE 1 #define SCHEDULER_VERIFY_INTERRUPT_STATE 1
@ -116,12 +116,11 @@ namespace Kernel
uint64_t current_time = SystemTimer::get().ms_since_boot(); uint64_t current_time = SystemTimer::get().ms_since_boot();
while (!m_sleeping_threads.empty() && m_sleeping_threads.front().wake_time <= current_time) while (!m_sleeping_threads.empty() && m_sleeping_threads.front().wake_time <= current_time)
{ {
Thread* thread = m_sleeping_threads.front().thread; m_sleeping_threads.move_element_to_other_linked_list(
m_sleeping_threads.remove(m_sleeping_threads.begin()); m_active_threads,
m_active_threads.end(),
// This should work as we released enough memory from sleeping thread m_sleeping_threads.begin()
static_assert(sizeof(ActiveThread) == sizeof(SleepingThread)); );
MUST(m_active_threads.emplace_back(thread));
} }
} }
@ -286,23 +285,26 @@ namespace Kernel
ASSERT(m_current_thread); ASSERT(m_current_thread);
Thread* sleeping = m_current_thread->thread;
if (save_current_thread()) if (save_current_thread())
{ {
ENABLE_INTERRUPTS(); ENABLE_INTERRUPTS();
return; return;
} }
remove_and_advance_current_thread();
auto it = m_sleeping_threads.begin(); auto it = m_sleeping_threads.begin();
for (; it != m_sleeping_threads.end(); it++) for (; it != m_sleeping_threads.end(); it++)
if (wake_time <= it->wake_time) if (wake_time <= it->wake_time)
break; break;
// This should work as we released enough memory from active thread m_current_thread->wake_time = wake_time;
static_assert(sizeof(ActiveThread) == sizeof(SleepingThread)); m_active_threads.move_element_to_other_linked_list(
MUST(m_sleeping_threads.emplace(it, sleeping, wake_time)); m_sleeping_threads,
it,
m_current_thread
);
m_current_thread = {};
advance_current_thread();
execute_current_thread(); execute_current_thread();
ASSERT_NOT_REACHED(); ASSERT_NOT_REACHED();
@ -315,18 +317,21 @@ namespace Kernel
ASSERT(m_current_thread); ASSERT(m_current_thread);
Thread* blocking = m_current_thread->thread;
if (save_current_thread()) if (save_current_thread())
{ {
ENABLE_INTERRUPTS(); ENABLE_INTERRUPTS();
return; return;
} }
remove_and_advance_current_thread();
// This should work as we released enough memory from active thread m_current_thread->semaphore = semaphore;
static_assert(sizeof(ActiveThread) == sizeof(BlockingThread)); m_active_threads.move_element_to_other_linked_list(
MUST(m_blocking_threads.emplace_back(blocking, semaphore)); m_blocking_threads,
m_blocking_threads.end(),
m_current_thread
);
m_current_thread = {};
advance_current_thread();
execute_current_thread(); execute_current_thread();
ASSERT_NOT_REACHED(); ASSERT_NOT_REACHED();
@ -340,12 +345,11 @@ namespace Kernel
{ {
if (it->semaphore == semaphore) if (it->semaphore == semaphore)
{ {
auto thread = it->thread; it = m_blocking_threads.move_element_to_other_linked_list(
it = m_blocking_threads.remove(it); m_active_threads,
m_active_threads.end(),
// This should work as we released enough memory from active thread it
static_assert(sizeof(ActiveThread) == sizeof(BlockingThread)); );
MUST(m_active_threads.emplace_back(thread));
} }
else else
{ {
@ -362,13 +366,11 @@ namespace Kernel
{ {
if (it->thread->tid() == tid) if (it->thread->tid() == tid)
{ {
Thread* thread = it->thread; m_blocking_threads.move_element_to_other_linked_list(
m_blocking_threads.remove(it); m_active_threads,
m_active_threads.end(),
// This should work as we released enough memory from active thread it
static_assert(sizeof(ActiveThread) == sizeof(BlockingThread)); );
MUST(m_active_threads.emplace_back(thread));
return; return;
} }
} }
@ -377,13 +379,11 @@ namespace Kernel
{ {
if (it->thread->tid() == tid) if (it->thread->tid() == tid)
{ {
Thread* thread = it->thread; m_sleeping_threads.move_element_to_other_linked_list(
m_sleeping_threads.remove(it); m_active_threads,
m_active_threads.end(),
// This should work as we released enough memory from active thread it
static_assert(sizeof(ActiveThread) == sizeof(BlockingThread)); );
MUST(m_active_threads.emplace_back(thread));
return; return;
} }
} }