diff options
Diffstat (limited to 'src/core/core.cpp')
| -rw-r--r-- | src/core/core.cpp | 128 |
1 files changed, 87 insertions, 41 deletions
diff --git a/src/core/core.cpp b/src/core/core.cpp index f9f8a3000..1a243c515 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp | |||
| @@ -8,10 +8,10 @@ | |||
| 8 | 8 | ||
| 9 | #include "common/file_util.h" | 9 | #include "common/file_util.h" |
| 10 | #include "common/logging/log.h" | 10 | #include "common/logging/log.h" |
| 11 | #include "common/microprofile.h" | ||
| 11 | #include "common/string_util.h" | 12 | #include "common/string_util.h" |
| 12 | #include "core/arm/exclusive_monitor.h" | 13 | #include "core/arm/exclusive_monitor.h" |
| 13 | #include "core/core.h" | 14 | #include "core/core.h" |
| 14 | #include "core/core_manager.h" | ||
| 15 | #include "core/core_timing.h" | 15 | #include "core/core_timing.h" |
| 16 | #include "core/cpu_manager.h" | 16 | #include "core/cpu_manager.h" |
| 17 | #include "core/device_memory.h" | 17 | #include "core/device_memory.h" |
| @@ -51,6 +51,11 @@ | |||
| 51 | #include "video_core/renderer_base.h" | 51 | #include "video_core/renderer_base.h" |
| 52 | #include "video_core/video_core.h" | 52 | #include "video_core/video_core.h" |
| 53 | 53 | ||
| 54 | MICROPROFILE_DEFINE(ARM_Jit_Dynarmic_CPU0, "ARM JIT", "Dynarmic CPU 0", MP_RGB(255, 64, 64)); | ||
| 55 | MICROPROFILE_DEFINE(ARM_Jit_Dynarmic_CPU1, "ARM JIT", "Dynarmic CPU 1", MP_RGB(255, 64, 64)); | ||
| 56 | MICROPROFILE_DEFINE(ARM_Jit_Dynarmic_CPU2, "ARM JIT", "Dynarmic CPU 2", MP_RGB(255, 64, 64)); | ||
| 57 | MICROPROFILE_DEFINE(ARM_Jit_Dynarmic_CPU3, "ARM JIT", "Dynarmic CPU 3", MP_RGB(255, 64, 64)); | ||
| 58 | |||
| 54 | namespace Core { | 59 | namespace Core { |
| 55 | 60 | ||
| 56 | namespace { | 61 | namespace { |
| @@ -117,23 +122,22 @@ struct System::Impl { | |||
| 117 | : kernel{system}, fs_controller{system}, memory{system}, | 122 | : kernel{system}, fs_controller{system}, memory{system}, |
| 118 | cpu_manager{system}, reporter{system}, applet_manager{system} {} | 123 | cpu_manager{system}, reporter{system}, applet_manager{system} {} |
| 119 | 124 | ||
| 120 | CoreManager& CurrentCoreManager() { | 125 | ResultStatus Run() { |
| 121 | return cpu_manager.GetCurrentCoreManager(); | 126 | status = ResultStatus::Success; |
| 122 | } | ||
| 123 | 127 | ||
| 124 | Kernel::PhysicalCore& CurrentPhysicalCore() { | 128 | kernel.Suspend(false); |
| 125 | const auto index = cpu_manager.GetActiveCoreIndex(); | 129 | core_timing.SyncPause(false); |
| 126 | return kernel.PhysicalCore(index); | 130 | cpu_manager.Pause(false); |
| 127 | } | ||
| 128 | 131 | ||
| 129 | Kernel::PhysicalCore& GetPhysicalCore(std::size_t index) { | 132 | return status; |
| 130 | return kernel.PhysicalCore(index); | ||
| 131 | } | 133 | } |
| 132 | 134 | ||
| 133 | ResultStatus RunLoop(bool tight_loop) { | 135 | ResultStatus Pause() { |
| 134 | status = ResultStatus::Success; | 136 | status = ResultStatus::Success; |
| 135 | 137 | ||
| 136 | cpu_manager.RunLoop(tight_loop); | 138 | core_timing.SyncPause(true); |
| 139 | kernel.Suspend(true); | ||
| 140 | cpu_manager.Pause(true); | ||
| 137 | 141 | ||
| 138 | return status; | 142 | return status; |
| 139 | } | 143 | } |
| @@ -143,7 +147,15 @@ struct System::Impl { | |||
| 143 | 147 | ||
| 144 | device_memory = std::make_unique<Core::DeviceMemory>(system); | 148 | device_memory = std::make_unique<Core::DeviceMemory>(system); |
| 145 | 149 | ||
| 146 | core_timing.Initialize(); | 150 | is_multicore = Settings::values.use_multi_core; |
| 151 | is_async_gpu = is_multicore || Settings::values.use_asynchronous_gpu_emulation; | ||
| 152 | |||
| 153 | kernel.SetMulticore(is_multicore); | ||
| 154 | cpu_manager.SetMulticore(is_multicore); | ||
| 155 | cpu_manager.SetAsyncGpu(is_async_gpu); | ||
| 156 | core_timing.SetMulticore(is_multicore); | ||
| 157 | |||
| 158 | core_timing.Initialize([&system]() { system.RegisterHostThread(); }); | ||
| 147 | kernel.Initialize(); | 159 | kernel.Initialize(); |
| 148 | cpu_manager.Initialize(); | 160 | cpu_manager.Initialize(); |
| 149 | 161 | ||
| @@ -180,6 +192,11 @@ struct System::Impl { | |||
| 180 | is_powered_on = true; | 192 | is_powered_on = true; |
| 181 | exit_lock = false; | 193 | exit_lock = false; |
| 182 | 194 | ||
| 195 | microprofile_dynarmic[0] = MICROPROFILE_TOKEN(ARM_Jit_Dynarmic_CPU0); | ||
| 196 | microprofile_dynarmic[1] = MICROPROFILE_TOKEN(ARM_Jit_Dynarmic_CPU1); | ||
| 197 | microprofile_dynarmic[2] = MICROPROFILE_TOKEN(ARM_Jit_Dynarmic_CPU2); | ||
| 198 | microprofile_dynarmic[3] = MICROPROFILE_TOKEN(ARM_Jit_Dynarmic_CPU3); | ||
| 199 | |||
| 183 | LOG_DEBUG(Core, "Initialized OK"); | 200 | LOG_DEBUG(Core, "Initialized OK"); |
| 184 | 201 | ||
| 185 | return ResultStatus::Success; | 202 | return ResultStatus::Success; |
| @@ -277,8 +294,6 @@ struct System::Impl { | |||
| 277 | service_manager.reset(); | 294 | service_manager.reset(); |
| 278 | cheat_engine.reset(); | 295 | cheat_engine.reset(); |
| 279 | telemetry_session.reset(); | 296 | telemetry_session.reset(); |
| 280 | perf_stats.reset(); | ||
| 281 | gpu_core.reset(); | ||
| 282 | device_memory.reset(); | 297 | device_memory.reset(); |
| 283 | 298 | ||
| 284 | // Close all CPU/threading state | 299 | // Close all CPU/threading state |
| @@ -290,6 +305,8 @@ struct System::Impl { | |||
| 290 | 305 | ||
| 291 | // Close app loader | 306 | // Close app loader |
| 292 | app_loader.reset(); | 307 | app_loader.reset(); |
| 308 | gpu_core.reset(); | ||
| 309 | perf_stats.reset(); | ||
| 293 | 310 | ||
| 294 | // Clear all applets | 311 | // Clear all applets |
| 295 | applet_manager.ClearAll(); | 312 | applet_manager.ClearAll(); |
| @@ -382,25 +399,35 @@ struct System::Impl { | |||
| 382 | 399 | ||
| 383 | std::unique_ptr<Core::PerfStats> perf_stats; | 400 | std::unique_ptr<Core::PerfStats> perf_stats; |
| 384 | Core::FrameLimiter frame_limiter; | 401 | Core::FrameLimiter frame_limiter; |
| 402 | |||
| 403 | bool is_multicore{}; | ||
| 404 | bool is_async_gpu{}; | ||
| 405 | |||
| 406 | std::array<u64, Core::Hardware::NUM_CPU_CORES> dynarmic_ticks{}; | ||
| 407 | std::array<MicroProfileToken, Core::Hardware::NUM_CPU_CORES> microprofile_dynarmic{}; | ||
| 385 | }; | 408 | }; |
| 386 | 409 | ||
| 387 | System::System() : impl{std::make_unique<Impl>(*this)} {} | 410 | System::System() : impl{std::make_unique<Impl>(*this)} {} |
| 388 | System::~System() = default; | 411 | System::~System() = default; |
| 389 | 412 | ||
| 390 | CoreManager& System::CurrentCoreManager() { | 413 | CpuManager& System::GetCpuManager() { |
| 391 | return impl->CurrentCoreManager(); | 414 | return impl->cpu_manager; |
| 415 | } | ||
| 416 | |||
| 417 | const CpuManager& System::GetCpuManager() const { | ||
| 418 | return impl->cpu_manager; | ||
| 392 | } | 419 | } |
| 393 | 420 | ||
| 394 | const CoreManager& System::CurrentCoreManager() const { | 421 | System::ResultStatus System::Run() { |
| 395 | return impl->CurrentCoreManager(); | 422 | return impl->Run(); |
| 396 | } | 423 | } |
| 397 | 424 | ||
| 398 | System::ResultStatus System::RunLoop(bool tight_loop) { | 425 | System::ResultStatus System::Pause() { |
| 399 | return impl->RunLoop(tight_loop); | 426 | return impl->Pause(); |
| 400 | } | 427 | } |
| 401 | 428 | ||
| 402 | System::ResultStatus System::SingleStep() { | 429 | System::ResultStatus System::SingleStep() { |
| 403 | return RunLoop(false); | 430 | return ResultStatus::Success; |
| 404 | } | 431 | } |
| 405 | 432 | ||
| 406 | void System::InvalidateCpuInstructionCaches() { | 433 | void System::InvalidateCpuInstructionCaches() { |
| @@ -416,7 +443,7 @@ bool System::IsPoweredOn() const { | |||
| 416 | } | 443 | } |
| 417 | 444 | ||
| 418 | void System::PrepareReschedule() { | 445 | void System::PrepareReschedule() { |
| 419 | impl->CurrentPhysicalCore().Stop(); | 446 | // Deprecated, does nothing, kept for backward compatibility. |
| 420 | } | 447 | } |
| 421 | 448 | ||
| 422 | void System::PrepareReschedule(const u32 core_index) { | 449 | void System::PrepareReschedule(const u32 core_index) { |
| @@ -436,31 +463,41 @@ const TelemetrySession& System::TelemetrySession() const { | |||
| 436 | } | 463 | } |
| 437 | 464 | ||
| 438 | ARM_Interface& System::CurrentArmInterface() { | 465 | ARM_Interface& System::CurrentArmInterface() { |
| 439 | return impl->CurrentPhysicalCore().ArmInterface(); | 466 | return impl->kernel.CurrentScheduler().GetCurrentThread()->ArmInterface(); |
| 440 | } | 467 | } |
| 441 | 468 | ||
| 442 | const ARM_Interface& System::CurrentArmInterface() const { | 469 | const ARM_Interface& System::CurrentArmInterface() const { |
| 443 | return impl->CurrentPhysicalCore().ArmInterface(); | 470 | return impl->kernel.CurrentScheduler().GetCurrentThread()->ArmInterface(); |
| 444 | } | 471 | } |
| 445 | 472 | ||
| 446 | std::size_t System::CurrentCoreIndex() const { | 473 | std::size_t System::CurrentCoreIndex() const { |
| 447 | return impl->cpu_manager.GetActiveCoreIndex(); | 474 | std::size_t core = impl->kernel.GetCurrentHostThreadID(); |
| 475 | ASSERT(core < Core::Hardware::NUM_CPU_CORES); | ||
| 476 | return core; | ||
| 448 | } | 477 | } |
| 449 | 478 | ||
| 450 | Kernel::Scheduler& System::CurrentScheduler() { | 479 | Kernel::Scheduler& System::CurrentScheduler() { |
| 451 | return impl->CurrentPhysicalCore().Scheduler(); | 480 | return impl->kernel.CurrentScheduler(); |
| 452 | } | 481 | } |
| 453 | 482 | ||
| 454 | const Kernel::Scheduler& System::CurrentScheduler() const { | 483 | const Kernel::Scheduler& System::CurrentScheduler() const { |
| 455 | return impl->CurrentPhysicalCore().Scheduler(); | 484 | return impl->kernel.CurrentScheduler(); |
| 485 | } | ||
| 486 | |||
| 487 | Kernel::PhysicalCore& System::CurrentPhysicalCore() { | ||
| 488 | return impl->kernel.CurrentPhysicalCore(); | ||
| 489 | } | ||
| 490 | |||
| 491 | const Kernel::PhysicalCore& System::CurrentPhysicalCore() const { | ||
| 492 | return impl->kernel.CurrentPhysicalCore(); | ||
| 456 | } | 493 | } |
| 457 | 494 | ||
| 458 | Kernel::Scheduler& System::Scheduler(std::size_t core_index) { | 495 | Kernel::Scheduler& System::Scheduler(std::size_t core_index) { |
| 459 | return impl->GetPhysicalCore(core_index).Scheduler(); | 496 | return impl->kernel.Scheduler(core_index); |
| 460 | } | 497 | } |
| 461 | 498 | ||
| 462 | const Kernel::Scheduler& System::Scheduler(std::size_t core_index) const { | 499 | const Kernel::Scheduler& System::Scheduler(std::size_t core_index) const { |
| 463 | return impl->GetPhysicalCore(core_index).Scheduler(); | 500 | return impl->kernel.Scheduler(core_index); |
| 464 | } | 501 | } |
| 465 | 502 | ||
| 466 | /// Gets the global scheduler | 503 | /// Gets the global scheduler |
| @@ -490,20 +527,15 @@ const Kernel::Process* System::CurrentProcess() const { | |||
| 490 | } | 527 | } |
| 491 | 528 | ||
| 492 | ARM_Interface& System::ArmInterface(std::size_t core_index) { | 529 | ARM_Interface& System::ArmInterface(std::size_t core_index) { |
| 493 | return impl->GetPhysicalCore(core_index).ArmInterface(); | 530 | auto* thread = impl->kernel.Scheduler(core_index).GetCurrentThread(); |
| 531 | ASSERT(thread && !thread->IsHLEThread()); | ||
| 532 | return thread->ArmInterface(); | ||
| 494 | } | 533 | } |
| 495 | 534 | ||
| 496 | const ARM_Interface& System::ArmInterface(std::size_t core_index) const { | 535 | const ARM_Interface& System::ArmInterface(std::size_t core_index) const { |
| 497 | return impl->GetPhysicalCore(core_index).ArmInterface(); | 536 | auto* thread = impl->kernel.Scheduler(core_index).GetCurrentThread(); |
| 498 | } | 537 | ASSERT(thread && !thread->IsHLEThread()); |
| 499 | 538 | return thread->ArmInterface(); | |
| 500 | CoreManager& System::GetCoreManager(std::size_t core_index) { | ||
| 501 | return impl->cpu_manager.GetCoreManager(core_index); | ||
| 502 | } | ||
| 503 | |||
| 504 | const CoreManager& System::GetCoreManager(std::size_t core_index) const { | ||
| 505 | ASSERT(core_index < NUM_CPU_CORES); | ||
| 506 | return impl->cpu_manager.GetCoreManager(core_index); | ||
| 507 | } | 539 | } |
| 508 | 540 | ||
| 509 | ExclusiveMonitor& System::Monitor() { | 541 | ExclusiveMonitor& System::Monitor() { |
| @@ -722,4 +754,18 @@ void System::RegisterHostThread() { | |||
| 722 | impl->kernel.RegisterHostThread(); | 754 | impl->kernel.RegisterHostThread(); |
| 723 | } | 755 | } |
| 724 | 756 | ||
| 757 | void System::EnterDynarmicProfile() { | ||
| 758 | std::size_t core = impl->kernel.GetCurrentHostThreadID(); | ||
| 759 | impl->dynarmic_ticks[core] = MicroProfileEnter(impl->microprofile_dynarmic[core]); | ||
| 760 | } | ||
| 761 | |||
| 762 | void System::ExitDynarmicProfile() { | ||
| 763 | std::size_t core = impl->kernel.GetCurrentHostThreadID(); | ||
| 764 | MicroProfileLeave(impl->microprofile_dynarmic[core], impl->dynarmic_ticks[core]); | ||
| 765 | } | ||
| 766 | |||
| 767 | bool System::IsMulticore() const { | ||
| 768 | return impl->is_multicore; | ||
| 769 | } | ||
| 770 | |||
| 725 | } // namespace Core | 771 | } // namespace Core |