summaryrefslogtreecommitdiff
path: root/src/core/core.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/core.cpp')
-rw-r--r--src/core/core.cpp128
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
54MICROPROFILE_DEFINE(ARM_Jit_Dynarmic_CPU0, "ARM JIT", "Dynarmic CPU 0", MP_RGB(255, 64, 64));
55MICROPROFILE_DEFINE(ARM_Jit_Dynarmic_CPU1, "ARM JIT", "Dynarmic CPU 1", MP_RGB(255, 64, 64));
56MICROPROFILE_DEFINE(ARM_Jit_Dynarmic_CPU2, "ARM JIT", "Dynarmic CPU 2", MP_RGB(255, 64, 64));
57MICROPROFILE_DEFINE(ARM_Jit_Dynarmic_CPU3, "ARM JIT", "Dynarmic CPU 3", MP_RGB(255, 64, 64));
58
54namespace Core { 59namespace Core {
55 60
56namespace { 61namespace {
@@ -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
387System::System() : impl{std::make_unique<Impl>(*this)} {} 410System::System() : impl{std::make_unique<Impl>(*this)} {}
388System::~System() = default; 411System::~System() = default;
389 412
390CoreManager& System::CurrentCoreManager() { 413CpuManager& System::GetCpuManager() {
391 return impl->CurrentCoreManager(); 414 return impl->cpu_manager;
415}
416
417const CpuManager& System::GetCpuManager() const {
418 return impl->cpu_manager;
392} 419}
393 420
394const CoreManager& System::CurrentCoreManager() const { 421System::ResultStatus System::Run() {
395 return impl->CurrentCoreManager(); 422 return impl->Run();
396} 423}
397 424
398System::ResultStatus System::RunLoop(bool tight_loop) { 425System::ResultStatus System::Pause() {
399 return impl->RunLoop(tight_loop); 426 return impl->Pause();
400} 427}
401 428
402System::ResultStatus System::SingleStep() { 429System::ResultStatus System::SingleStep() {
403 return RunLoop(false); 430 return ResultStatus::Success;
404} 431}
405 432
406void System::InvalidateCpuInstructionCaches() { 433void System::InvalidateCpuInstructionCaches() {
@@ -416,7 +443,7 @@ bool System::IsPoweredOn() const {
416} 443}
417 444
418void System::PrepareReschedule() { 445void System::PrepareReschedule() {
419 impl->CurrentPhysicalCore().Stop(); 446 // Deprecated, does nothing, kept for backward compatibility.
420} 447}
421 448
422void System::PrepareReschedule(const u32 core_index) { 449void System::PrepareReschedule(const u32 core_index) {
@@ -436,31 +463,41 @@ const TelemetrySession& System::TelemetrySession() const {
436} 463}
437 464
438ARM_Interface& System::CurrentArmInterface() { 465ARM_Interface& System::CurrentArmInterface() {
439 return impl->CurrentPhysicalCore().ArmInterface(); 466 return impl->kernel.CurrentScheduler().GetCurrentThread()->ArmInterface();
440} 467}
441 468
442const ARM_Interface& System::CurrentArmInterface() const { 469const ARM_Interface& System::CurrentArmInterface() const {
443 return impl->CurrentPhysicalCore().ArmInterface(); 470 return impl->kernel.CurrentScheduler().GetCurrentThread()->ArmInterface();
444} 471}
445 472
446std::size_t System::CurrentCoreIndex() const { 473std::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
450Kernel::Scheduler& System::CurrentScheduler() { 479Kernel::Scheduler& System::CurrentScheduler() {
451 return impl->CurrentPhysicalCore().Scheduler(); 480 return impl->kernel.CurrentScheduler();
452} 481}
453 482
454const Kernel::Scheduler& System::CurrentScheduler() const { 483const Kernel::Scheduler& System::CurrentScheduler() const {
455 return impl->CurrentPhysicalCore().Scheduler(); 484 return impl->kernel.CurrentScheduler();
485}
486
487Kernel::PhysicalCore& System::CurrentPhysicalCore() {
488 return impl->kernel.CurrentPhysicalCore();
489}
490
491const Kernel::PhysicalCore& System::CurrentPhysicalCore() const {
492 return impl->kernel.CurrentPhysicalCore();
456} 493}
457 494
458Kernel::Scheduler& System::Scheduler(std::size_t core_index) { 495Kernel::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
462const Kernel::Scheduler& System::Scheduler(std::size_t core_index) const { 499const 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
492ARM_Interface& System::ArmInterface(std::size_t core_index) { 529ARM_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
496const ARM_Interface& System::ArmInterface(std::size_t core_index) const { 535const 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();
500CoreManager& System::GetCoreManager(std::size_t core_index) {
501 return impl->cpu_manager.GetCoreManager(core_index);
502}
503
504const 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
509ExclusiveMonitor& System::Monitor() { 541ExclusiveMonitor& System::Monitor() {
@@ -722,4 +754,18 @@ void System::RegisterHostThread() {
722 impl->kernel.RegisterHostThread(); 754 impl->kernel.RegisterHostThread();
723} 755}
724 756
757void System::EnterDynarmicProfile() {
758 std::size_t core = impl->kernel.GetCurrentHostThreadID();
759 impl->dynarmic_ticks[core] = MicroProfileEnter(impl->microprofile_dynarmic[core]);
760}
761
762void System::ExitDynarmicProfile() {
763 std::size_t core = impl->kernel.GetCurrentHostThreadID();
764 MicroProfileLeave(impl->microprofile_dynarmic[core], impl->dynarmic_ticks[core]);
765}
766
767bool System::IsMulticore() const {
768 return impl->is_multicore;
769}
770
725} // namespace Core 771} // namespace Core