kernel: barrier memory before condition variable write

This commit is contained in:
Liam 2023-02-22 21:46:06 -05:00
parent 9f9b64cda2
commit 367e89f984

View file

@ -112,7 +112,7 @@ Result KConditionVariable::SignalToAddress(VAddr addr) {
// Remove waiter thread. // Remove waiter thread.
s32 num_waiters{}; s32 num_waiters{};
KThread* next_owner_thread = KThread* const next_owner_thread =
owner_thread->RemoveWaiterByKey(std::addressof(num_waiters), addr); owner_thread->RemoveWaiterByKey(std::addressof(num_waiters), addr);
// Determine the next tag. // Determine the next tag.
@ -122,6 +122,10 @@ Result KConditionVariable::SignalToAddress(VAddr addr) {
if (num_waiters > 1) { if (num_waiters > 1) {
next_value |= Svc::HandleWaitMask; next_value |= Svc::HandleWaitMask;
} }
}
// Synchronize memory before proceeding.
std::atomic_thread_fence(std::memory_order_seq_cst);
// Write the value to userspace. // Write the value to userspace.
Result result{ResultSuccess}; Result result{ResultSuccess};
@ -131,16 +135,12 @@ Result KConditionVariable::SignalToAddress(VAddr addr) {
result = ResultInvalidCurrentMemory; result = ResultInvalidCurrentMemory;
} }
// Signal the next owner thread. // If necessary, signal the next owner thread.
if (next_owner_thread != nullptr) {
next_owner_thread->EndWait(result); 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;
} }
R_RETURN(result);
} }
} }