From 367e89f984e635ae6680e6c640fe3d1259fb692e Mon Sep 17 00:00:00 2001 From: Liam Date: Wed, 22 Feb 2023 21:46:06 -0500 Subject: [PATCH] kernel: barrier memory before condition variable write --- src/core/hle/kernel/k_condition_variable.cpp | 38 ++++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/src/core/hle/kernel/k_condition_variable.cpp b/src/core/hle/kernel/k_condition_variable.cpp index 50a805296c..c6a0889425 100644 --- a/src/core/hle/kernel/k_condition_variable.cpp +++ b/src/core/hle/kernel/k_condition_variable.cpp @@ -112,7 +112,7 @@ Result KConditionVariable::SignalToAddress(VAddr addr) { // Remove waiter thread. s32 num_waiters{}; - KThread* next_owner_thread = + KThread* const next_owner_thread = owner_thread->RemoveWaiterByKey(std::addressof(num_waiters), addr); // Determine the next tag. @@ -122,25 +122,25 @@ Result KConditionVariable::SignalToAddress(VAddr addr) { if (num_waiters > 1) { next_value |= Svc::HandleWaitMask; } - - // Write the value to userspace. - Result result{ResultSuccess}; - if (WriteToUser(system, addr, std::addressof(next_value))) [[likely]] { - result = ResultSuccess; - } else { - result = ResultInvalidCurrentMemory; - } - - // Signal the next owner thread. - next_owner_thread->EndWait(result); - return result; - } else { - // Just write the value to userspace. - R_UNLESS(WriteToUser(system, addr, std::addressof(next_value)), - ResultInvalidCurrentMemory); - - return ResultSuccess; } + + // Synchronize memory before proceeding. + std::atomic_thread_fence(std::memory_order_seq_cst); + + // Write the value to userspace. + Result result{ResultSuccess}; + if (WriteToUser(system, addr, std::addressof(next_value))) [[likely]] { + result = ResultSuccess; + } else { + result = ResultInvalidCurrentMemory; + } + + // If necessary, signal the next owner thread. + if (next_owner_thread != nullptr) { + next_owner_thread->EndWait(result); + } + + R_RETURN(result); } }