#pragma once #include #include #include namespace Kernel { class Scheduler { public: static BAN::ErrorOr initialize(); static Scheduler& get(); [[noreturn]] void start(); void timer_reschedule(); void reschedule(); void reschedule_if_idling(); void set_current_thread_sleeping(uint64_t); void block_current_thread(Semaphore*); void unblock_threads(Semaphore*); void unblock_thread(pid_t tid); Thread& current_thread(); static pid_t current_tid(); static bool is_valid_tid(pid_t tid); [[noreturn]] void delete_current_process_and_thread(); private: Scheduler() = default; void wake_threads(); [[nodiscard]] bool save_current_thread(); void remove_and_advance_current_thread(); void advance_current_thread(); [[noreturn]] void execute_current_thread(); BAN::ErrorOr add_thread(Thread*); private: struct ActiveThread { ActiveThread(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; 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*)]; }; Thread* m_idle_thread { nullptr }; BAN::LinkedList m_active_threads; BAN::LinkedList m_sleeping_threads; BAN::LinkedList m_blocking_threads; BAN::LinkedList::iterator m_current_thread; uint64_t m_last_reschedule = 0; friend class Thread; friend class Process; }; }