summaryrefslogtreecommitdiff
path: root/src/core/cpu_manager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/cpu_manager.cpp')
-rw-r--r--src/core/cpu_manager.cpp40
1 files changed, 24 insertions, 16 deletions
diff --git a/src/core/cpu_manager.cpp b/src/core/cpu_manager.cpp
index de2e5563e..7e195346b 100644
--- a/src/core/cpu_manager.cpp
+++ b/src/core/cpu_manager.cpp
@@ -21,25 +21,34 @@ namespace Core {
21CpuManager::CpuManager(System& system_) : system{system_} {} 21CpuManager::CpuManager(System& system_) : system{system_} {}
22CpuManager::~CpuManager() = default; 22CpuManager::~CpuManager() = default;
23 23
24void CpuManager::ThreadStart(std::stop_token stop_token, CpuManager& cpu_manager, 24void CpuManager::ThreadStart(CpuManager& cpu_manager, std::size_t core) {
25 std::size_t core) { 25 cpu_manager.RunThread(core);
26 cpu_manager.RunThread(stop_token, core);
27} 26}
28 27
29void CpuManager::Initialize() { 28void CpuManager::Initialize() {
30 running_mode = true; 29 running_mode = true;
31 if (is_multicore) { 30 if (is_multicore) {
32 for (std::size_t core = 0; core < Core::Hardware::NUM_CPU_CORES; core++) { 31 for (std::size_t core = 0; core < Core::Hardware::NUM_CPU_CORES; core++) {
33 core_data[core].host_thread = std::jthread(ThreadStart, std::ref(*this), core); 32 core_data[core].host_thread =
33 std::make_unique<std::thread>(ThreadStart, std::ref(*this), core);
34 } 34 }
35 } else { 35 } else {
36 core_data[0].host_thread = std::jthread(ThreadStart, std::ref(*this), 0); 36 core_data[0].host_thread = std::make_unique<std::thread>(ThreadStart, std::ref(*this), 0);
37 } 37 }
38} 38}
39 39
40void CpuManager::Shutdown() { 40void CpuManager::Shutdown() {
41 running_mode = false; 41 running_mode = false;
42 Pause(false); 42 Pause(false);
43 if (is_multicore) {
44 for (auto& data : core_data) {
45 data.host_thread->join();
46 data.host_thread.reset();
47 }
48 } else {
49 core_data[0].host_thread->join();
50 core_data[0].host_thread.reset();
51 }
43} 52}
44 53
45std::function<void(void*)> CpuManager::GetGuestThreadStartFunc() { 54std::function<void(void*)> CpuManager::GetGuestThreadStartFunc() {
@@ -118,18 +127,17 @@ void CpuManager::MultiCoreRunGuestLoop() {
118 physical_core = &kernel.CurrentPhysicalCore(); 127 physical_core = &kernel.CurrentPhysicalCore();
119 } 128 }
120 system.ExitDynarmicProfile(); 129 system.ExitDynarmicProfile();
121 { 130 physical_core->ArmInterface().ClearExclusiveState();
122 Kernel::KScopedDisableDispatch dd(kernel); 131 kernel.CurrentScheduler()->RescheduleCurrentCore();
123 physical_core->ArmInterface().ClearExclusiveState();
124 }
125 } 132 }
126} 133}
127 134
128void CpuManager::MultiCoreRunIdleThread() { 135void CpuManager::MultiCoreRunIdleThread() {
129 auto& kernel = system.Kernel(); 136 auto& kernel = system.Kernel();
130 while (true) { 137 while (true) {
131 Kernel::KScopedDisableDispatch dd(kernel); 138 auto& physical_core = kernel.CurrentPhysicalCore();
132 kernel.CurrentPhysicalCore().Idle(); 139 physical_core.Idle();
140 kernel.CurrentScheduler()->RescheduleCurrentCore();
133 } 141 }
134} 142}
135 143
@@ -137,12 +145,12 @@ void CpuManager::MultiCoreRunSuspendThread() {
137 auto& kernel = system.Kernel(); 145 auto& kernel = system.Kernel();
138 kernel.CurrentScheduler()->OnThreadStart(); 146 kernel.CurrentScheduler()->OnThreadStart();
139 while (true) { 147 while (true) {
140 auto core = kernel.CurrentPhysicalCoreIndex(); 148 auto core = kernel.GetCurrentHostThreadID();
141 auto& scheduler = *kernel.CurrentScheduler(); 149 auto& scheduler = *kernel.CurrentScheduler();
142 Kernel::KThread* current_thread = scheduler.GetCurrentThread(); 150 Kernel::KThread* current_thread = scheduler.GetCurrentThread();
143 Common::Fiber::YieldTo(current_thread->GetHostContext(), *core_data[core].host_context); 151 Common::Fiber::YieldTo(current_thread->GetHostContext(), *core_data[core].host_context);
144 ASSERT(scheduler.ContextSwitchPending()); 152 ASSERT(scheduler.ContextSwitchPending());
145 ASSERT(core == kernel.CurrentPhysicalCoreIndex()); 153 ASSERT(core == kernel.GetCurrentHostThreadID());
146 scheduler.RescheduleCurrentCore(); 154 scheduler.RescheduleCurrentCore();
147 } 155 }
148} 156}
@@ -309,7 +317,7 @@ void CpuManager::Pause(bool paused) {
309 } 317 }
310} 318}
311 319
312void CpuManager::RunThread(std::stop_token stop_token, std::size_t core) { 320void CpuManager::RunThread(std::size_t core) {
313 /// Initialization 321 /// Initialization
314 system.RegisterCoreThread(core); 322 system.RegisterCoreThread(core);
315 std::string name; 323 std::string name;
@@ -348,8 +356,8 @@ void CpuManager::RunThread(std::stop_token stop_token, std::size_t core) {
348 sc_sync_first_use = false; 356 sc_sync_first_use = false;
349 } 357 }
350 358
351 // Emulation was stopped 359 // Abort if emulation was killed before the session really starts
352 if (stop_token.stop_requested()) { 360 if (!system.IsPoweredOn()) {
353 return; 361 return;
354 } 362 }
355 363