|
|
@@ -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);
|
|
|
}
|
|
|
}
|
|
|
|