From e5b93741d36d3a432abc64887833544220162b66 Mon Sep 17 00:00:00 2001 From: Weiyi Wang Date: Tue, 23 Oct 2018 14:17:30 -0400 Subject: [PATCH] kernel/timer: add TimerManager for timer system states --- src/core/hle/kernel/kernel.cpp | 11 +++++++++-- src/core/hle/kernel/kernel.h | 5 +++++ src/core/hle/kernel/timer.cpp | 35 ++++++++++++++-------------------- src/core/hle/kernel/timer.h | 26 ++++++++++++++++++++----- 4 files changed, 49 insertions(+), 28 deletions(-) diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 1c324e247..c43029c37 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -22,12 +22,11 @@ KernelSystem::KernelSystem(u32 system_mode) { resource_limits = std::make_unique(*this); thread_manager = std::make_unique(); - Kernel::TimersInit(); + timer_manager = std::make_unique(); } /// Shutdown the kernel KernelSystem::~KernelSystem() { - Kernel::TimersShutdown(); Kernel::MemoryShutdown(); } @@ -59,4 +58,12 @@ const ThreadManager& KernelSystem::GetThreadManager() const { return *thread_manager; } +TimerManager& KernelSystem::GetTimerManager() { + return *timer_manager; +} + +const TimerManager& KernelSystem::GetTimerManager() const { + return *timer_manager; +} + } // namespace Kernel diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index 83f622670..5d27b2df7 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -29,6 +29,7 @@ class ServerSession; class ResourceLimitList; class SharedMemory; class ThreadManager; +class TimerManager; enum class ResetType { OneShot, @@ -191,6 +192,9 @@ public: ThreadManager& GetThreadManager(); const ThreadManager& GetThreadManager() const; + TimerManager& GetTimerManager(); + const TimerManager& GetTimerManager() const; + private: std::unique_ptr resource_limits; std::atomic next_object_id{0}; @@ -205,6 +209,7 @@ private: SharedPtr current_process; std::unique_ptr thread_manager; + std::unique_ptr timer_manager; }; } // namespace Kernel diff --git a/src/core/hle/kernel/timer.cpp b/src/core/hle/kernel/timer.cpp index d9d89abd0..07a98a659 100644 --- a/src/core/hle/kernel/timer.cpp +++ b/src/core/hle/kernel/timer.cpp @@ -6,7 +6,6 @@ #include #include "common/assert.h" #include "common/logging/log.h" -#include "core/core_timing.h" #include "core/hle/kernel/handle_table.h" #include "core/hle/kernel/object.h" #include "core/hle/kernel/thread.h" @@ -14,16 +13,10 @@ namespace Kernel { -/// The event type of the generic timer callback event -static CoreTiming::EventType* timer_callback_event_type = nullptr; - -static u64 next_timer_callback_id; -static std::unordered_map timer_callback_table; - -Timer::Timer(KernelSystem& kernel) : WaitObject(kernel) {} +Timer::Timer(KernelSystem& kernel) : WaitObject(kernel), timer_manager(kernel.GetTimerManager()) {} Timer::~Timer() { Cancel(); - timer_callback_table.erase(callback_id); + timer_manager.timer_callback_table.erase(callback_id); } SharedPtr KernelSystem::CreateTimer(ResetType reset_type, std::string name) { @@ -34,8 +27,8 @@ SharedPtr KernelSystem::CreateTimer(ResetType reset_type, std::string nam timer->name = std::move(name); timer->initial_delay = 0; timer->interval_delay = 0; - timer->callback_id = ++next_timer_callback_id; - timer_callback_table[timer->callback_id] = timer.get(); + timer->callback_id = ++timer_manager->next_timer_callback_id; + timer_manager->timer_callback_table[timer->callback_id] = timer.get(); return timer; } @@ -62,12 +55,13 @@ void Timer::Set(s64 initial, s64 interval) { // Immediately invoke the callback Signal(0); } else { - CoreTiming::ScheduleEvent(nsToCycles(initial), timer_callback_event_type, callback_id); + CoreTiming::ScheduleEvent(nsToCycles(initial), timer_manager.timer_callback_event_type, + callback_id); } } void Timer::Cancel() { - CoreTiming::UnscheduleEvent(timer_callback_event_type, callback_id); + CoreTiming::UnscheduleEvent(timer_manager.timer_callback_event_type, callback_id); } void Timer::Clear() { @@ -92,12 +86,12 @@ void Timer::Signal(s64 cycles_late) { if (interval_delay != 0) { // Reschedule the timer with the interval delay CoreTiming::ScheduleEvent(nsToCycles(interval_delay) - cycles_late, - timer_callback_event_type, callback_id); + timer_manager.timer_callback_event_type, callback_id); } } /// The timer callback event, called when a timer is fired -static void TimerCallback(u64 callback_id, s64 cycles_late) { +void TimerManager::TimerCallback(u64 callback_id, s64 cycles_late) { SharedPtr timer = timer_callback_table.at(callback_id); if (timer == nullptr) { @@ -108,12 +102,11 @@ static void TimerCallback(u64 callback_id, s64 cycles_late) { timer->Signal(cycles_late); } -void TimersInit() { - next_timer_callback_id = 0; - timer_callback_table.clear(); - timer_callback_event_type = CoreTiming::RegisterEvent("TimerCallback", TimerCallback); +TimerManager::TimerManager() { + timer_callback_event_type = + CoreTiming::RegisterEvent("TimerCallback", [this](u64 thread_id, s64 cycle_late) { + TimerCallback(thread_id, cycle_late); + }); } -void TimersShutdown() {} - } // namespace Kernel diff --git a/src/core/hle/kernel/timer.h b/src/core/hle/kernel/timer.h index 653dacb5b..e0eccaa33 100644 --- a/src/core/hle/kernel/timer.h +++ b/src/core/hle/kernel/timer.h @@ -5,11 +5,30 @@ #pragma once #include "common/common_types.h" +#include "core/core_timing.h" #include "core/hle/kernel/object.h" #include "core/hle/kernel/wait_object.h" namespace Kernel { +class TimerManager { +public: + TimerManager(); + +private: + /// The timer callback event, called when a timer is fired + void TimerCallback(u64 callback_id, s64 cycles_late); + + /// The event type of the generic timer callback event + CoreTiming::EventType* timer_callback_event_type = nullptr; + + u64 next_timer_callback_id = 0; + std::unordered_map timer_callback_table; + + friend class Timer; + friend class KernelSystem; +}; + class Timer final : public WaitObject { public: std::string GetTypeName() const override { @@ -74,12 +93,9 @@ private: /// ID used as userdata to reference this object when inserting into the CoreTiming queue. u64 callback_id; + TimerManager& timer_manager; + friend class KernelSystem; }; -/// Initializes the required variables for timers -void TimersInit(); -/// Tears down the timer variables -void TimersShutdown(); - } // namespace Kernel