summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/process.cpp
diff options
context:
space:
mode:
authorGravatar Fernando Sahmkow2019-11-14 20:13:18 -0400
committerGravatar FernandoS272019-11-21 10:46:55 -0400
commit2d16507f9fa06e868349d6f57a78585aec8628fd (patch)
tree7931e2bb9db6d55e7be760f1a1dcff14de09db78 /src/core/hle/kernel/process.cpp
parentMerge pull request #3142 from ReinUsesLisp/depbar-log (diff)
downloadyuzu-2d16507f9fa06e868349d6f57a78585aec8628fd.tar.gz
yuzu-2d16507f9fa06e868349d6f57a78585aec8628fd.tar.xz
yuzu-2d16507f9fa06e868349d6f57a78585aec8628fd.zip
Kernel: Correct behavior of Condition Variables to be more similar to real hardware.
This commit ensures cond var threads act exactly as they do in the real console. The original implementation uses an RBTree and the behavior of cond var threads is that at the same priority level they act like a FIFO.
Diffstat (limited to 'src/core/hle/kernel/process.cpp')
-rw-r--r--src/core/hle/kernel/process.cpp46
1 files changed, 46 insertions, 0 deletions
diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp
index 12a900bcc..43576c6ab 100644
--- a/src/core/hle/kernel/process.cpp
+++ b/src/core/hle/kernel/process.cpp
@@ -142,6 +142,52 @@ u64 Process::GetTotalPhysicalMemoryUsedWithoutSystemResource() const {
142 return GetTotalPhysicalMemoryUsed() - GetSystemResourceUsage(); 142 return GetTotalPhysicalMemoryUsed() - GetSystemResourceUsage();
143} 143}
144 144
145void Process::InsertConditionVariableThread(SharedPtr<Thread> thread) {
146 auto it = cond_var_threads.begin();
147 while (it != cond_var_threads.end()) {
148 const SharedPtr<Thread> current_thread = *it;
149 if (current_thread->GetCondVarWaitAddress() < thread->GetCondVarWaitAddress()) {
150 if (current_thread->GetCondVarWaitAddress() == thread->GetCondVarWaitAddress()) {
151 if (current_thread->GetPriority() > thread->GetPriority()) {
152 cond_var_threads.insert(it, thread);
153 return;
154 }
155 } else {
156 cond_var_threads.insert(it, thread);
157 return;
158 }
159 }
160 ++it;
161 }
162 cond_var_threads.push_back(thread);
163}
164
165void Process::RemoveConditionVariableThread(SharedPtr<Thread> thread) {
166 auto it = cond_var_threads.begin();
167 while (it != cond_var_threads.end()) {
168 const SharedPtr<Thread> current_thread = *it;
169 if (current_thread.get() == thread.get()) {
170 cond_var_threads.erase(it);
171 return;
172 }
173 ++it;
174 }
175 UNREACHABLE();
176}
177
178std::vector<SharedPtr<Thread>> Process::GetConditionVariableThreads(const VAddr cond_var_addr) {
179 std::vector<SharedPtr<Thread>> result{};
180 auto it = cond_var_threads.begin();
181 while (it != cond_var_threads.end()) {
182 SharedPtr<Thread> current_thread = *it;
183 if (current_thread->GetCondVarWaitAddress() == cond_var_addr) {
184 result.push_back(current_thread);
185 }
186 ++it;
187 }
188 return result;
189}
190
145void Process::RegisterThread(const Thread* thread) { 191void Process::RegisterThread(const Thread* thread) {
146 thread_list.push_back(thread); 192 thread_list.push_back(thread);
147} 193}