kernel: remove TimeManager

This commit is contained in:
Liam 2022-12-18 16:50:02 -05:00
parent 67c0d714c5
commit c770f25ccb
11 changed files with 33 additions and 117 deletions

View file

@ -294,8 +294,6 @@ add_library(core STATIC
hle/kernel/svc_common.h hle/kernel/svc_common.h
hle/kernel/svc_types.h hle/kernel/svc_types.h
hle/kernel/svc_wrap.h hle/kernel/svc_wrap.h
hle/kernel/time_manager.cpp
hle/kernel/time_manager.h
hle/result.h hle/result.h
hle/service/acc/acc.cpp hle/service/acc/acc.cpp
hle/service/acc/acc.h hle/service/acc/acc.h

View file

@ -10,7 +10,6 @@
#include "core/hle/kernel/k_thread_queue.h" #include "core/hle/kernel/k_thread_queue.h"
#include "core/hle/kernel/kernel.h" #include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/svc_results.h" #include "core/hle/kernel/svc_results.h"
#include "core/hle/kernel/time_manager.h"
#include "core/memory.h" #include "core/memory.h"
namespace Kernel { namespace Kernel {

View file

@ -5,15 +5,13 @@
#include "core/core_timing.h" #include "core/core_timing.h"
#include "core/hle/kernel/k_hardware_timer.h" #include "core/hle/kernel/k_hardware_timer.h"
#include "core/hle/kernel/k_scheduler.h" #include "core/hle/kernel/k_scheduler.h"
#include "core/hle/kernel/time_manager.h"
namespace Kernel { namespace Kernel {
void KHardwareTimer::Initialize() { void KHardwareTimer::Initialize() {
// Create the timing callback to register with CoreTiming. // Create the timing callback to register with CoreTiming.
m_event_type = Core::Timing::CreateEvent( m_event_type = Core::Timing::CreateEvent(
"KHardwareTimer::Callback", "KHardwareTimer::Callback", [](std::uintptr_t timer_handle, s64, std::chrono::nanoseconds) {
[this](std::uintptr_t timer_handle, s64, std::chrono::nanoseconds) {
reinterpret_cast<KHardwareTimer*>(timer_handle)->DoTask(); reinterpret_cast<KHardwareTimer*>(timer_handle)->DoTask();
return std::nullopt; return std::nullopt;
}); });
@ -21,6 +19,7 @@ void KHardwareTimer::Initialize() {
void KHardwareTimer::Finalize() { void KHardwareTimer::Finalize() {
this->DisableInterrupt(); this->DisableInterrupt();
m_event_type.reset();
} }
void KHardwareTimer::DoTask() { void KHardwareTimer::DoTask() {
@ -64,7 +63,7 @@ void KHardwareTimer::DisableInterrupt() {
m_wakeup_time = std::numeric_limits<s64>::max(); m_wakeup_time = std::numeric_limits<s64>::max();
} }
s64 KHardwareTimer::GetTick() { s64 KHardwareTimer::GetTick() const {
return m_kernel.System().CoreTiming().GetGlobalTimeNs().count(); return m_kernel.System().CoreTiming().GetGlobalTimeNs().count();
} }

View file

@ -19,10 +19,14 @@ public:
void Initialize(); void Initialize();
void Finalize(); void Finalize();
s64 GetCount() { s64 GetCount() const {
return GetTick(); return GetTick();
} }
void RegisterTask(KTimerTask* task, s64 time_from_now) {
this->RegisterAbsoluteTask(task, GetTick() + time_from_now);
}
void RegisterAbsoluteTask(KTimerTask* task, s64 task_time) { void RegisterAbsoluteTask(KTimerTask* task, s64 task_time) {
KScopedDisableDispatch dd{m_kernel}; KScopedDisableDispatch dd{m_kernel};
KScopedSpinLock lk{this->GetLock()}; KScopedSpinLock lk{this->GetLock()};
@ -38,7 +42,7 @@ private:
void EnableInterrupt(s64 wakeup_time); void EnableInterrupt(s64 wakeup_time);
void DisableInterrupt(); void DisableInterrupt();
bool GetInterruptEnabled(); bool GetInterruptEnabled();
s64 GetTick(); s64 GetTick() const;
void DoTask(); void DoTask();
private: private:

View file

@ -5,9 +5,9 @@
#include "common/common_types.h" #include "common/common_types.h"
#include "core/hle/kernel/global_scheduler_context.h" #include "core/hle/kernel/global_scheduler_context.h"
#include "core/hle/kernel/k_hardware_timer.h"
#include "core/hle/kernel/k_thread.h" #include "core/hle/kernel/k_thread.h"
#include "core/hle/kernel/kernel.h" #include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/time_manager.h"
namespace Kernel { namespace Kernel {
@ -22,7 +22,7 @@ public:
~KScopedSchedulerLockAndSleep() { ~KScopedSchedulerLockAndSleep() {
// Register the sleep. // Register the sleep.
if (timeout_tick > 0) { if (timeout_tick > 0) {
kernel.TimeManager().ScheduleTimeEvent(thread, timeout_tick); kernel.HardwareTimer().RegisterTask(thread, timeout_tick);
} }
// Unlock the scheduler. // Unlock the scheduler.

View file

@ -662,7 +662,7 @@ private:
union SyncObjectBuffer { union SyncObjectBuffer {
std::array<KSynchronizationObject*, Svc::ArgumentHandleCountMax> sync_objects{}; std::array<KSynchronizationObject*, Svc::ArgumentHandleCountMax> sync_objects{};
std::array<Handle, std::array<Handle,
Svc::ArgumentHandleCountMax * (sizeof(KSynchronizationObject*) / sizeof(Handle))> Svc::ArgumentHandleCountMax*(sizeof(KSynchronizationObject*) / sizeof(Handle))>
handles; handles;
constexpr SyncObjectBuffer() {} constexpr SyncObjectBuffer() {}
}; };
@ -683,8 +683,10 @@ private:
}; };
template <typename T> template <typename T>
requires(std::same_as<T, KThread> || std::same_as<T, RedBlackKeyType>) requires(
static constexpr int Compare(const T& lhs, const KThread& rhs) { std::same_as<T, KThread> ||
std::same_as<T, RedBlackKeyType>) static constexpr int Compare(const T& lhs,
const KThread& rhs) {
const u64 l_key = lhs.GetConditionVariableKey(); const u64 l_key = lhs.GetConditionVariableKey();
const u64 r_key = rhs.GetConditionVariableKey(); const u64 r_key = rhs.GetConditionVariableKey();

View file

@ -1,9 +1,9 @@
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
#include "core/hle/kernel/k_hardware_timer.h"
#include "core/hle/kernel/k_thread_queue.h" #include "core/hle/kernel/k_thread_queue.h"
#include "core/hle/kernel/kernel.h" #include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/time_manager.h"
namespace Kernel { namespace Kernel {
@ -22,7 +22,7 @@ void KThreadQueue::EndWait(KThread* waiting_thread, Result wait_result) {
waiting_thread->ClearWaitQueue(); waiting_thread->ClearWaitQueue();
// Cancel the thread task. // Cancel the thread task.
kernel.TimeManager().UnscheduleTimeEvent(waiting_thread); kernel.HardwareTimer().CancelTask(waiting_thread);
} }
void KThreadQueue::CancelWait(KThread* waiting_thread, Result wait_result, bool cancel_timer_task) { void KThreadQueue::CancelWait(KThread* waiting_thread, Result wait_result, bool cancel_timer_task) {
@ -37,7 +37,7 @@ void KThreadQueue::CancelWait(KThread* waiting_thread, Result wait_result, bool
// Cancel the thread task. // Cancel the thread task.
if (cancel_timer_task) { if (cancel_timer_task) {
kernel.TimeManager().UnscheduleTimeEvent(waiting_thread); kernel.HardwareTimer().CancelTask(waiting_thread);
} }
} }

View file

@ -26,6 +26,7 @@
#include "core/hle/kernel/k_client_port.h" #include "core/hle/kernel/k_client_port.h"
#include "core/hle/kernel/k_dynamic_resource_manager.h" #include "core/hle/kernel/k_dynamic_resource_manager.h"
#include "core/hle/kernel/k_handle_table.h" #include "core/hle/kernel/k_handle_table.h"
#include "core/hle/kernel/k_hardware_timer.h"
#include "core/hle/kernel/k_memory_layout.h" #include "core/hle/kernel/k_memory_layout.h"
#include "core/hle/kernel/k_memory_manager.h" #include "core/hle/kernel/k_memory_manager.h"
#include "core/hle/kernel/k_page_buffer.h" #include "core/hle/kernel/k_page_buffer.h"
@ -39,7 +40,6 @@
#include "core/hle/kernel/kernel.h" #include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/physical_core.h" #include "core/hle/kernel/physical_core.h"
#include "core/hle/kernel/service_thread.h" #include "core/hle/kernel/service_thread.h"
#include "core/hle/kernel/time_manager.h"
#include "core/hle/result.h" #include "core/hle/result.h"
#include "core/hle/service/sm/sm.h" #include "core/hle/service/sm/sm.h"
#include "core/memory.h" #include "core/memory.h"
@ -55,7 +55,7 @@ struct KernelCore::Impl {
static constexpr size_t ReservedDynamicPageCount = 64; static constexpr size_t ReservedDynamicPageCount = 64;
explicit Impl(Core::System& system_, KernelCore& kernel_) explicit Impl(Core::System& system_, KernelCore& kernel_)
: time_manager{system_}, service_threads_manager{1, "ServiceThreadsManager"}, : service_threads_manager{1, "ServiceThreadsManager"},
service_thread_barrier{2}, system{system_} {} service_thread_barrier{2}, system{system_} {}
void SetMulticore(bool is_multi) { void SetMulticore(bool is_multi) {
@ -63,6 +63,9 @@ struct KernelCore::Impl {
} }
void Initialize(KernelCore& kernel) { void Initialize(KernelCore& kernel) {
hardware_timer = std::make_unique<Kernel::KHardwareTimer>(kernel);
hardware_timer->Initialize();
global_object_list_container = std::make_unique<KAutoObjectWithListContainer>(kernel); global_object_list_container = std::make_unique<KAutoObjectWithListContainer>(kernel);
global_scheduler_context = std::make_unique<Kernel::GlobalSchedulerContext>(kernel); global_scheduler_context = std::make_unique<Kernel::GlobalSchedulerContext>(kernel);
global_handle_table = std::make_unique<Kernel::KHandleTable>(kernel); global_handle_table = std::make_unique<Kernel::KHandleTable>(kernel);
@ -193,6 +196,9 @@ struct KernelCore::Impl {
// Ensure that the object list container is finalized and properly shutdown. // Ensure that the object list container is finalized and properly shutdown.
global_object_list_container->Finalize(); global_object_list_container->Finalize();
global_object_list_container.reset(); global_object_list_container.reset();
hardware_timer->Finalize();
hardware_timer.reset();
} }
void CloseServices() { void CloseServices() {
@ -832,7 +838,7 @@ struct KernelCore::Impl {
std::vector<KProcess*> process_list; std::vector<KProcess*> process_list;
std::atomic<KProcess*> current_process{}; std::atomic<KProcess*> current_process{};
std::unique_ptr<Kernel::GlobalSchedulerContext> global_scheduler_context; std::unique_ptr<Kernel::GlobalSchedulerContext> global_scheduler_context;
Kernel::TimeManager time_manager; std::unique_ptr<Kernel::KHardwareTimer> hardware_timer;
Init::KSlabResourceCounts slab_resource_counts{}; Init::KSlabResourceCounts slab_resource_counts{};
KResourceLimit* system_resource_limit{}; KResourceLimit* system_resource_limit{};
@ -1019,12 +1025,8 @@ Kernel::KScheduler* KernelCore::CurrentScheduler() {
return impl->schedulers[core_id].get(); return impl->schedulers[core_id].get();
} }
Kernel::TimeManager& KernelCore::TimeManager() { Kernel::KHardwareTimer& KernelCore::HardwareTimer() {
return impl->time_manager; return *impl->hardware_timer;
}
const Kernel::TimeManager& KernelCore::TimeManager() const {
return impl->time_manager;
} }
Core::ExclusiveMonitor& KernelCore::GetExclusiveMonitor() { Core::ExclusiveMonitor& KernelCore::GetExclusiveMonitor() {

View file

@ -39,6 +39,7 @@ class KDynamicPageManager;
class KEvent; class KEvent;
class KEventInfo; class KEventInfo;
class KHandleTable; class KHandleTable;
class KHardwareTimer;
class KLinkedListNode; class KLinkedListNode;
class KMemoryLayout; class KMemoryLayout;
class KMemoryManager; class KMemoryManager;
@ -63,7 +64,6 @@ class KCodeMemory;
class PhysicalCore; class PhysicalCore;
class ServiceThread; class ServiceThread;
class Synchronization; class Synchronization;
class TimeManager;
using ServiceInterfaceFactory = using ServiceInterfaceFactory =
std::function<KClientPort&(Service::SM::ServiceManager&, Core::System&)>; std::function<KClientPort&(Service::SM::ServiceManager&, Core::System&)>;
@ -175,11 +175,8 @@ public:
/// Gets the an instance of the current physical CPU core. /// Gets the an instance of the current physical CPU core.
const Kernel::PhysicalCore& CurrentPhysicalCore() const; const Kernel::PhysicalCore& CurrentPhysicalCore() const;
/// Gets the an instance of the TimeManager Interface. /// Gets the an instance of the hardware timer.
Kernel::TimeManager& TimeManager(); Kernel::KHardwareTimer& HardwareTimer();
/// Gets the an instance of the TimeManager Interface.
const Kernel::TimeManager& TimeManager() const;
/// Stops execution of 'id' core, in order to reschedule a new thread. /// Stops execution of 'id' core, in order to reschedule a new thread.
void PrepareReschedule(std::size_t id); void PrepareReschedule(std::size_t id);

View file

@ -1,44 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "common/assert.h"
#include "core/core.h"
#include "core/core_timing.h"
#include "core/hle/kernel/k_scheduler.h"
#include "core/hle/kernel/k_thread.h"
#include "core/hle/kernel/time_manager.h"
namespace Kernel {
TimeManager::TimeManager(Core::System& system_) : system{system_} {
time_manager_event_type = Core::Timing::CreateEvent(
"Kernel::TimeManagerCallback",
[this](std::uintptr_t thread_handle, s64 time,
std::chrono::nanoseconds) -> std::optional<std::chrono::nanoseconds> {
KThread* thread = reinterpret_cast<KThread*>(thread_handle);
{
KScopedSchedulerLock sl(system.Kernel());
thread->OnTimer();
}
return std::nullopt;
});
}
void TimeManager::ScheduleTimeEvent(KThread* thread, s64 nanoseconds) {
std::scoped_lock lock{mutex};
if (nanoseconds > 0) {
ASSERT(thread);
ASSERT(thread->GetState() != ThreadState::Runnable);
system.CoreTiming().ScheduleEvent(std::chrono::nanoseconds{nanoseconds},
time_manager_event_type,
reinterpret_cast<uintptr_t>(thread));
}
}
void TimeManager::UnscheduleTimeEvent(KThread* thread) {
std::scoped_lock lock{mutex};
system.CoreTiming().UnscheduleEvent(time_manager_event_type,
reinterpret_cast<uintptr_t>(thread));
}
} // namespace Kernel

View file

@ -1,41 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <memory>
#include <mutex>
namespace Core {
class System;
} // namespace Core
namespace Core::Timing {
struct EventType;
} // namespace Core::Timing
namespace Kernel {
class KThread;
/**
* The `TimeManager` takes care of scheduling time events on threads and executes their TimeUp
* method when the event is triggered.
*/
class TimeManager {
public:
explicit TimeManager(Core::System& system);
/// Schedule a time event on `timetask` thread that will expire in 'nanoseconds'
void ScheduleTimeEvent(KThread* time_task, s64 nanoseconds);
/// Unschedule an existing time event
void UnscheduleTimeEvent(KThread* thread);
private:
Core::System& system;
std::shared_ptr<Core::Timing::EventType> time_manager_event_type;
std::mutex mutex;
};
} // namespace Kernel