summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Liam2023-02-22 21:46:06 -0500
committerGravatar Liam2023-03-01 10:42:45 -0500
commit367e89f984e635ae6680e6c640fe3d1259fb692e (patch)
tree4e58679f9b5b28f6c7784ec21301e3bcb21abd9d
parentkernel: document previous location of interrupt disables in arbiter/condvar (diff)
downloadyuzu-367e89f984e635ae6680e6c640fe3d1259fb692e.tar.gz
yuzu-367e89f984e635ae6680e6c640fe3d1259fb692e.tar.xz
yuzu-367e89f984e635ae6680e6c640fe3d1259fb692e.zip
kernel: barrier memory before condition variable write
Diffstat (limited to '')
-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) {
112 112
113 // Remove waiter thread. 113 // Remove waiter thread.
114 s32 num_waiters{}; 114 s32 num_waiters{};
115 KThread* next_owner_thread = 115 KThread* const next_owner_thread =
116 owner_thread->RemoveWaiterByKey(std::addressof(num_waiters), addr); 116 owner_thread->RemoveWaiterByKey(std::addressof(num_waiters), addr);
117 117
118 // Determine the next tag. 118 // Determine the next tag.
@@ -122,25 +122,25 @@ Result KConditionVariable::SignalToAddress(VAddr addr) {
122 if (num_waiters > 1) { 122 if (num_waiters > 1) {
123 next_value |= Svc::HandleWaitMask; 123 next_value |= Svc::HandleWaitMask;
124 } 124 }
125 }
125 126
126 // Write the value to userspace. 127 // Synchronize memory before proceeding.
127 Result result{ResultSuccess}; 128 std::atomic_thread_fence(std::memory_order_seq_cst);
128 if (WriteToUser(system, addr, std::addressof(next_value))) [[likely]] {
129 result = ResultSuccess;
130 } else {
131 result = ResultInvalidCurrentMemory;
132 }
133 129
134 // Signal the next owner thread. 130 // Write the value to userspace.
135 next_owner_thread->EndWait(result); 131 Result result{ResultSuccess};
136 return result; 132 if (WriteToUser(system, addr, std::addressof(next_value))) [[likely]] {
133 result = ResultSuccess;
137 } else { 134 } else {
138 // Just write the value to userspace. 135 result = ResultInvalidCurrentMemory;
139 R_UNLESS(WriteToUser(system, addr, std::addressof(next_value)), 136 }
140 ResultInvalidCurrentMemory);
141 137
142 return ResultSuccess; 138 // If necessary, signal the next owner thread.
139 if (next_owner_thread != nullptr) {
140 next_owner_thread->EndWait(result);
143 } 141 }
142
143 R_RETURN(result);
144 } 144 }
145} 145}
146 146