kernel: barrier memory before condition variable write
This commit is contained in:
parent
9f9b64cda2
commit
367e89f984
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Reference in New Issue