diff --git a/Kernel/Arch/x86/common/Processor.cpp b/Kernel/Arch/x86/common/Processor.cpp index 39e0b0a673..8c51771131 100644 --- a/Kernel/Arch/x86/common/Processor.cpp +++ b/Kernel/Arch/x86/common/Processor.cpp @@ -928,7 +928,7 @@ void Processor::enter_trap(TrapFrame& trap, bool raise_irq) // The cs register of this trap tells us where we will return back to auto new_previous_mode = ((trap.regs->cs & 3) != 0) ? Thread::PreviousMode::UserMode : Thread::PreviousMode::KernelMode; if (current_thread->set_previous_mode(new_previous_mode) && trap.prev_irq_level == 0) { - current_thread->update_time_scheduled(Scheduler::current_time(), new_previous_mode == Thread::PreviousMode::KernelMode, false); + current_thread->update_time_scheduled(TimeManagement::scheduler_current_time(), new_previous_mode == Thread::PreviousMode::KernelMode, false); } } else { trap.next_trap = nullptr; @@ -975,7 +975,7 @@ void Processor::exit_trap(TrapFrame& trap) } if (current_thread->set_previous_mode(new_previous_mode)) - current_thread->update_time_scheduled(Scheduler::current_time(), true, false); + current_thread->update_time_scheduled(TimeManagement::scheduler_current_time(), true, false); } VERIFY_INTERRUPTS_DISABLED(); diff --git a/Kernel/Scheduler.cpp b/Kernel/Scheduler.cpp index 818a3ca0c4..6335185662 100644 --- a/Kernel/Scheduler.cpp +++ b/Kernel/Scheduler.cpp @@ -8,7 +8,6 @@ #include #include #include -#include #include #include #include @@ -51,10 +50,6 @@ static Singleton> g_ready_queues; static SpinlockProtected g_total_time_scheduled { LockRank::None }; -// The Scheduler::current_time function provides a current time for scheduling purposes, -// which may not necessarily relate to wall time -u64 (*Scheduler::current_time)(); - static void dump_thread_list(bool = false); static inline u32 thread_priority_to_priority_index(u32 thread_priority) @@ -309,7 +304,7 @@ void Scheduler::enter_current(Thread& prev_thread) VERIFY(g_scheduler_lock.is_locked_by_current_processor()); // We already recorded the scheduled time when entering the trap, so this merely accounts for the kernel time since then - auto scheduler_time = Scheduler::current_time(); + auto scheduler_time = TimeManagement::scheduler_current_time(); prev_thread.update_time_scheduled(scheduler_time, true, true); auto* current_thread = Thread::current(); current_thread->update_time_scheduled(scheduler_time, true, false); @@ -366,21 +361,10 @@ Process* Scheduler::colonel() return s_colonel_process; } -static u64 current_time_monotonic() -{ - // We always need a precise timestamp here, we cannot rely on a coarse timestamp - return (u64)TimeManagement::the().monotonic_time(TimePrecision::Precise).to_nanoseconds(); -} - UNMAP_AFTER_INIT void Scheduler::initialize() { VERIFY(Processor::is_initialized()); // sanity check - - auto* possible_arch_specific_current_time_function = optional_current_time(); - if (possible_arch_specific_current_time_function) - current_time = possible_arch_specific_current_time_function; - else - current_time = current_time_monotonic; + VERIFY(TimeManagement::is_initialized()); LockRefPtr idle_thread; g_finalizer_wait_queue = new WaitQueue; @@ -440,7 +424,7 @@ void Scheduler::timer_tick(RegisterState const& regs) // Because the previous mode when entering/exiting kernel threads never changes // we never update the time scheduled. So we need to update it manually on the // timer interrupt - current_thread->update_time_scheduled(current_time(), true, false); + current_thread->update_time_scheduled(TimeManagement::scheduler_current_time(), true, false); } if (current_thread->previous_mode() == Thread::PreviousMode::UserMode && current_thread->should_die() && !current_thread->is_blocked()) { diff --git a/Kernel/Scheduler.h b/Kernel/Scheduler.h index 01882cab38..ef15c3eb85 100644 --- a/Kernel/Scheduler.h +++ b/Kernel/Scheduler.h @@ -55,7 +55,6 @@ public: static bool is_initialized(); static TotalTimeScheduled get_total_time_scheduled(); static void add_time_scheduled(u64, bool); - static u64 (*current_time)(); }; } diff --git a/Kernel/Time/TimeManagement.cpp b/Kernel/Time/TimeManagement.cpp index 4bf25c7e20..99318a918e 100644 --- a/Kernel/Time/TimeManagement.cpp +++ b/Kernel/Time/TimeManagement.cpp @@ -17,6 +17,7 @@ # include # include #endif +#include #include #include #include @@ -40,6 +41,22 @@ TimeManagement& TimeManagement::the() return *s_the; } +// The s_scheduler_specific_current_time function provides a current time for scheduling purposes, +// which may not necessarily relate to wall time +static u64 (*s_scheduler_current_time)(); + +static u64 current_time_monotonic() +{ + // We always need a precise timestamp here, we cannot rely on a coarse timestamp + return (u64)TimeManagement::the().monotonic_time(TimePrecision::Precise).to_nanoseconds(); +} + +u64 TimeManagement::scheduler_current_time() +{ + VERIFY(s_scheduler_current_time); + return s_scheduler_current_time(); +} + ErrorOr TimeManagement::validate_clock_id(clockid_t clock_id) { switch (clock_id) { @@ -163,6 +180,11 @@ UNMAP_AFTER_INIT void TimeManagement::initialize([[maybe_unused]] u32 cpu) apic_timer->enable_local_timer(); } } + auto* possible_arch_specific_current_time_function = optional_current_time(); + if (possible_arch_specific_current_time_function) + s_scheduler_current_time = possible_arch_specific_current_time_function; + else + s_scheduler_current_time = current_time_monotonic; #endif } diff --git a/Kernel/Time/TimeManagement.h b/Kernel/Time/TimeManagement.h index d2973f6f86..f5e20d0f66 100644 --- a/Kernel/Time/TimeManagement.h +++ b/Kernel/Time/TimeManagement.h @@ -37,6 +37,8 @@ public: static bool is_initialized(); static TimeManagement& the(); + static u64 scheduler_current_time(); + static ErrorOr validate_clock_id(clockid_t); Time current_time(clockid_t) const; Time monotonic_time(TimePrecision = TimePrecision::Coarse) const;