diff options
| author | 2020-02-14 10:56:27 -0400 | |
|---|---|---|
| committer | 2020-02-22 11:18:07 -0400 | |
| commit | 5c90d22f3d92b9be818b19e03dd57eb217eb6567 (patch) | |
| tree | 206a925ef68687d7b90e2b11d9d68bc42f2ce9d3 | |
| parent | Kernel: Rename ThreadCallbackHandleTable and Setup Thread Ids on Kernel. (diff) | |
| download | yuzu-5c90d22f3d92b9be818b19e03dd57eb217eb6567.tar.gz yuzu-5c90d22f3d92b9be818b19e03dd57eb217eb6567.tar.xz yuzu-5c90d22f3d92b9be818b19e03dd57eb217eb6567.zip | |
Kernel: Implement Time Manager.
| -rw-r--r-- | src/core/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | src/core/hle/kernel/kernel.cpp | 12 | ||||
| -rw-r--r-- | src/core/hle/kernel/kernel.h | 7 | ||||
| -rw-r--r-- | src/core/hle/kernel/time_manager.cpp | 42 | ||||
| -rw-r--r-- | src/core/hle/kernel/time_manager.h | 36 |
5 files changed, 98 insertions, 1 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 26612e692..88c06b2ce 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt | |||
| @@ -187,6 +187,8 @@ add_library(core STATIC | |||
| 187 | hle/kernel/synchronization.h | 187 | hle/kernel/synchronization.h |
| 188 | hle/kernel/thread.cpp | 188 | hle/kernel/thread.cpp |
| 189 | hle/kernel/thread.h | 189 | hle/kernel/thread.h |
| 190 | hle/kernel/time_manager.cpp | ||
| 191 | hle/kernel/time_manager.h | ||
| 190 | hle/kernel/transfer_memory.cpp | 192 | hle/kernel/transfer_memory.cpp |
| 191 | hle/kernel/transfer_memory.h | 193 | hle/kernel/transfer_memory.h |
| 192 | hle/kernel/vm_manager.cpp | 194 | hle/kernel/vm_manager.cpp |
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index b3a5d7505..de14e1936 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp | |||
| @@ -27,6 +27,7 @@ | |||
| 27 | #include "core/hle/kernel/scheduler.h" | 27 | #include "core/hle/kernel/scheduler.h" |
| 28 | #include "core/hle/kernel/synchronization.h" | 28 | #include "core/hle/kernel/synchronization.h" |
| 29 | #include "core/hle/kernel/thread.h" | 29 | #include "core/hle/kernel/thread.h" |
| 30 | #include "core/hle/kernel/time_manager.h" | ||
| 30 | #include "core/hle/lock.h" | 31 | #include "core/hle/lock.h" |
| 31 | #include "core/hle/result.h" | 32 | #include "core/hle/result.h" |
| 32 | #include "core/memory.h" | 33 | #include "core/memory.h" |
| @@ -100,7 +101,7 @@ static void ThreadWakeupCallback(u64 thread_handle, [[maybe_unused]] s64 cycles_ | |||
| 100 | 101 | ||
| 101 | struct KernelCore::Impl { | 102 | struct KernelCore::Impl { |
| 102 | explicit Impl(Core::System& system, KernelCore& kernel) | 103 | explicit Impl(Core::System& system, KernelCore& kernel) |
| 103 | : system{system}, global_scheduler{kernel}, synchronization{system} {} | 104 | : system{system}, global_scheduler{kernel}, synchronization{system}, time_manager{system} {} |
| 104 | 105 | ||
| 105 | void Initialize(KernelCore& kernel) { | 106 | void Initialize(KernelCore& kernel) { |
| 106 | Shutdown(); | 107 | Shutdown(); |
| @@ -238,6 +239,7 @@ struct KernelCore::Impl { | |||
| 238 | Process* current_process = nullptr; | 239 | Process* current_process = nullptr; |
| 239 | Kernel::GlobalScheduler global_scheduler; | 240 | Kernel::GlobalScheduler global_scheduler; |
| 240 | Kernel::Synchronization synchronization; | 241 | Kernel::Synchronization synchronization; |
| 242 | Kernel::TimeManager time_manager; | ||
| 241 | 243 | ||
| 242 | std::shared_ptr<ResourceLimit> system_resource_limit; | 244 | std::shared_ptr<ResourceLimit> system_resource_limit; |
| 243 | 245 | ||
| @@ -337,6 +339,14 @@ const Kernel::Synchronization& KernelCore::Synchronization() const { | |||
| 337 | return impl->synchronization; | 339 | return impl->synchronization; |
| 338 | } | 340 | } |
| 339 | 341 | ||
| 342 | Kernel::TimeManager& KernelCore::TimeManager() { | ||
| 343 | return impl->time_manager; | ||
| 344 | } | ||
| 345 | |||
| 346 | const Kernel::TimeManager& KernelCore::TimeManager() const { | ||
| 347 | return impl->time_manager; | ||
| 348 | } | ||
| 349 | |||
| 340 | Core::ExclusiveMonitor& KernelCore::GetExclusiveMonitor() { | 350 | Core::ExclusiveMonitor& KernelCore::GetExclusiveMonitor() { |
| 341 | return *impl->exclusive_monitor; | 351 | return *impl->exclusive_monitor; |
| 342 | } | 352 | } |
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index c5e05f7b6..76fd12ace 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h | |||
| @@ -33,6 +33,7 @@ class ResourceLimit; | |||
| 33 | class Scheduler; | 33 | class Scheduler; |
| 34 | class Synchronization; | 34 | class Synchronization; |
| 35 | class Thread; | 35 | class Thread; |
| 36 | class TimeManager; | ||
| 36 | 37 | ||
| 37 | /// Represents a single instance of the kernel. | 38 | /// Represents a single instance of the kernel. |
| 38 | class KernelCore { | 39 | class KernelCore { |
| @@ -107,6 +108,12 @@ public: | |||
| 107 | /// Gets the an instance of the Synchronization Interface. | 108 | /// Gets the an instance of the Synchronization Interface. |
| 108 | const Kernel::Synchronization& Synchronization() const; | 109 | const Kernel::Synchronization& Synchronization() const; |
| 109 | 110 | ||
| 111 | /// Gets the an instance of the TimeManager Interface. | ||
| 112 | Kernel::TimeManager& TimeManager(); | ||
| 113 | |||
| 114 | /// Gets the an instance of the TimeManager Interface. | ||
| 115 | const Kernel::TimeManager& TimeManager() const; | ||
| 116 | |||
| 110 | /// Stops execution of 'id' core, in order to reschedule a new thread. | 117 | /// Stops execution of 'id' core, in order to reschedule a new thread. |
| 111 | void PrepareReschedule(std::size_t id); | 118 | void PrepareReschedule(std::size_t id); |
| 112 | 119 | ||
diff --git a/src/core/hle/kernel/time_manager.cpp b/src/core/hle/kernel/time_manager.cpp new file mode 100644 index 000000000..0b3e464d0 --- /dev/null +++ b/src/core/hle/kernel/time_manager.cpp | |||
| @@ -0,0 +1,42 @@ | |||
| 1 | // Copyright 2020 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include "core/core.h" | ||
| 6 | #include "core/core_timing.h" | ||
| 7 | #include "core/core_timing_util.h" | ||
| 8 | #include "core/hle/kernel/handle_table.h" | ||
| 9 | #include "core/hle/kernel/kernel.h" | ||
| 10 | #include "core/hle/kernel/thread.h" | ||
| 11 | #include "core/hle/kernel/time_manager.h" | ||
| 12 | |||
| 13 | namespace Kernel { | ||
| 14 | |||
| 15 | TimeManager::TimeManager(Core::System& system) : system{system} { | ||
| 16 | time_manager_event_type = Core::Timing::CreateEvent( | ||
| 17 | "Kernel::TimeManagerCallback", [this](u64 thread_handle, [[maybe_unused]] s64 cycles_late) { | ||
| 18 | Handle proper_handle = static_cast<Handle>(thread_handle); | ||
| 19 | std::shared_ptr<Thread> thread = | ||
| 20 | this->system.Kernel().RetrieveThreadFromGlobalHandleTable(proper_handle); | ||
| 21 | thread->ResumeFromWait(); | ||
| 22 | }); | ||
| 23 | } | ||
| 24 | |||
| 25 | void TimeManager::ScheduleTimeEvent(Handle& event_handle, Thread* timetask, s64 nanoseconds) { | ||
| 26 | if (nanoseconds > 0) { | ||
| 27 | ASSERT(timetask); | ||
| 28 | event_handle = timetask->GetGlobalHandle(); | ||
| 29 | const s64 cycles = Core::Timing::nsToCycles(std::chrono::nanoseconds{nanoseconds}); | ||
| 30 | system.CoreTiming().ScheduleEvent(cycles, time_manager_event_type, event_handle); | ||
| 31 | } else { | ||
| 32 | event_handle = InvalidHandle; | ||
| 33 | } | ||
| 34 | } | ||
| 35 | |||
| 36 | void TimeManager::UnscheduleTimeEvent(Handle event_handle) { | ||
| 37 | if (event_handle != InvalidHandle) { | ||
| 38 | system.CoreTiming().UnscheduleEvent(time_manager_event_type, event_handle); | ||
| 39 | } | ||
| 40 | } | ||
| 41 | |||
| 42 | } // namespace Kernel | ||
diff --git a/src/core/hle/kernel/time_manager.h b/src/core/hle/kernel/time_manager.h new file mode 100644 index 000000000..b760311f1 --- /dev/null +++ b/src/core/hle/kernel/time_manager.h | |||
| @@ -0,0 +1,36 @@ | |||
| 1 | // Copyright 2020 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <memory> | ||
| 8 | |||
| 9 | #include "core/hle/kernel/object.h" | ||
| 10 | |||
| 11 | namespace Core { | ||
| 12 | class System; | ||
| 13 | } // namespace Core | ||
| 14 | |||
| 15 | namespace Core::Timing { | ||
| 16 | struct EventType; | ||
| 17 | } // namespace Core::Timing | ||
| 18 | |||
| 19 | namespace Kernel { | ||
| 20 | |||
| 21 | class Thread; | ||
| 22 | |||
| 23 | class TimeManager { | ||
| 24 | public: | ||
| 25 | TimeManager(Core::System& system); | ||
| 26 | |||
| 27 | void ScheduleTimeEvent(Handle& event_handle, Thread* timetask, s64 nanoseconds); | ||
| 28 | |||
| 29 | void UnscheduleTimeEvent(Handle event_handle); | ||
| 30 | |||
| 31 | private: | ||
| 32 | Core::System& system; | ||
| 33 | std::shared_ptr<Core::Timing::EventType> time_manager_event_type; | ||
| 34 | }; | ||
| 35 | |||
| 36 | } // namespace Kernel | ||