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