diff --git a/kernel/include/kernel/Scheduler.h b/kernel/include/kernel/Scheduler.h index 1f132a9d90..95f146c00c 100644 --- a/kernel/include/kernel/Scheduler.h +++ b/kernel/include/kernel/Scheduler.h @@ -44,34 +44,26 @@ namespace Kernel BAN::ErrorOr add_thread(Thread*); private: - struct ActiveThread + struct SchedulerThread { - ActiveThread(Thread* thread) : thread(thread) {} - Thread* thread; - uint64_t padding; - }; + SchedulerThread(Thread* thread) + : thread(thread) + {} - struct SleepingThread - { - SleepingThread(Thread* thread, uint64_t wake_time) : thread(thread), wake_time(wake_time) {} Thread* thread; - uint64_t wake_time; - }; - - struct BlockingThread - { - BlockingThread(Thread* thread, Semaphore* semaphore) : thread(thread), semaphore(semaphore) {} - Thread* thread; - Semaphore* semaphore; - uint8_t padding[sizeof(uint64_t) - sizeof(Semaphore*)]; + union + { + uint64_t wake_time; + Semaphore* semaphore; + }; }; Thread* m_idle_thread { nullptr }; - BAN::LinkedList m_active_threads; - BAN::LinkedList m_sleeping_threads; - BAN::LinkedList m_blocking_threads; + BAN::LinkedList m_active_threads; + BAN::LinkedList m_sleeping_threads; + BAN::LinkedList m_blocking_threads; - BAN::LinkedList::iterator m_current_thread; + BAN::LinkedList::iterator m_current_thread; friend class Process; }; diff --git a/kernel/kernel/Scheduler.cpp b/kernel/kernel/Scheduler.cpp index c1dffbed1c..42000b5314 100644 --- a/kernel/kernel/Scheduler.cpp +++ b/kernel/kernel/Scheduler.cpp @@ -5,7 +5,7 @@ #include #include #include -#include +#include #define SCHEDULER_VERIFY_STACK 1 #define SCHEDULER_VERIFY_INTERRUPT_STATE 1 @@ -116,12 +116,11 @@ namespace Kernel uint64_t current_time = SystemTimer::get().ms_since_boot(); while (!m_sleeping_threads.empty() && m_sleeping_threads.front().wake_time <= current_time) { - Thread* thread = m_sleeping_threads.front().thread; - m_sleeping_threads.remove(m_sleeping_threads.begin()); - - // This should work as we released enough memory from sleeping thread - static_assert(sizeof(ActiveThread) == sizeof(SleepingThread)); - MUST(m_active_threads.emplace_back(thread)); + m_sleeping_threads.move_element_to_other_linked_list( + m_active_threads, + m_active_threads.end(), + m_sleeping_threads.begin() + ); } } @@ -286,23 +285,26 @@ namespace Kernel ASSERT(m_current_thread); - Thread* sleeping = m_current_thread->thread; - if (save_current_thread()) { ENABLE_INTERRUPTS(); return; } - remove_and_advance_current_thread(); auto it = m_sleeping_threads.begin(); for (; it != m_sleeping_threads.end(); it++) if (wake_time <= it->wake_time) break; - // This should work as we released enough memory from active thread - static_assert(sizeof(ActiveThread) == sizeof(SleepingThread)); - MUST(m_sleeping_threads.emplace(it, sleeping, wake_time)); + m_current_thread->wake_time = wake_time; + m_active_threads.move_element_to_other_linked_list( + m_sleeping_threads, + it, + m_current_thread + ); + + m_current_thread = {}; + advance_current_thread(); execute_current_thread(); ASSERT_NOT_REACHED(); @@ -315,18 +317,21 @@ namespace Kernel ASSERT(m_current_thread); - Thread* blocking = m_current_thread->thread; - if (save_current_thread()) { ENABLE_INTERRUPTS(); return; } - remove_and_advance_current_thread(); - // This should work as we released enough memory from active thread - static_assert(sizeof(ActiveThread) == sizeof(BlockingThread)); - MUST(m_blocking_threads.emplace_back(blocking, semaphore)); + m_current_thread->semaphore = semaphore; + m_active_threads.move_element_to_other_linked_list( + m_blocking_threads, + m_blocking_threads.end(), + m_current_thread + ); + + m_current_thread = {}; + advance_current_thread(); execute_current_thread(); ASSERT_NOT_REACHED(); @@ -340,12 +345,11 @@ namespace Kernel { if (it->semaphore == semaphore) { - auto thread = it->thread; - it = m_blocking_threads.remove(it); - - // This should work as we released enough memory from active thread - static_assert(sizeof(ActiveThread) == sizeof(BlockingThread)); - MUST(m_active_threads.emplace_back(thread)); + it = m_blocking_threads.move_element_to_other_linked_list( + m_active_threads, + m_active_threads.end(), + it + ); } else { @@ -362,13 +366,11 @@ namespace Kernel { if (it->thread->tid() == tid) { - Thread* thread = it->thread; - m_blocking_threads.remove(it); - - // This should work as we released enough memory from active thread - static_assert(sizeof(ActiveThread) == sizeof(BlockingThread)); - MUST(m_active_threads.emplace_back(thread)); - + m_blocking_threads.move_element_to_other_linked_list( + m_active_threads, + m_active_threads.end(), + it + ); return; } } @@ -377,13 +379,11 @@ namespace Kernel { if (it->thread->tid() == tid) { - Thread* thread = it->thread; - m_sleeping_threads.remove(it); - - // This should work as we released enough memory from active thread - static_assert(sizeof(ActiveThread) == sizeof(BlockingThread)); - MUST(m_active_threads.emplace_back(thread)); - + m_sleeping_threads.move_element_to_other_linked_list( + m_active_threads, + m_active_threads.end(), + it + ); return; } }