diff options
| author | 2020-12-20 20:57:54 -0800 | |
|---|---|---|
| committer | 2020-12-20 20:57:54 -0800 | |
| commit | 1279c7ce7afd3d1bf2b4e33aa922158acf2cd060 (patch) | |
| tree | 6db8088caed2bd957187e4730f51424325038fa5 /src/core/hle/kernel/kernel.cpp | |
| parent | Merge pull request #5201 from ameerj/bufferq-refactor (diff) | |
| parent | hle: kernel: Process: Various style fixes based on code review feedback. (diff) | |
| download | yuzu-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.cpp | 63 |
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 | ||
| 50 | struct KernelCore::Impl { | 50 | struct 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 | ||
| 418 | Kernel::GlobalScheduler& KernelCore::GlobalScheduler() { | 410 | Kernel::GlobalSchedulerContext& KernelCore::GlobalSchedulerContext() { |
| 419 | return impl->global_scheduler; | 411 | return *impl->global_scheduler_context; |
| 420 | } | 412 | } |
| 421 | 413 | ||
| 422 | const Kernel::GlobalScheduler& KernelCore::GlobalScheduler() const { | 414 | const Kernel::GlobalSchedulerContext& KernelCore::GlobalSchedulerContext() const { |
| 423 | return impl->global_scheduler; | 415 | return *impl->global_scheduler_context; |
| 424 | } | 416 | } |
| 425 | 417 | ||
| 426 | Kernel::Scheduler& KernelCore::Scheduler(std::size_t id) { | 418 | Kernel::KScheduler& KernelCore::Scheduler(std::size_t id) { |
| 427 | return *impl->schedulers[id]; | 419 | return *impl->schedulers[id]; |
| 428 | } | 420 | } |
| 429 | 421 | ||
| 430 | const Kernel::Scheduler& KernelCore::Scheduler(std::size_t id) const { | 422 | const 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 | ||
| 454 | Kernel::Scheduler& KernelCore::CurrentScheduler() { | 446 | Kernel::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 | } | |
| 460 | const 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 | ||
| 466 | std::array<Core::CPUInterruptHandler, Core::Hardware::NUM_CPU_CORES>& KernelCore::Interrupts() { | 455 | std::array<Core::CPUInterruptHandler, Core::Hardware::NUM_CPU_CORES>& KernelCore::Interrupts() { |
| @@ -623,7 +612,7 @@ const Kernel::SharedMemory& KernelCore::GetTimeSharedMem() const { | |||
| 623 | void KernelCore::Suspend(bool in_suspention) { | 612 | void 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); |