From 3651d9701e2a91b5c13012bdd3fbcf333ae2369a Mon Sep 17 00:00:00 2001 From: Liav A Date: Sat, 8 Oct 2022 04:27:48 +0300 Subject: [PATCH] Kernel: Abstract platform-specific current time methods from Scheduler This change ensures that the scheduler doesn't depend on a platform specific or arch-specific code when it initializes itself, but rather we ensure that in compile-time we will generate the appropriate code to find the correct arch-specific current time methods. --- Kernel/Arch/CurrentTime.h | 17 +++++++++++++++++ Kernel/Arch/aarch64/CurrentTime.cpp | 18 ++++++++++++++++++ Kernel/Arch/x86/CurrentTime.cpp | 28 ++++++++++++++++++++++++++++ Kernel/CMakeLists.txt | 3 +++ Kernel/Scheduler.cpp | 16 +++++----------- 5 files changed, 71 insertions(+), 11 deletions(-) create mode 100644 Kernel/Arch/CurrentTime.h create mode 100644 Kernel/Arch/aarch64/CurrentTime.cpp create mode 100644 Kernel/Arch/x86/CurrentTime.cpp diff --git a/Kernel/Arch/CurrentTime.h b/Kernel/Arch/CurrentTime.h new file mode 100644 index 0000000000..b5ca112ebe --- /dev/null +++ b/Kernel/Arch/CurrentTime.h @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2022, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include + +namespace Kernel { + +typedef u64 (*fptr)(); + +fptr optional_current_time(); + +} diff --git a/Kernel/Arch/aarch64/CurrentTime.cpp b/Kernel/Arch/aarch64/CurrentTime.cpp new file mode 100644 index 0000000000..b4a97564c3 --- /dev/null +++ b/Kernel/Arch/aarch64/CurrentTime.cpp @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2022, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include + +namespace Kernel { + +fptr optional_current_time() +{ + return nullptr; +} + +} diff --git a/Kernel/Arch/x86/CurrentTime.cpp b/Kernel/Arch/x86/CurrentTime.cpp new file mode 100644 index 0000000000..3963263ab4 --- /dev/null +++ b/Kernel/Arch/x86/CurrentTime.cpp @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2022, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include + +namespace Kernel { + +static u64 current_time_tsc() +{ + return read_tsc(); +} + +fptr optional_current_time() +{ + VERIFY(Processor::is_initialized()); // sanity check + // Figure out a good scheduling time source + if (Processor::current().has_feature(CPUFeature::TSC) && Processor::current().has_feature(CPUFeature::CONSTANT_TSC)) { + return current_time_tsc; + } + return nullptr; +} + +} diff --git a/Kernel/CMakeLists.txt b/Kernel/CMakeLists.txt index cf30b1cd20..02ed2d5c03 100644 --- a/Kernel/CMakeLists.txt +++ b/Kernel/CMakeLists.txt @@ -327,6 +327,8 @@ if ("${SERENITY_ARCH}" STREQUAL "i686" OR "${SERENITY_ARCH}" STREQUAL "x86_64") Arch/x86/common/SmapDisabler.cpp Arch/x86/common/Shutdown.cpp + Arch/x86/CurrentTime.cpp + Arch/x86/Hypervisor/BochsDisplayConnector.cpp Arch/x86/Hypervisor/VMWareBackdoor.cpp @@ -477,6 +479,7 @@ else() Arch/aarch64/boot.S Arch/aarch64/BootPPMParser.cpp Arch/aarch64/CrashHandler.cpp + Arch/aarch64/CurrentTime.cpp Arch/aarch64/Dummy.cpp Arch/aarch64/Exceptions.cpp Arch/aarch64/init.cpp diff --git a/Kernel/Scheduler.cpp b/Kernel/Scheduler.cpp index 11336d9212..818a3ca0c4 100644 --- a/Kernel/Scheduler.cpp +++ b/Kernel/Scheduler.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -365,11 +366,6 @@ Process* Scheduler::colonel() return s_colonel_process; } -static u64 current_time_tsc() -{ - return read_tsc(); -} - static u64 current_time_monotonic() { // We always need a precise timestamp here, we cannot rely on a coarse timestamp @@ -380,13 +376,11 @@ UNMAP_AFTER_INIT void Scheduler::initialize() { VERIFY(Processor::is_initialized()); // sanity check - // Figure out a good scheduling time source - if (Processor::current().has_feature(CPUFeature::TSC) && Processor::current().has_feature(CPUFeature::CONSTANT_TSC)) { - current_time = current_time_tsc; - } else { - // TODO: Using HPET is rather slow, can we use any other time source that may be faster? + 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; - } LockRefPtr idle_thread; g_finalizer_wait_queue = new WaitQueue;