summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-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