diff options
Diffstat (limited to 'src/core/cpu_manager.cpp')
| -rw-r--r-- | src/core/cpu_manager.cpp | 17 |
1 files changed, 15 insertions, 2 deletions
diff --git a/src/core/cpu_manager.cpp b/src/core/cpu_manager.cpp index d7bd162bc..2aea95a25 100644 --- a/src/core/cpu_manager.cpp +++ b/src/core/cpu_manager.cpp | |||
| @@ -242,8 +242,11 @@ void CpuManager::SingleCoreRunGuestLoop() { | |||
| 242 | break; | 242 | break; |
| 243 | } | 243 | } |
| 244 | } | 244 | } |
| 245 | physical_core.ClearExclusive(); | ||
| 246 | system.ExitDynarmicProfile(); | 245 | system.ExitDynarmicProfile(); |
| 246 | thread->SetPhantomMode(true); | ||
| 247 | system.CoreTiming().Advance(); | ||
| 248 | thread->SetPhantomMode(false); | ||
| 249 | physical_core.ClearExclusive(); | ||
| 247 | PreemptSingleCore(); | 250 | PreemptSingleCore(); |
| 248 | auto& scheduler = kernel.Scheduler(current_core); | 251 | auto& scheduler = kernel.Scheduler(current_core); |
| 249 | scheduler.TryDoContextSwitch(); | 252 | scheduler.TryDoContextSwitch(); |
| @@ -255,6 +258,7 @@ void CpuManager::SingleCoreRunIdleThread() { | |||
| 255 | while (true) { | 258 | while (true) { |
| 256 | auto& physical_core = kernel.CurrentPhysicalCore(); | 259 | auto& physical_core = kernel.CurrentPhysicalCore(); |
| 257 | PreemptSingleCore(); | 260 | PreemptSingleCore(); |
| 261 | idle_count++; | ||
| 258 | auto& scheduler = physical_core.Scheduler(); | 262 | auto& scheduler = physical_core.Scheduler(); |
| 259 | scheduler.TryDoContextSwitch(); | 263 | scheduler.TryDoContextSwitch(); |
| 260 | } | 264 | } |
| @@ -280,15 +284,24 @@ void CpuManager::SingleCoreRunSuspendThread() { | |||
| 280 | void CpuManager::PreemptSingleCore() { | 284 | void CpuManager::PreemptSingleCore() { |
| 281 | preemption_count = 0; | 285 | preemption_count = 0; |
| 282 | std::size_t old_core = current_core; | 286 | std::size_t old_core = current_core; |
| 283 | current_core.store((current_core + 1) % Core::Hardware::NUM_CPU_CORES); | ||
| 284 | auto& scheduler = system.Kernel().Scheduler(old_core); | 287 | auto& scheduler = system.Kernel().Scheduler(old_core); |
| 285 | Kernel::Thread* current_thread = scheduler.GetCurrentThread(); | 288 | Kernel::Thread* current_thread = scheduler.GetCurrentThread(); |
| 289 | if (idle_count >= 4) { | ||
| 290 | current_thread->SetPhantomMode(true); | ||
| 291 | system.CoreTiming().Advance(); | ||
| 292 | current_thread->SetPhantomMode(false); | ||
| 293 | } | ||
| 294 | current_core.store((current_core + 1) % Core::Hardware::NUM_CPU_CORES); | ||
| 286 | scheduler.Unload(); | 295 | scheduler.Unload(); |
| 287 | auto& next_scheduler = system.Kernel().Scheduler(current_core); | 296 | auto& next_scheduler = system.Kernel().Scheduler(current_core); |
| 288 | Common::Fiber::YieldTo(current_thread->GetHostContext(), next_scheduler.ControlContext()); | 297 | Common::Fiber::YieldTo(current_thread->GetHostContext(), next_scheduler.ControlContext()); |
| 289 | /// May have changed scheduler | 298 | /// May have changed scheduler |
| 290 | auto& current_scheduler = system.Kernel().Scheduler(current_core); | 299 | auto& current_scheduler = system.Kernel().Scheduler(current_core); |
| 291 | current_scheduler.Reload(); | 300 | current_scheduler.Reload(); |
| 301 | auto* currrent_thread2 = current_scheduler.GetCurrentThread(); | ||
| 302 | if (!currrent_thread2->IsIdleThread()) { | ||
| 303 | idle_count = 0; | ||
| 304 | } | ||
| 292 | } | 305 | } |
| 293 | 306 | ||
| 294 | void CpuManager::SingleCorePause(bool paused) { | 307 | void CpuManager::SingleCorePause(bool paused) { |