diff options
Diffstat (limited to 'src/core')
| -rw-r--r-- | src/core/hle/kernel/scheduler.cpp | 28 | ||||
| -rw-r--r-- | src/core/hle/kernel/thread.h | 4 |
2 files changed, 25 insertions, 7 deletions
diff --git a/src/core/hle/kernel/scheduler.cpp b/src/core/hle/kernel/scheduler.cpp index affc2fbed..ab17204bb 100644 --- a/src/core/hle/kernel/scheduler.cpp +++ b/src/core/hle/kernel/scheduler.cpp | |||
| @@ -147,9 +147,11 @@ bool GlobalScheduler::YieldThread(Thread* yielding_thread) { | |||
| 147 | const u32 priority = yielding_thread->GetPriority(); | 147 | const u32 priority = yielding_thread->GetPriority(); |
| 148 | 148 | ||
| 149 | // Yield the thread | 149 | // Yield the thread |
| 150 | const Thread* const winner = scheduled_queue[core_id].front(priority); | 150 | Reschedule(priority, core_id, yielding_thread); |
| 151 | ASSERT_MSG(yielding_thread == winner, "Thread yielding without being in front"); | 151 | const Thread* const winner = scheduled_queue[core_id].front(); |
| 152 | scheduled_queue[core_id].yield(priority); | 152 | if (kernel.GetCurrentHostThreadID() != core_id) { |
| 153 | is_reselection_pending.store(true, std::memory_order_release); | ||
| 154 | } | ||
| 153 | 155 | ||
| 154 | return AskForReselectionOrMarkRedundant(yielding_thread, winner); | 156 | return AskForReselectionOrMarkRedundant(yielding_thread, winner); |
| 155 | } | 157 | } |
| @@ -162,9 +164,7 @@ bool GlobalScheduler::YieldThreadAndBalanceLoad(Thread* yielding_thread) { | |||
| 162 | const u32 priority = yielding_thread->GetPriority(); | 164 | const u32 priority = yielding_thread->GetPriority(); |
| 163 | 165 | ||
| 164 | // Yield the thread | 166 | // Yield the thread |
| 165 | ASSERT_MSG(yielding_thread == scheduled_queue[core_id].front(priority), | 167 | Reschedule(priority, core_id, yielding_thread); |
| 166 | "Thread yielding without being in front"); | ||
| 167 | scheduled_queue[core_id].yield(priority); | ||
| 168 | 168 | ||
| 169 | std::array<Thread*, Core::Hardware::NUM_CPU_CORES> current_threads; | 169 | std::array<Thread*, Core::Hardware::NUM_CPU_CORES> current_threads; |
| 170 | for (std::size_t i = 0; i < current_threads.size(); i++) { | 170 | for (std::size_t i = 0; i < current_threads.size(); i++) { |
| @@ -200,6 +200,10 @@ bool GlobalScheduler::YieldThreadAndBalanceLoad(Thread* yielding_thread) { | |||
| 200 | winner = next_thread; | 200 | winner = next_thread; |
| 201 | } | 201 | } |
| 202 | 202 | ||
| 203 | if (kernel.GetCurrentHostThreadID() != core_id) { | ||
| 204 | is_reselection_pending.store(true, std::memory_order_release); | ||
| 205 | } | ||
| 206 | |||
| 203 | return AskForReselectionOrMarkRedundant(yielding_thread, winner); | 207 | return AskForReselectionOrMarkRedundant(yielding_thread, winner); |
| 204 | } | 208 | } |
| 205 | 209 | ||
| @@ -239,6 +243,12 @@ bool GlobalScheduler::YieldThreadAndWaitForLoadBalancing(Thread* yielding_thread | |||
| 239 | } else { | 243 | } else { |
| 240 | winner = yielding_thread; | 244 | winner = yielding_thread; |
| 241 | } | 245 | } |
| 246 | } else { | ||
| 247 | winner = scheduled_queue[i].front(); | ||
| 248 | } | ||
| 249 | |||
| 250 | if (kernel.GetCurrentHostThreadID() != core_id) { | ||
| 251 | is_reselection_pending.store(true, std::memory_order_release); | ||
| 242 | } | 252 | } |
| 243 | 253 | ||
| 244 | return AskForReselectionOrMarkRedundant(yielding_thread, winner); | 254 | return AskForReselectionOrMarkRedundant(yielding_thread, winner); |
| @@ -687,7 +697,11 @@ void Scheduler::SwitchToCurrent() { | |||
| 687 | while (!is_context_switch_pending) { | 697 | while (!is_context_switch_pending) { |
| 688 | if (current_thread != nullptr && !current_thread->IsHLEThread()) { | 698 | if (current_thread != nullptr && !current_thread->IsHLEThread()) { |
| 689 | current_thread->context_guard.lock(); | 699 | current_thread->context_guard.lock(); |
| 690 | if (current_thread->GetSchedulingStatus() != ThreadSchedStatus::Runnable) { | 700 | if (!current_thread->IsRunnable()) { |
| 701 | current_thread->context_guard.unlock(); | ||
| 702 | break; | ||
| 703 | } | ||
| 704 | if (current_thread->GetProcessorID() != core_id) { | ||
| 691 | current_thread->context_guard.unlock(); | 705 | current_thread->context_guard.unlock(); |
| 692 | break; | 706 | break; |
| 693 | } | 707 | } |
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index 0a8f7bb65..953b023b5 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h | |||
| @@ -524,6 +524,10 @@ public: | |||
| 524 | static_cast<u32>(ThreadSchedMasks::LowMask)); | 524 | static_cast<u32>(ThreadSchedMasks::LowMask)); |
| 525 | } | 525 | } |
| 526 | 526 | ||
| 527 | bool IsRunnable() const { | ||
| 528 | return scheduling_state == static_cast<u32>(ThreadSchedStatus::Runnable); | ||
| 529 | } | ||
| 530 | |||
| 527 | bool IsRunning() const { | 531 | bool IsRunning() const { |
| 528 | return is_running; | 532 | return is_running; |
| 529 | } | 533 | } |