summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/kernel.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle/kernel/kernel.cpp')
-rw-r--r--src/core/hle/kernel/kernel.cpp84
1 files changed, 77 insertions, 7 deletions
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index 7655382fa..ba051a7d8 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -13,11 +13,13 @@
13 13
14#include "common/assert.h" 14#include "common/assert.h"
15#include "common/logging/log.h" 15#include "common/logging/log.h"
16#include "common/thread.h"
16#include "core/arm/arm_interface.h" 17#include "core/arm/arm_interface.h"
17#include "core/arm/exclusive_monitor.h" 18#include "core/arm/exclusive_monitor.h"
18#include "core/core.h" 19#include "core/core.h"
19#include "core/core_timing.h" 20#include "core/core_timing.h"
20#include "core/core_timing_util.h" 21#include "core/core_timing_util.h"
22#include "core/cpu_manager.h"
21#include "core/device_memory.h" 23#include "core/device_memory.h"
22#include "core/hardware_properties.h" 24#include "core/hardware_properties.h"
23#include "core/hle/kernel/client_port.h" 25#include "core/hle/kernel/client_port.h"
@@ -117,7 +119,9 @@ struct KernelCore::Impl {
117 InitializeSystemResourceLimit(kernel); 119 InitializeSystemResourceLimit(kernel);
118 InitializeMemoryLayout(); 120 InitializeMemoryLayout();
119 InitializeThreads(); 121 InitializeThreads();
120 InitializePreemption(); 122 InitializePreemption(kernel);
123 InitializeSchedulers();
124 InitializeSuspendThreads();
121 } 125 }
122 126
123 void Shutdown() { 127 void Shutdown() {
@@ -155,6 +159,12 @@ struct KernelCore::Impl {
155 } 159 }
156 } 160 }
157 161
162 void InitializeSchedulers() {
163 for (std::size_t i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) {
164 cores[i].Scheduler().Initialize();
165 }
166 }
167
158 // Creates the default system resource limit 168 // Creates the default system resource limit
159 void InitializeSystemResourceLimit(KernelCore& kernel) { 169 void InitializeSystemResourceLimit(KernelCore& kernel) {
160 system_resource_limit = ResourceLimit::Create(kernel); 170 system_resource_limit = ResourceLimit::Create(kernel);
@@ -178,10 +188,13 @@ struct KernelCore::Impl {
178 Core::Timing::CreateEvent("ThreadWakeupCallback", ThreadWakeupCallback); 188 Core::Timing::CreateEvent("ThreadWakeupCallback", ThreadWakeupCallback);
179 } 189 }
180 190
181 void InitializePreemption() { 191 void InitializePreemption(KernelCore& kernel) {
182 preemption_event = 192 preemption_event = Core::Timing::CreateEvent(
183 Core::Timing::CreateEvent("PreemptionCallback", [this](u64 userdata, s64 cycles_late) { 193 "PreemptionCallback", [this, &kernel](u64 userdata, s64 cycles_late) {
184 global_scheduler.PreemptThreads(); 194 {
195 SchedulerLock lock(kernel);
196 global_scheduler.PreemptThreads();
197 }
185 s64 time_interval = Core::Timing::msToCycles(std::chrono::milliseconds(10)); 198 s64 time_interval = Core::Timing::msToCycles(std::chrono::milliseconds(10));
186 system.CoreTiming().ScheduleEvent(time_interval, preemption_event); 199 system.CoreTiming().ScheduleEvent(time_interval, preemption_event);
187 }); 200 });
@@ -190,6 +203,20 @@ struct KernelCore::Impl {
190 system.CoreTiming().ScheduleEvent(time_interval, preemption_event); 203 system.CoreTiming().ScheduleEvent(time_interval, preemption_event);
191 } 204 }
192 205
206 void InitializeSuspendThreads() {
207 for (std::size_t i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) {
208 std::string name = "Suspend Thread Id:" + std::to_string(i);
209 std::function<void(void*)> init_func =
210 system.GetCpuManager().GetSuspendThreadStartFunc();
211 void* init_func_parameter = system.GetCpuManager().GetStartFuncParamater();
212 ThreadType type =
213 static_cast<ThreadType>(THREADTYPE_KERNEL | THREADTYPE_HLE | THREADTYPE_SUSPEND);
214 auto thread_res = Thread::Create(system, type, name, 0, 0, 0, static_cast<u32>(i), 0,
215 nullptr, std::move(init_func), init_func_parameter);
216 suspend_threads[i] = std::move(thread_res).Unwrap();
217 }
218 }
219
193 void MakeCurrentProcess(Process* process) { 220 void MakeCurrentProcess(Process* process) {
194 current_process = process; 221 current_process = process;
195 222
@@ -201,7 +228,10 @@ struct KernelCore::Impl {
201 core.SetIs64Bit(process->Is64BitProcess()); 228 core.SetIs64Bit(process->Is64BitProcess());
202 } 229 }
203 230
204 system.Memory().SetCurrentPageTable(*process); 231 u32 core_id = GetCurrentHostThreadID();
232 if (core_id < Core::Hardware::NUM_CPU_CORES) {
233 system.Memory().SetCurrentPageTable(*process, core_id);
234 }
205 } 235 }
206 236
207 void RegisterCoreThread(std::size_t core_id) { 237 void RegisterCoreThread(std::size_t core_id) {
@@ -219,7 +249,9 @@ struct KernelCore::Impl {
219 std::unique_lock lock{register_thread_mutex}; 249 std::unique_lock lock{register_thread_mutex};
220 const std::thread::id this_id = std::this_thread::get_id(); 250 const std::thread::id this_id = std::this_thread::get_id();
221 const auto it = host_thread_ids.find(this_id); 251 const auto it = host_thread_ids.find(this_id);
222 ASSERT(it == host_thread_ids.end()); 252 if (it != host_thread_ids.end()) {
253 return;
254 }
223 host_thread_ids[this_id] = registered_thread_ids++; 255 host_thread_ids[this_id] = registered_thread_ids++;
224 } 256 }
225 257
@@ -343,6 +375,8 @@ struct KernelCore::Impl {
343 std::shared_ptr<Kernel::SharedMemory> irs_shared_mem; 375 std::shared_ptr<Kernel::SharedMemory> irs_shared_mem;
344 std::shared_ptr<Kernel::SharedMemory> time_shared_mem; 376 std::shared_ptr<Kernel::SharedMemory> time_shared_mem;
345 377
378 std::array<std::shared_ptr<Thread>, Core::Hardware::NUM_CPU_CORES> suspend_threads{};
379
346 // System context 380 // System context
347 Core::System& system; 381 Core::System& system;
348}; 382};
@@ -412,6 +446,26 @@ const Kernel::PhysicalCore& KernelCore::PhysicalCore(std::size_t id) const {
412 return impl->cores[id]; 446 return impl->cores[id];
413} 447}
414 448
449Kernel::PhysicalCore& KernelCore::CurrentPhysicalCore() {
450 u32 core_id = impl->GetCurrentHostThreadID();
451 ASSERT(core_id < Core::Hardware::NUM_CPU_CORES);
452 return impl->cores[core_id];
453}
454
455const Kernel::PhysicalCore& KernelCore::CurrentPhysicalCore() const {
456 u32 core_id = impl->GetCurrentHostThreadID();
457 ASSERT(core_id < Core::Hardware::NUM_CPU_CORES);
458 return impl->cores[core_id];
459}
460
461Kernel::Scheduler& KernelCore::CurrentScheduler() {
462 return CurrentPhysicalCore().Scheduler();
463}
464
465const Kernel::Scheduler& KernelCore::CurrentScheduler() const {
466 return CurrentPhysicalCore().Scheduler();
467}
468
415Kernel::Synchronization& KernelCore::Synchronization() { 469Kernel::Synchronization& KernelCore::Synchronization() {
416 return impl->synchronization; 470 return impl->synchronization;
417} 471}
@@ -557,4 +611,20 @@ const Kernel::SharedMemory& KernelCore::GetTimeSharedMem() const {
557 return *impl->time_shared_mem; 611 return *impl->time_shared_mem;
558} 612}
559 613
614void KernelCore::Suspend(bool in_suspention) {
615 const bool should_suspend = exception_exited || in_suspention;
616 {
617 SchedulerLock lock(*this);
618 ThreadStatus status = should_suspend ? ThreadStatus::Ready : ThreadStatus::WaitSleep;
619 for (std::size_t i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) {
620 impl->suspend_threads[i]->SetStatus(status);
621 }
622 }
623}
624
625void KernelCore::ExceptionalExit() {
626 exception_exited = true;
627 Suspend(true);
628}
629
560} // namespace Kernel 630} // namespace Kernel