diff options
| author | 2020-02-24 22:04:12 -0400 | |
|---|---|---|
| committer | 2020-06-27 11:35:06 -0400 | |
| commit | e31425df3877636c098ec7426ebd2067920715cb (patch) | |
| tree | 5c0fc518a4ebb8413c491b43a9fdd99450c7bd80 /src/core/hle/kernel/kernel.cpp | |
| parent | Merge pull request #3396 from FernandoS27/prometheus-1 (diff) | |
| download | yuzu-e31425df3877636c098ec7426ebd2067920715cb.tar.gz yuzu-e31425df3877636c098ec7426ebd2067920715cb.tar.xz yuzu-e31425df3877636c098ec7426ebd2067920715cb.zip | |
General: Recover Prometheus project from harddrive failure
This commit: Implements CPU Interrupts, Replaces Cycle Timing for Host
Timing, Reworks the Kernel's Scheduler, Introduce Idle State and
Suspended State, Recreates the bootmanager, Initializes Multicore
system.
Diffstat (limited to 'src/core/hle/kernel/kernel.cpp')
| -rw-r--r-- | src/core/hle/kernel/kernel.cpp | 84 |
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 | ||
| 449 | Kernel::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 | |||
| 455 | const 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 | |||
| 461 | Kernel::Scheduler& KernelCore::CurrentScheduler() { | ||
| 462 | return CurrentPhysicalCore().Scheduler(); | ||
| 463 | } | ||
| 464 | |||
| 465 | const Kernel::Scheduler& KernelCore::CurrentScheduler() const { | ||
| 466 | return CurrentPhysicalCore().Scheduler(); | ||
| 467 | } | ||
| 468 | |||
| 415 | Kernel::Synchronization& KernelCore::Synchronization() { | 469 | Kernel::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 | ||
| 614 | void 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 | |||
| 625 | void KernelCore::ExceptionalExit() { | ||
| 626 | exception_exited = true; | ||
| 627 | Suspend(true); | ||
| 628 | } | ||
| 629 | |||
| 560 | } // namespace Kernel | 630 | } // namespace Kernel |