summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel
diff options
context:
space:
mode:
authorGravatar Lioncash2019-02-14 12:42:58 -0500
committerGravatar Lioncash2019-02-15 21:50:25 -0500
commitbd983414f643b734a1f8bebe3183723733344f72 (patch)
treebda0421458439e25cba9d772a6a79b56e473d72e /src/core/hle/kernel
parentMerge pull request #2113 from ReinUsesLisp/vulkan-base (diff)
downloadyuzu-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.cpp12
-rw-r--r--src/core/hle/kernel/kernel.h9
-rw-r--r--src/core/hle/kernel/scheduler.cpp2
-rw-r--r--src/core/hle/kernel/svc.cpp10
-rw-r--r--src/core/hle/kernel/thread.cpp19
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
88struct KernelCore::Impl { 88struct 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
155void KernelCore::Initialize() { 155void KernelCore::Initialize(Core::Timing::CoreTiming& core_timing) {
156 impl->Initialize(*this); 156 impl->Initialize(*this, core_timing);
157} 157}
158 158
159void KernelCore::Shutdown() { 159void 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>
12class ResultVal; 12class ResultVal;
13 13
14namespace Core::Timing { 14namespace Core::Timing {
15class CoreTiming;
15struct EventType; 16struct EventType;
16} 17} // namespace Core::Timing
17 18
18namespace Kernel { 19namespace 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
112void Scheduler::UpdateLastContextSwitchTime(Thread* thread, Process* process) { 112void 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
1546static u64 GetSystemTick() { 1547static 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
44void Thread::Stop() { 44void 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
92void Thread::CancelWakeupTimer() { 94void 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
97static std::optional<s32> GetNextProcessorId(u64 mask) { 99static 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;