summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/kernel.cpp
diff options
context:
space:
mode:
authorGravatar David2019-10-28 10:53:27 +1100
committerGravatar GitHub2019-10-28 10:53:27 +1100
commit4c5731c34f0915457a31c60c9f70a2f169ea575d (patch)
tree7f03a7f892370b59e56ae06c6c74514f1cc44998 /src/core/hle/kernel/kernel.cpp
parentMerge pull request #3034 from ReinUsesLisp/w4244-maxwell3d (diff)
parentKernel Thread: Cleanup THREADPROCESSORID_DONT_UPDATE. (diff)
downloadyuzu-4c5731c34f0915457a31c60c9f70a2f169ea575d.tar.gz
yuzu-4c5731c34f0915457a31c60c9f70a2f169ea575d.tar.xz
yuzu-4c5731c34f0915457a31c60c9f70a2f169ea575d.zip
Merge pull request #2971 from FernandoS27/new-scheduler-v2
Kernel: Implement a New Thread Scheduler V2
Diffstat (limited to 'src/core/hle/kernel/kernel.cpp')
-rw-r--r--src/core/hle/kernel/kernel.cpp43
1 files changed, 36 insertions, 7 deletions
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index 799e5e0d8..f94ac150d 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -12,12 +12,15 @@
12 12
13#include "core/core.h" 13#include "core/core.h"
14#include "core/core_timing.h" 14#include "core/core_timing.h"
15#include "core/core_timing_util.h"
15#include "core/hle/kernel/address_arbiter.h" 16#include "core/hle/kernel/address_arbiter.h"
16#include "core/hle/kernel/client_port.h" 17#include "core/hle/kernel/client_port.h"
18#include "core/hle/kernel/errors.h"
17#include "core/hle/kernel/handle_table.h" 19#include "core/hle/kernel/handle_table.h"
18#include "core/hle/kernel/kernel.h" 20#include "core/hle/kernel/kernel.h"
19#include "core/hle/kernel/process.h" 21#include "core/hle/kernel/process.h"
20#include "core/hle/kernel/resource_limit.h" 22#include "core/hle/kernel/resource_limit.h"
23#include "core/hle/kernel/scheduler.h"
21#include "core/hle/kernel/thread.h" 24#include "core/hle/kernel/thread.h"
22#include "core/hle/lock.h" 25#include "core/hle/lock.h"
23#include "core/hle/result.h" 26#include "core/hle/result.h"
@@ -58,12 +61,8 @@ static void ThreadWakeupCallback(u64 thread_handle, [[maybe_unused]] s64 cycles_
58 if (thread->HasWakeupCallback()) { 61 if (thread->HasWakeupCallback()) {
59 resume = thread->InvokeWakeupCallback(ThreadWakeupReason::Timeout, thread, nullptr, 0); 62 resume = thread->InvokeWakeupCallback(ThreadWakeupReason::Timeout, thread, nullptr, 0);
60 } 63 }
61 } 64 } else if (thread->GetStatus() == ThreadStatus::WaitMutex ||
62 65 thread->GetStatus() == ThreadStatus::WaitCondVar) {
63 if (thread->GetMutexWaitAddress() != 0 || thread->GetCondVarWaitAddress() != 0 ||
64 thread->GetWaitHandle() != 0) {
65 ASSERT(thread->GetStatus() == ThreadStatus::WaitMutex ||
66 thread->GetStatus() == ThreadStatus::WaitCondVar);
67 thread->SetMutexWaitAddress(0); 66 thread->SetMutexWaitAddress(0);
68 thread->SetCondVarWaitAddress(0); 67 thread->SetCondVarWaitAddress(0);
69 thread->SetWaitHandle(0); 68 thread->SetWaitHandle(0);
@@ -83,18 +82,23 @@ static void ThreadWakeupCallback(u64 thread_handle, [[maybe_unused]] s64 cycles_
83 } 82 }
84 83
85 if (resume) { 84 if (resume) {
85 if (thread->GetStatus() == ThreadStatus::WaitCondVar ||
86 thread->GetStatus() == ThreadStatus::WaitArb) {
87 thread->SetWaitSynchronizationResult(RESULT_TIMEOUT);
88 }
86 thread->ResumeFromWait(); 89 thread->ResumeFromWait();
87 } 90 }
88} 91}
89 92
90struct KernelCore::Impl { 93struct KernelCore::Impl {
91 explicit Impl(Core::System& system) : system{system} {} 94 explicit Impl(Core::System& system) : system{system}, global_scheduler{system} {}
92 95
93 void Initialize(KernelCore& kernel) { 96 void Initialize(KernelCore& kernel) {
94 Shutdown(); 97 Shutdown();
95 98
96 InitializeSystemResourceLimit(kernel); 99 InitializeSystemResourceLimit(kernel);
97 InitializeThreads(); 100 InitializeThreads();
101 InitializePreemption();
98 } 102 }
99 103
100 void Shutdown() { 104 void Shutdown() {
@@ -110,6 +114,9 @@ struct KernelCore::Impl {
110 114
111 thread_wakeup_callback_handle_table.Clear(); 115 thread_wakeup_callback_handle_table.Clear();
112 thread_wakeup_event_type = nullptr; 116 thread_wakeup_event_type = nullptr;
117 preemption_event = nullptr;
118
119 global_scheduler.Shutdown();
113 120
114 named_ports.clear(); 121 named_ports.clear();
115 } 122 }
@@ -132,6 +139,18 @@ struct KernelCore::Impl {
132 system.CoreTiming().RegisterEvent("ThreadWakeupCallback", ThreadWakeupCallback); 139 system.CoreTiming().RegisterEvent("ThreadWakeupCallback", ThreadWakeupCallback);
133 } 140 }
134 141
142 void InitializePreemption() {
143 preemption_event = system.CoreTiming().RegisterEvent(
144 "PreemptionCallback", [this](u64 userdata, s64 cycles_late) {
145 global_scheduler.PreemptThreads();
146 s64 time_interval = Core::Timing::msToCycles(std::chrono::milliseconds(10));
147 system.CoreTiming().ScheduleEvent(time_interval, preemption_event);
148 });
149
150 s64 time_interval = Core::Timing::msToCycles(std::chrono::milliseconds(10));
151 system.CoreTiming().ScheduleEvent(time_interval, preemption_event);
152 }
153
135 std::atomic<u32> next_object_id{0}; 154 std::atomic<u32> next_object_id{0};
136 std::atomic<u64> next_kernel_process_id{Process::InitialKIPIDMin}; 155 std::atomic<u64> next_kernel_process_id{Process::InitialKIPIDMin};
137 std::atomic<u64> next_user_process_id{Process::ProcessIDMin}; 156 std::atomic<u64> next_user_process_id{Process::ProcessIDMin};
@@ -140,10 +159,12 @@ struct KernelCore::Impl {
140 // Lists all processes that exist in the current session. 159 // Lists all processes that exist in the current session.
141 std::vector<SharedPtr<Process>> process_list; 160 std::vector<SharedPtr<Process>> process_list;
142 Process* current_process = nullptr; 161 Process* current_process = nullptr;
162 Kernel::GlobalScheduler global_scheduler;
143 163
144 SharedPtr<ResourceLimit> system_resource_limit; 164 SharedPtr<ResourceLimit> system_resource_limit;
145 165
146 Core::Timing::EventType* thread_wakeup_event_type = nullptr; 166 Core::Timing::EventType* thread_wakeup_event_type = nullptr;
167 Core::Timing::EventType* preemption_event = nullptr;
147 // TODO(yuriks): This can be removed if Thread objects are explicitly pooled in the future, 168 // TODO(yuriks): This can be removed if Thread objects are explicitly pooled in the future,
148 // allowing us to simply use a pool index or similar. 169 // allowing us to simply use a pool index or similar.
149 Kernel::HandleTable thread_wakeup_callback_handle_table; 170 Kernel::HandleTable thread_wakeup_callback_handle_table;
@@ -203,6 +224,14 @@ const std::vector<SharedPtr<Process>>& KernelCore::GetProcessList() const {
203 return impl->process_list; 224 return impl->process_list;
204} 225}
205 226
227Kernel::GlobalScheduler& KernelCore::GlobalScheduler() {
228 return impl->global_scheduler;
229}
230
231const Kernel::GlobalScheduler& KernelCore::GlobalScheduler() const {
232 return impl->global_scheduler;
233}
234
206void KernelCore::AddNamedPort(std::string name, SharedPtr<ClientPort> port) { 235void KernelCore::AddNamedPort(std::string name, SharedPtr<ClientPort> port) {
207 impl->named_ports.emplace(std::move(name), std::move(port)); 236 impl->named_ports.emplace(std::move(name), std::move(port));
208} 237}