summaryrefslogtreecommitdiffstats
path: root/src/core/hle/kernel/k_condition_variable.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle/kernel/k_condition_variable.cpp')
-rw-r--r--src/core/hle/kernel/k_condition_variable.cpp30
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);
}
}