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.
This commit is contained in:
		@@ -7,8 +7,6 @@
 | 
			
		||||
#include <optional>
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
#include <boost/range/algorithm_ext/erase.hpp>
 | 
			
		||||
 | 
			
		||||
#include "common/assert.h"
 | 
			
		||||
#include "common/common_types.h"
 | 
			
		||||
#include "common/logging/log.h"
 | 
			
		||||
@@ -269,8 +267,8 @@ void Thread::AddMutexWaiter(SharedPtr<Thread> thread) {
 | 
			
		||||
    if (thread->lock_owner == this) {
 | 
			
		||||
        // If the thread is already waiting for this thread to release the mutex, ensure that the
 | 
			
		||||
        // waiters list is consistent and return without doing anything.
 | 
			
		||||
        auto itr = std::find(wait_mutex_threads.begin(), wait_mutex_threads.end(), thread);
 | 
			
		||||
        ASSERT(itr != wait_mutex_threads.end());
 | 
			
		||||
        const auto iter = std::find(wait_mutex_threads.begin(), wait_mutex_threads.end(), thread);
 | 
			
		||||
        ASSERT(iter != wait_mutex_threads.end());
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -278,11 +276,16 @@ void Thread::AddMutexWaiter(SharedPtr<Thread> thread) {
 | 
			
		||||
    ASSERT(thread->lock_owner == nullptr);
 | 
			
		||||
 | 
			
		||||
    // Ensure that the thread is not already in the list of mutex waiters
 | 
			
		||||
    auto itr = std::find(wait_mutex_threads.begin(), wait_mutex_threads.end(), thread);
 | 
			
		||||
    ASSERT(itr == wait_mutex_threads.end());
 | 
			
		||||
    const auto iter = std::find(wait_mutex_threads.begin(), wait_mutex_threads.end(), thread);
 | 
			
		||||
    ASSERT(iter == wait_mutex_threads.end());
 | 
			
		||||
 | 
			
		||||
    // Keep the list in an ordered fashion
 | 
			
		||||
    const auto insertion_point = std::find_if(
 | 
			
		||||
        wait_mutex_threads.begin(), wait_mutex_threads.end(),
 | 
			
		||||
        [&thread](const auto& entry) { return entry->GetPriority() > thread->GetPriority(); });
 | 
			
		||||
    wait_mutex_threads.insert(insertion_point, thread);
 | 
			
		||||
    thread->lock_owner = this;
 | 
			
		||||
    wait_mutex_threads.emplace_back(std::move(thread));
 | 
			
		||||
 | 
			
		||||
    UpdatePriority();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -290,10 +293,11 @@ void Thread::RemoveMutexWaiter(SharedPtr<Thread> thread) {
 | 
			
		||||
    ASSERT(thread->lock_owner == this);
 | 
			
		||||
 | 
			
		||||
    // Ensure that the thread is in the list of mutex waiters
 | 
			
		||||
    auto itr = std::find(wait_mutex_threads.begin(), wait_mutex_threads.end(), thread);
 | 
			
		||||
    ASSERT(itr != wait_mutex_threads.end());
 | 
			
		||||
    const auto iter = std::find(wait_mutex_threads.begin(), wait_mutex_threads.end(), thread);
 | 
			
		||||
    ASSERT(iter != wait_mutex_threads.end());
 | 
			
		||||
 | 
			
		||||
    wait_mutex_threads.erase(iter);
 | 
			
		||||
 | 
			
		||||
    boost::remove_erase(wait_mutex_threads, thread);
 | 
			
		||||
    thread->lock_owner = nullptr;
 | 
			
		||||
    UpdatePriority();
 | 
			
		||||
}
 | 
			
		||||
@@ -310,12 +314,18 @@ void Thread::UpdatePriority() {
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    scheduler->SetThreadPriority(this, new_priority);
 | 
			
		||||
 | 
			
		||||
    current_priority = new_priority;
 | 
			
		||||
 | 
			
		||||
    if (!lock_owner) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Ensure that the thread is within the correct location in the waiting list.
 | 
			
		||||
    lock_owner->RemoveMutexWaiter(this);
 | 
			
		||||
    lock_owner->AddMutexWaiter(this);
 | 
			
		||||
 | 
			
		||||
    // Recursively update the priority of the thread that depends on the priority of this one.
 | 
			
		||||
    if (lock_owner)
 | 
			
		||||
        lock_owner->UpdatePriority();
 | 
			
		||||
    lock_owner->UpdatePriority();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Thread::ChangeCore(u32 core, u64 mask) {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user