summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/thread.cpp
diff options
context:
space:
mode:
authorGravatar Lioncash2019-03-15 01:02:13 -0400
committerGravatar Lioncash2019-03-15 23:01:39 -0400
commit0b78cfcc532ed4353019d361fc595012cdf2e7c4 (patch)
treeba08237adad3c3969074c557961fdbf9a3297214 /src/core/hle/kernel/thread.cpp
parentMerge pull request #2211 from lioncash/arbiter (diff)
downloadyuzu-0b78cfcc532ed4353019d361fc595012cdf2e7c4.tar.gz
yuzu-0b78cfcc532ed4353019d361fc595012cdf2e7c4.tar.xz
yuzu-0b78cfcc532ed4353019d361fc595012cdf2e7c4.zip
kernel/thread: Maintain priority ordering of added mutex waiting threads
The kernel keeps the internal waiting list ordered by priority. This is trivial to do with std::find_if followed by an insertion.
Diffstat (limited to 'src/core/hle/kernel/thread.cpp')
-rw-r--r--src/core/hle/kernel/thread.cpp38
1 files changed, 24 insertions, 14 deletions
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index eb54d6651..7706ca9e5 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -7,8 +7,6 @@
7#include <optional> 7#include <optional>
8#include <vector> 8#include <vector>
9 9
10#include <boost/range/algorithm_ext/erase.hpp>
11
12#include "common/assert.h" 10#include "common/assert.h"
13#include "common/common_types.h" 11#include "common/common_types.h"
14#include "common/logging/log.h" 12#include "common/logging/log.h"
@@ -269,8 +267,8 @@ void Thread::AddMutexWaiter(SharedPtr<Thread> thread) {
269 if (thread->lock_owner == this) { 267 if (thread->lock_owner == this) {
270 // If the thread is already waiting for this thread to release the mutex, ensure that the 268 // If the thread is already waiting for this thread to release the mutex, ensure that the
271 // waiters list is consistent and return without doing anything. 269 // waiters list is consistent and return without doing anything.
272 auto itr = std::find(wait_mutex_threads.begin(), wait_mutex_threads.end(), thread); 270 const auto iter = std::find(wait_mutex_threads.begin(), wait_mutex_threads.end(), thread);
273 ASSERT(itr != wait_mutex_threads.end()); 271 ASSERT(iter != wait_mutex_threads.end());
274 return; 272 return;
275 } 273 }
276 274
@@ -278,11 +276,16 @@ void Thread::AddMutexWaiter(SharedPtr<Thread> thread) {
278 ASSERT(thread->lock_owner == nullptr); 276 ASSERT(thread->lock_owner == nullptr);
279 277
280 // Ensure that the thread is not already in the list of mutex waiters 278 // Ensure that the thread is not already in the list of mutex waiters
281 auto itr = std::find(wait_mutex_threads.begin(), wait_mutex_threads.end(), thread); 279 const auto iter = std::find(wait_mutex_threads.begin(), wait_mutex_threads.end(), thread);
282 ASSERT(itr == wait_mutex_threads.end()); 280 ASSERT(iter == wait_mutex_threads.end());
283 281
282 // Keep the list in an ordered fashion
283 const auto insertion_point = std::find_if(
284 wait_mutex_threads.begin(), wait_mutex_threads.end(),
285 [&thread](const auto& entry) { return entry->GetPriority() > thread->GetPriority(); });
286 wait_mutex_threads.insert(insertion_point, thread);
284 thread->lock_owner = this; 287 thread->lock_owner = this;
285 wait_mutex_threads.emplace_back(std::move(thread)); 288
286 UpdatePriority(); 289 UpdatePriority();
287} 290}
288 291
@@ -290,10 +293,11 @@ void Thread::RemoveMutexWaiter(SharedPtr<Thread> thread) {
290 ASSERT(thread->lock_owner == this); 293 ASSERT(thread->lock_owner == this);
291 294
292 // Ensure that the thread is in the list of mutex waiters 295 // Ensure that the thread is in the list of mutex waiters
293 auto itr = std::find(wait_mutex_threads.begin(), wait_mutex_threads.end(), thread); 296 const auto iter = std::find(wait_mutex_threads.begin(), wait_mutex_threads.end(), thread);
294 ASSERT(itr != wait_mutex_threads.end()); 297 ASSERT(iter != wait_mutex_threads.end());
298
299 wait_mutex_threads.erase(iter);
295 300
296 boost::remove_erase(wait_mutex_threads, thread);
297 thread->lock_owner = nullptr; 301 thread->lock_owner = nullptr;
298 UpdatePriority(); 302 UpdatePriority();
299} 303}
@@ -310,12 +314,18 @@ void Thread::UpdatePriority() {
310 return; 314 return;
311 315
312 scheduler->SetThreadPriority(this, new_priority); 316 scheduler->SetThreadPriority(this, new_priority);
313
314 current_priority = new_priority; 317 current_priority = new_priority;
315 318
319 if (!lock_owner) {
320 return;
321 }
322
323 // Ensure that the thread is within the correct location in the waiting list.
324 lock_owner->RemoveMutexWaiter(this);
325 lock_owner->AddMutexWaiter(this);
326
316 // Recursively update the priority of the thread that depends on the priority of this one. 327 // Recursively update the priority of the thread that depends on the priority of this one.
317 if (lock_owner) 328 lock_owner->UpdatePriority();
318 lock_owner->UpdatePriority();
319} 329}
320 330
321void Thread::ChangeCore(u32 core, u64 mask) { 331void Thread::ChangeCore(u32 core, u64 mask) {