diff options
| author | 2019-02-14 12:42:58 -0500 | |
|---|---|---|
| committer | 2019-02-15 21:50:25 -0500 | |
| commit | bd983414f643b734a1f8bebe3183723733344f72 (patch) | |
| tree | bda0421458439e25cba9d772a6a79b56e473d72e /src/core/hle/kernel | |
| parent | Merge pull request #2113 from ReinUsesLisp/vulkan-base (diff) | |
| download | yuzu-bd983414f643b734a1f8bebe3183723733344f72.tar.gz yuzu-bd983414f643b734a1f8bebe3183723733344f72.tar.xz yuzu-bd983414f643b734a1f8bebe3183723733344f72.zip | |
core_timing: Convert core timing into a class
Gets rid of the largest set of mutable global state within the core.
This also paves a way for eliminating usages of GetInstance() on the
System class as a follow-up.
Note that no behavioral changes have been made, and this simply extracts
the functionality into a class. This also has the benefit of making
dependencies on the core timing functionality explicit within the
relevant interfaces.
Diffstat (limited to 'src/core/hle/kernel')
| -rw-r--r-- | src/core/hle/kernel/kernel.cpp | 12 | ||||
| -rw-r--r-- | src/core/hle/kernel/kernel.h | 9 | ||||
| -rw-r--r-- | src/core/hle/kernel/scheduler.cpp | 2 | ||||
| -rw-r--r-- | src/core/hle/kernel/svc.cpp | 10 | ||||
| -rw-r--r-- | src/core/hle/kernel/thread.cpp | 19 |
5 files changed, 31 insertions, 21 deletions
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 3721ae8fe..dd749eed4 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp | |||
| @@ -86,11 +86,11 @@ static void ThreadWakeupCallback(u64 thread_handle, [[maybe_unused]] int cycles_ | |||
| 86 | } | 86 | } |
| 87 | 87 | ||
| 88 | struct KernelCore::Impl { | 88 | struct KernelCore::Impl { |
| 89 | void Initialize(KernelCore& kernel) { | 89 | void Initialize(KernelCore& kernel, Core::Timing::CoreTiming& core_timing) { |
| 90 | Shutdown(); | 90 | Shutdown(); |
| 91 | 91 | ||
| 92 | InitializeSystemResourceLimit(kernel); | 92 | InitializeSystemResourceLimit(kernel); |
| 93 | InitializeThreads(); | 93 | InitializeThreads(core_timing); |
| 94 | } | 94 | } |
| 95 | 95 | ||
| 96 | void Shutdown() { | 96 | void Shutdown() { |
| @@ -122,9 +122,9 @@ struct KernelCore::Impl { | |||
| 122 | ASSERT(system_resource_limit->SetLimitValue(ResourceType::Sessions, 900).IsSuccess()); | 122 | ASSERT(system_resource_limit->SetLimitValue(ResourceType::Sessions, 900).IsSuccess()); |
| 123 | } | 123 | } |
| 124 | 124 | ||
| 125 | void InitializeThreads() { | 125 | void InitializeThreads(Core::Timing::CoreTiming& core_timing) { |
| 126 | thread_wakeup_event_type = | 126 | thread_wakeup_event_type = |
| 127 | Core::Timing::RegisterEvent("ThreadWakeupCallback", ThreadWakeupCallback); | 127 | core_timing.RegisterEvent("ThreadWakeupCallback", ThreadWakeupCallback); |
| 128 | } | 128 | } |
| 129 | 129 | ||
| 130 | std::atomic<u32> next_object_id{0}; | 130 | std::atomic<u32> next_object_id{0}; |
| @@ -152,8 +152,8 @@ KernelCore::~KernelCore() { | |||
| 152 | Shutdown(); | 152 | Shutdown(); |
| 153 | } | 153 | } |
| 154 | 154 | ||
| 155 | void KernelCore::Initialize() { | 155 | void KernelCore::Initialize(Core::Timing::CoreTiming& core_timing) { |
| 156 | impl->Initialize(*this); | 156 | impl->Initialize(*this, core_timing); |
| 157 | } | 157 | } |
| 158 | 158 | ||
| 159 | void KernelCore::Shutdown() { | 159 | void KernelCore::Shutdown() { |
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index 7406f107e..154bced42 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h | |||
| @@ -12,8 +12,9 @@ template <typename T> | |||
| 12 | class ResultVal; | 12 | class ResultVal; |
| 13 | 13 | ||
| 14 | namespace Core::Timing { | 14 | namespace Core::Timing { |
| 15 | class CoreTiming; | ||
| 15 | struct EventType; | 16 | struct EventType; |
| 16 | } | 17 | } // namespace Core::Timing |
| 17 | 18 | ||
| 18 | namespace Kernel { | 19 | namespace Kernel { |
| 19 | 20 | ||
| @@ -39,7 +40,11 @@ public: | |||
| 39 | KernelCore& operator=(KernelCore&&) = delete; | 40 | KernelCore& operator=(KernelCore&&) = delete; |
| 40 | 41 | ||
| 41 | /// Resets the kernel to a clean slate for use. | 42 | /// Resets the kernel to a clean slate for use. |
| 42 | void Initialize(); | 43 | /// |
| 44 | /// @param core_timing CoreTiming instance used to create any necessary | ||
| 45 | /// kernel-specific callback events. | ||
| 46 | /// | ||
| 47 | void Initialize(Core::Timing::CoreTiming& core_timing); | ||
| 43 | 48 | ||
| 44 | /// Clears all resources in use by the kernel instance. | 49 | /// Clears all resources in use by the kernel instance. |
| 45 | void Shutdown(); | 50 | void Shutdown(); |
diff --git a/src/core/hle/kernel/scheduler.cpp b/src/core/hle/kernel/scheduler.cpp index 9e2517e1b..44f30d070 100644 --- a/src/core/hle/kernel/scheduler.cpp +++ b/src/core/hle/kernel/scheduler.cpp | |||
| @@ -111,7 +111,7 @@ void Scheduler::SwitchContext(Thread* new_thread) { | |||
| 111 | 111 | ||
| 112 | void Scheduler::UpdateLastContextSwitchTime(Thread* thread, Process* process) { | 112 | void Scheduler::UpdateLastContextSwitchTime(Thread* thread, Process* process) { |
| 113 | const u64 prev_switch_ticks = last_context_switch_time; | 113 | const u64 prev_switch_ticks = last_context_switch_time; |
| 114 | const u64 most_recent_switch_ticks = Core::Timing::GetTicks(); | 114 | const u64 most_recent_switch_ticks = Core::System::GetInstance().CoreTiming().GetTicks(); |
| 115 | const u64 update_ticks = most_recent_switch_ticks - prev_switch_ticks; | 115 | const u64 update_ticks = most_recent_switch_ticks - prev_switch_ticks; |
| 116 | 116 | ||
| 117 | if (thread != nullptr) { | 117 | if (thread != nullptr) { |
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 5f040f79f..c5d399bab 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp | |||
| @@ -918,6 +918,7 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id) | |||
| 918 | } | 918 | } |
| 919 | 919 | ||
| 920 | const auto& system = Core::System::GetInstance(); | 920 | const auto& system = Core::System::GetInstance(); |
| 921 | const auto& core_timing = system.CoreTiming(); | ||
| 921 | const auto& scheduler = system.CurrentScheduler(); | 922 | const auto& scheduler = system.CurrentScheduler(); |
| 922 | const auto* const current_thread = scheduler.GetCurrentThread(); | 923 | const auto* const current_thread = scheduler.GetCurrentThread(); |
| 923 | const bool same_thread = current_thread == thread; | 924 | const bool same_thread = current_thread == thread; |
| @@ -927,9 +928,9 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id) | |||
| 927 | if (same_thread && info_sub_id == 0xFFFFFFFFFFFFFFFF) { | 928 | if (same_thread && info_sub_id == 0xFFFFFFFFFFFFFFFF) { |
| 928 | const u64 thread_ticks = current_thread->GetTotalCPUTimeTicks(); | 929 | const u64 thread_ticks = current_thread->GetTotalCPUTimeTicks(); |
| 929 | 930 | ||
| 930 | out_ticks = thread_ticks + (Core::Timing::GetTicks() - prev_ctx_ticks); | 931 | out_ticks = thread_ticks + (core_timing.GetTicks() - prev_ctx_ticks); |
| 931 | } else if (same_thread && info_sub_id == system.CurrentCoreIndex()) { | 932 | } else if (same_thread && info_sub_id == system.CurrentCoreIndex()) { |
| 932 | out_ticks = Core::Timing::GetTicks() - prev_ctx_ticks; | 933 | out_ticks = core_timing.GetTicks() - prev_ctx_ticks; |
| 933 | } | 934 | } |
| 934 | 935 | ||
| 935 | *result = out_ticks; | 936 | *result = out_ticks; |
| @@ -1546,10 +1547,11 @@ static ResultCode SignalToAddress(VAddr address, u32 type, s32 value, s32 num_to | |||
| 1546 | static u64 GetSystemTick() { | 1547 | static u64 GetSystemTick() { |
| 1547 | LOG_TRACE(Kernel_SVC, "called"); | 1548 | LOG_TRACE(Kernel_SVC, "called"); |
| 1548 | 1549 | ||
| 1549 | const u64 result{Core::Timing::GetTicks()}; | 1550 | auto& core_timing = Core::System::GetInstance().CoreTiming(); |
| 1551 | const u64 result{core_timing.GetTicks()}; | ||
| 1550 | 1552 | ||
| 1551 | // Advance time to defeat dumb games that busy-wait for the frame to end. | 1553 | // Advance time to defeat dumb games that busy-wait for the frame to end. |
| 1552 | Core::Timing::AddTicks(400); | 1554 | core_timing.AddTicks(400); |
| 1553 | 1555 | ||
| 1554 | return result; | 1556 | return result; |
| 1555 | } | 1557 | } |
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 7881c2b90..6661e2130 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp | |||
| @@ -43,7 +43,8 @@ Thread::~Thread() = default; | |||
| 43 | 43 | ||
| 44 | void Thread::Stop() { | 44 | void Thread::Stop() { |
| 45 | // Cancel any outstanding wakeup events for this thread | 45 | // Cancel any outstanding wakeup events for this thread |
| 46 | Core::Timing::UnscheduleEvent(kernel.ThreadWakeupCallbackEventType(), callback_handle); | 46 | Core::System::GetInstance().CoreTiming().UnscheduleEvent(kernel.ThreadWakeupCallbackEventType(), |
| 47 | callback_handle); | ||
| 47 | kernel.ThreadWakeupCallbackHandleTable().Close(callback_handle); | 48 | kernel.ThreadWakeupCallbackHandleTable().Close(callback_handle); |
| 48 | callback_handle = 0; | 49 | callback_handle = 0; |
| 49 | 50 | ||
| @@ -85,13 +86,14 @@ void Thread::WakeAfterDelay(s64 nanoseconds) { | |||
| 85 | 86 | ||
| 86 | // This function might be called from any thread so we have to be cautious and use the | 87 | // This function might be called from any thread so we have to be cautious and use the |
| 87 | // thread-safe version of ScheduleEvent. | 88 | // thread-safe version of ScheduleEvent. |
| 88 | Core::Timing::ScheduleEventThreadsafe(Core::Timing::nsToCycles(nanoseconds), | 89 | Core::System::GetInstance().CoreTiming().ScheduleEventThreadsafe( |
| 89 | kernel.ThreadWakeupCallbackEventType(), callback_handle); | 90 | Core::Timing::nsToCycles(nanoseconds), kernel.ThreadWakeupCallbackEventType(), |
| 91 | callback_handle); | ||
| 90 | } | 92 | } |
| 91 | 93 | ||
| 92 | void Thread::CancelWakeupTimer() { | 94 | void Thread::CancelWakeupTimer() { |
| 93 | Core::Timing::UnscheduleEventThreadsafe(kernel.ThreadWakeupCallbackEventType(), | 95 | Core::System::GetInstance().CoreTiming().UnscheduleEventThreadsafe( |
| 94 | callback_handle); | 96 | kernel.ThreadWakeupCallbackEventType(), callback_handle); |
| 95 | } | 97 | } |
| 96 | 98 | ||
| 97 | static std::optional<s32> GetNextProcessorId(u64 mask) { | 99 | static std::optional<s32> GetNextProcessorId(u64 mask) { |
| @@ -190,6 +192,7 @@ ResultVal<SharedPtr<Thread>> Thread::Create(KernelCore& kernel, std::string name | |||
| 190 | return ResultCode(-1); | 192 | return ResultCode(-1); |
| 191 | } | 193 | } |
| 192 | 194 | ||
| 195 | auto& system = Core::System::GetInstance(); | ||
| 193 | SharedPtr<Thread> thread(new Thread(kernel)); | 196 | SharedPtr<Thread> thread(new Thread(kernel)); |
| 194 | 197 | ||
| 195 | thread->thread_id = kernel.CreateNewThreadID(); | 198 | thread->thread_id = kernel.CreateNewThreadID(); |
| @@ -198,7 +201,7 @@ ResultVal<SharedPtr<Thread>> Thread::Create(KernelCore& kernel, std::string name | |||
| 198 | thread->stack_top = stack_top; | 201 | thread->stack_top = stack_top; |
| 199 | thread->tpidr_el0 = 0; | 202 | thread->tpidr_el0 = 0; |
| 200 | thread->nominal_priority = thread->current_priority = priority; | 203 | thread->nominal_priority = thread->current_priority = priority; |
| 201 | thread->last_running_ticks = Core::Timing::GetTicks(); | 204 | thread->last_running_ticks = system.CoreTiming().GetTicks(); |
| 202 | thread->processor_id = processor_id; | 205 | thread->processor_id = processor_id; |
| 203 | thread->ideal_core = processor_id; | 206 | thread->ideal_core = processor_id; |
| 204 | thread->affinity_mask = 1ULL << processor_id; | 207 | thread->affinity_mask = 1ULL << processor_id; |
| @@ -209,7 +212,7 @@ ResultVal<SharedPtr<Thread>> Thread::Create(KernelCore& kernel, std::string name | |||
| 209 | thread->name = std::move(name); | 212 | thread->name = std::move(name); |
| 210 | thread->callback_handle = kernel.ThreadWakeupCallbackHandleTable().Create(thread).Unwrap(); | 213 | thread->callback_handle = kernel.ThreadWakeupCallbackHandleTable().Create(thread).Unwrap(); |
| 211 | thread->owner_process = &owner_process; | 214 | thread->owner_process = &owner_process; |
| 212 | thread->scheduler = &Core::System::GetInstance().Scheduler(processor_id); | 215 | thread->scheduler = &system.Scheduler(processor_id); |
| 213 | thread->scheduler->AddThread(thread, priority); | 216 | thread->scheduler->AddThread(thread, priority); |
| 214 | thread->tls_address = thread->owner_process->MarkNextAvailableTLSSlotAsUsed(*thread); | 217 | thread->tls_address = thread->owner_process->MarkNextAvailableTLSSlotAsUsed(*thread); |
| 215 | 218 | ||
| @@ -258,7 +261,7 @@ void Thread::SetStatus(ThreadStatus new_status) { | |||
| 258 | } | 261 | } |
| 259 | 262 | ||
| 260 | if (status == ThreadStatus::Running) { | 263 | if (status == ThreadStatus::Running) { |
| 261 | last_running_ticks = Core::Timing::GetTicks(); | 264 | last_running_ticks = Core::System::GetInstance().CoreTiming().GetTicks(); |
| 262 | } | 265 | } |
| 263 | 266 | ||
| 264 | status = new_status; | 267 | status = new_status; |