From ccdd84a778244eb1ebbf7ea6e39d5fca79f16e2a Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Wed, 26 Aug 2020 01:55:44 +0000 Subject: hle/scheduler: Fix data race in is_context_switch_pending As reported by tsan, SelectThreads could write to is_context_switch_pending holding a mutex while SwitchToCurrent reads it without holding any. It is assumed that the author didn't want an atomic here, so the code is reordered so that whenever is_context_switch_pending is read inside SwitchToContext, the mutex is locked. --- src/core/hle/kernel/scheduler.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src/core/hle/kernel') diff --git a/src/core/hle/kernel/scheduler.cpp b/src/core/hle/kernel/scheduler.cpp index a4b234424..5cbd3b912 100644 --- a/src/core/hle/kernel/scheduler.cpp +++ b/src/core/hle/kernel/scheduler.cpp @@ -756,7 +756,11 @@ void Scheduler::SwitchToCurrent() { current_thread = selected_thread; is_context_switch_pending = false; } - while (!is_context_switch_pending) { + const auto is_switch_pending = [this] { + std::scoped_lock lock{guard}; + return is_context_switch_pending; + }; + do { if (current_thread != nullptr && !current_thread->IsHLEThread()) { current_thread->context_guard.lock(); if (!current_thread->IsRunnable()) { @@ -775,7 +779,7 @@ void Scheduler::SwitchToCurrent() { next_context = &idle_thread->GetHostContext(); } Common::Fiber::YieldTo(switch_fiber, *next_context); - } + } while (!is_switch_pending()); } } -- cgit v1.2.3