forked from suyu/suyu
kernel: barrier memory before condition variable write
This commit is contained in:
parent
9f9b64cda2
commit
367e89f984
1 changed files with 19 additions and 19 deletions
|
@ -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,6 +122,10 @@ Result KConditionVariable::SignalToAddress(VAddr addr) {
|
|||
if (num_waiters > 1) {
|
||||
next_value |= Svc::HandleWaitMask;
|
||||
}
|
||||
}
|
||||
|
||||
// Synchronize memory before proceeding.
|
||||
std::atomic_thread_fence(std::memory_order_seq_cst);
|
||||
|
||||
// Write the value to userspace.
|
||||
Result result{ResultSuccess};
|
||||
|
@ -131,16 +135,12 @@ Result KConditionVariable::SignalToAddress(VAddr addr) {
|
|||
result = ResultInvalidCurrentMemory;
|
||||
}
|
||||
|
||||
// Signal the next owner thread.
|
||||
// If necessary, signal the next owner thread.
|
||||
if (next_owner_thread != nullptr) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue