summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/kernel.cpp
diff options
context:
space:
mode:
authorGravatar bunnei2020-12-20 20:57:54 -0800
committerGravatar GitHub2020-12-20 20:57:54 -0800
commit1279c7ce7afd3d1bf2b4e33aa922158acf2cd060 (patch)
tree6db8088caed2bd957187e4730f51424325038fa5 /src/core/hle/kernel/kernel.cpp
parentMerge pull request #5201 from ameerj/bufferq-refactor (diff)
parenthle: kernel: Process: Various style fixes based on code review feedback. (diff)
downloadyuzu-1279c7ce7afd3d1bf2b4e33aa922158acf2cd060.tar.gz
yuzu-1279c7ce7afd3d1bf2b4e33aa922158acf2cd060.tar.xz
yuzu-1279c7ce7afd3d1bf2b4e33aa922158acf2cd060.zip
Merge pull request #5131 from bunnei/scheduler-rewrite
Rewrite Kernel scheduler based on Atmosphere
Diffstat (limited to 'src/core/hle/kernel/kernel.cpp')
-rw-r--r--src/core/hle/kernel/kernel.cpp63
1 files changed, 26 insertions, 37 deletions
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index 929db696d..04cae3a43 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -27,6 +27,7 @@
27#include "core/hle/kernel/client_port.h" 27#include "core/hle/kernel/client_port.h"
28#include "core/hle/kernel/errors.h" 28#include "core/hle/kernel/errors.h"
29#include "core/hle/kernel/handle_table.h" 29#include "core/hle/kernel/handle_table.h"
30#include "core/hle/kernel/k_scheduler.h"
30#include "core/hle/kernel/kernel.h" 31#include "core/hle/kernel/kernel.h"
31#include "core/hle/kernel/memory/memory_layout.h" 32#include "core/hle/kernel/memory/memory_layout.h"
32#include "core/hle/kernel/memory/memory_manager.h" 33#include "core/hle/kernel/memory/memory_manager.h"
@@ -34,7 +35,6 @@
34#include "core/hle/kernel/physical_core.h" 35#include "core/hle/kernel/physical_core.h"
35#include "core/hle/kernel/process.h" 36#include "core/hle/kernel/process.h"
36#include "core/hle/kernel/resource_limit.h" 37#include "core/hle/kernel/resource_limit.h"
37#include "core/hle/kernel/scheduler.h"
38#include "core/hle/kernel/shared_memory.h" 38#include "core/hle/kernel/shared_memory.h"
39#include "core/hle/kernel/synchronization.h" 39#include "core/hle/kernel/synchronization.h"
40#include "core/hle/kernel/thread.h" 40#include "core/hle/kernel/thread.h"
@@ -49,17 +49,18 @@ namespace Kernel {
49 49
50struct KernelCore::Impl { 50struct KernelCore::Impl {
51 explicit Impl(Core::System& system, KernelCore& kernel) 51 explicit Impl(Core::System& system, KernelCore& kernel)
52 : global_scheduler{kernel}, synchronization{system}, time_manager{system}, 52 : synchronization{system}, time_manager{system}, global_handle_table{kernel}, system{
53 global_handle_table{kernel}, system{system} {} 53 system} {}
54 54
55 void SetMulticore(bool is_multicore) { 55 void SetMulticore(bool is_multicore) {
56 this->is_multicore = is_multicore; 56 this->is_multicore = is_multicore;
57 } 57 }
58 58
59 void Initialize(KernelCore& kernel) { 59 void Initialize(KernelCore& kernel) {
60 Shutdown();
61 RegisterHostThread(); 60 RegisterHostThread();
62 61
62 global_scheduler_context = std::make_unique<Kernel::GlobalSchedulerContext>(kernel);
63
63 InitializePhysicalCores(); 64 InitializePhysicalCores();
64 InitializeSystemResourceLimit(kernel); 65 InitializeSystemResourceLimit(kernel);
65 InitializeMemoryLayout(); 66 InitializeMemoryLayout();
@@ -86,29 +87,20 @@ struct KernelCore::Impl {
86 } 87 }
87 } 88 }
88 89
89 for (std::size_t i = 0; i < cores.size(); i++) {
90 cores[i].Shutdown();
91 schedulers[i].reset();
92 }
93 cores.clear(); 90 cores.clear();
94 91
95 process_list.clear(); 92 process_list.clear();
93
96 current_process = nullptr; 94 current_process = nullptr;
97 95
98 system_resource_limit = nullptr; 96 system_resource_limit = nullptr;
99 97
100 global_handle_table.Clear(); 98 global_handle_table.Clear();
101 preemption_event = nullptr;
102 99
103 global_scheduler.Shutdown(); 100 preemption_event = nullptr;
104 101
105 named_ports.clear(); 102 named_ports.clear();
106 103
107 for (auto& core : cores) {
108 core.Shutdown();
109 }
110 cores.clear();
111
112 exclusive_monitor.reset(); 104 exclusive_monitor.reset();
113 105
114 num_host_threads = 0; 106 num_host_threads = 0;
@@ -121,7 +113,7 @@ struct KernelCore::Impl {
121 exclusive_monitor = 113 exclusive_monitor =
122 Core::MakeExclusiveMonitor(system.Memory(), Core::Hardware::NUM_CPU_CORES); 114 Core::MakeExclusiveMonitor(system.Memory(), Core::Hardware::NUM_CPU_CORES);
123 for (std::size_t i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) { 115 for (std::size_t i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) {
124 schedulers[i] = std::make_unique<Kernel::Scheduler>(system, i); 116 schedulers[i] = std::make_unique<Kernel::KScheduler>(system, i);
125 cores.emplace_back(i, system, *schedulers[i], interrupts); 117 cores.emplace_back(i, system, *schedulers[i], interrupts);
126 } 118 }
127 } 119 }
@@ -154,8 +146,8 @@ struct KernelCore::Impl {
154 preemption_event = Core::Timing::CreateEvent( 146 preemption_event = Core::Timing::CreateEvent(
155 "PreemptionCallback", [this, &kernel](std::uintptr_t, std::chrono::nanoseconds) { 147 "PreemptionCallback", [this, &kernel](std::uintptr_t, std::chrono::nanoseconds) {
156 { 148 {
157 SchedulerLock lock(kernel); 149 KScopedSchedulerLock lock(kernel);
158 global_scheduler.PreemptThreads(); 150 global_scheduler_context->PreemptThreads();
159 } 151 }
160 const auto time_interval = std::chrono::nanoseconds{ 152 const auto time_interval = std::chrono::nanoseconds{
161 Core::Timing::msToCycles(std::chrono::milliseconds(10))}; 153 Core::Timing::msToCycles(std::chrono::milliseconds(10))};
@@ -245,7 +237,7 @@ struct KernelCore::Impl {
245 if (result.host_handle >= Core::Hardware::NUM_CPU_CORES) { 237 if (result.host_handle >= Core::Hardware::NUM_CPU_CORES) {
246 return result; 238 return result;
247 } 239 }
248 const Kernel::Scheduler& sched = cores[result.host_handle].Scheduler(); 240 const Kernel::KScheduler& sched = cores[result.host_handle].Scheduler();
249 const Kernel::Thread* current = sched.GetCurrentThread(); 241 const Kernel::Thread* current = sched.GetCurrentThread();
250 if (current != nullptr && !current->IsPhantomMode()) { 242 if (current != nullptr && !current->IsPhantomMode()) {
251 result.guest_handle = current->GetGlobalHandle(); 243 result.guest_handle = current->GetGlobalHandle();
@@ -314,7 +306,7 @@ struct KernelCore::Impl {
314 // Lists all processes that exist in the current session. 306 // Lists all processes that exist in the current session.
315 std::vector<std::shared_ptr<Process>> process_list; 307 std::vector<std::shared_ptr<Process>> process_list;
316 Process* current_process = nullptr; 308 Process* current_process = nullptr;
317 Kernel::GlobalScheduler global_scheduler; 309 std::unique_ptr<Kernel::GlobalSchedulerContext> global_scheduler_context;
318 Kernel::Synchronization synchronization; 310 Kernel::Synchronization synchronization;
319 Kernel::TimeManager time_manager; 311 Kernel::TimeManager time_manager;
320 312
@@ -355,7 +347,7 @@ struct KernelCore::Impl {
355 347
356 std::array<std::shared_ptr<Thread>, Core::Hardware::NUM_CPU_CORES> suspend_threads{}; 348 std::array<std::shared_ptr<Thread>, Core::Hardware::NUM_CPU_CORES> suspend_threads{};
357 std::array<Core::CPUInterruptHandler, Core::Hardware::NUM_CPU_CORES> interrupts{}; 349 std::array<Core::CPUInterruptHandler, Core::Hardware::NUM_CPU_CORES> interrupts{};
358 std::array<std::unique_ptr<Kernel::Scheduler>, Core::Hardware::NUM_CPU_CORES> schedulers{}; 350 std::array<std::unique_ptr<Kernel::KScheduler>, Core::Hardware::NUM_CPU_CORES> schedulers{};
359 351
360 bool is_multicore{}; 352 bool is_multicore{};
361 std::thread::id single_core_thread_id{}; 353 std::thread::id single_core_thread_id{};
@@ -415,19 +407,19 @@ const std::vector<std::shared_ptr<Process>>& KernelCore::GetProcessList() const
415 return impl->process_list; 407 return impl->process_list;
416} 408}
417 409
418Kernel::GlobalScheduler& KernelCore::GlobalScheduler() { 410Kernel::GlobalSchedulerContext& KernelCore::GlobalSchedulerContext() {
419 return impl->global_scheduler; 411 return *impl->global_scheduler_context;
420} 412}
421 413
422const Kernel::GlobalScheduler& KernelCore::GlobalScheduler() const { 414const Kernel::GlobalSchedulerContext& KernelCore::GlobalSchedulerContext() const {
423 return impl->global_scheduler; 415 return *impl->global_scheduler_context;
424} 416}
425 417
426Kernel::Scheduler& KernelCore::Scheduler(std::size_t id) { 418Kernel::KScheduler& KernelCore::Scheduler(std::size_t id) {
427 return *impl->schedulers[id]; 419 return *impl->schedulers[id];
428} 420}
429 421
430const Kernel::Scheduler& KernelCore::Scheduler(std::size_t id) const { 422const Kernel::KScheduler& KernelCore::Scheduler(std::size_t id) const {
431 return *impl->schedulers[id]; 423 return *impl->schedulers[id];
432} 424}
433 425
@@ -451,16 +443,13 @@ const Kernel::PhysicalCore& KernelCore::CurrentPhysicalCore() const {
451 return impl->cores[core_id]; 443 return impl->cores[core_id];
452} 444}
453 445
454Kernel::Scheduler& KernelCore::CurrentScheduler() { 446Kernel::KScheduler* KernelCore::CurrentScheduler() {
455 u32 core_id = impl->GetCurrentHostThreadID(); 447 u32 core_id = impl->GetCurrentHostThreadID();
456 ASSERT(core_id < Core::Hardware::NUM_CPU_CORES); 448 if (core_id >= Core::Hardware::NUM_CPU_CORES) {
457 return *impl->schedulers[core_id]; 449 // This is expected when called from not a guest thread
458} 450 return {};
459 451 }
460const Kernel::Scheduler& KernelCore::CurrentScheduler() const { 452 return impl->schedulers[core_id].get();
461 u32 core_id = impl->GetCurrentHostThreadID();
462 ASSERT(core_id < Core::Hardware::NUM_CPU_CORES);
463 return *impl->schedulers[core_id];
464} 453}
465 454
466std::array<Core::CPUInterruptHandler, Core::Hardware::NUM_CPU_CORES>& KernelCore::Interrupts() { 455std::array<Core::CPUInterruptHandler, Core::Hardware::NUM_CPU_CORES>& KernelCore::Interrupts() {
@@ -623,7 +612,7 @@ const Kernel::SharedMemory& KernelCore::GetTimeSharedMem() const {
623void KernelCore::Suspend(bool in_suspention) { 612void KernelCore::Suspend(bool in_suspention) {
624 const bool should_suspend = exception_exited || in_suspention; 613 const bool should_suspend = exception_exited || in_suspention;
625 { 614 {
626 SchedulerLock lock(*this); 615 KScopedSchedulerLock lock(*this);
627 ThreadStatus status = should_suspend ? ThreadStatus::Ready : ThreadStatus::WaitSleep; 616 ThreadStatus status = should_suspend ? ThreadStatus::Ready : ThreadStatus::WaitSleep;
628 for (std::size_t i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) { 617 for (std::size_t i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) {
629 impl->suspend_threads[i]->SetStatus(status); 618 impl->suspend_threads[i]->SetStatus(status);