diff options
author | Liam <byteslice@airmail.cc> | 2023-02-23 03:46:06 +0100 |
---|---|---|
committer | Liam <byteslice@airmail.cc> | 2023-03-01 16:42:45 +0100 |
commit | 367e89f984e635ae6680e6c640fe3d1259fb692e (patch) | |
tree | 4e58679f9b5b28f6c7784ec21301e3bcb21abd9d | |
parent | kernel: document previous location of interrupt disables in arbiter/condvar (diff) | |
download | yuzu-367e89f984e635ae6680e6c640fe3d1259fb692e.tar yuzu-367e89f984e635ae6680e6c640fe3d1259fb692e.tar.gz yuzu-367e89f984e635ae6680e6c640fe3d1259fb692e.tar.bz2 yuzu-367e89f984e635ae6680e6c640fe3d1259fb692e.tar.lz yuzu-367e89f984e635ae6680e6c640fe3d1259fb692e.tar.xz yuzu-367e89f984e635ae6680e6c640fe3d1259fb692e.tar.zst yuzu-367e89f984e635ae6680e6c640fe3d1259fb692e.zip |
-rw-r--r-- | src/core/hle/kernel/k_condition_variable.cpp | 30 |
1 files changed, 15 insertions, 15 deletions
diff --git a/src/core/hle/kernel/k_condition_variable.cpp b/src/core/hle/kernel/k_condition_variable.cpp index 50a805296..c6a088942 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; - } + // Synchronize memory before proceeding. + std::atomic_thread_fence(std::memory_order_seq_cst); - // Signal the next owner thread. - next_owner_thread->EndWait(result); - return result; + // Write the value to userspace. + Result result{ResultSuccess}; + if (WriteToUser(system, addr, std::addressof(next_value))) [[likely]] { + result = ResultSuccess; } else { - // Just write the value to userspace. - R_UNLESS(WriteToUser(system, addr, std::addressof(next_value)), - ResultInvalidCurrentMemory); + result = ResultInvalidCurrentMemory; + } - return ResultSuccess; + // If necessary, signal the next owner thread. + if (next_owner_thread != nullptr) { + next_owner_thread->EndWait(result); } + + R_RETURN(result); } } |