diff options
| author | 2019-03-15 01:02:13 -0400 | |
|---|---|---|
| committer | 2019-03-15 23:01:39 -0400 | |
| commit | 0b78cfcc532ed4353019d361fc595012cdf2e7c4 (patch) | |
| tree | ba08237adad3c3969074c557961fdbf9a3297214 /src/core/hle/kernel/thread.cpp | |
| parent | Merge pull request #2211 from lioncash/arbiter (diff) | |
| download | yuzu-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.cpp | 38 |
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 | ||
| 321 | void Thread::ChangeCore(u32 core, u64 mask) { | 331 | void Thread::ChangeCore(u32 core, u64 mask) { |