summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/mutex.cpp
diff options
context:
space:
mode:
authorGravatar Subv2017-01-02 13:53:10 -0500
committerGravatar Subv2017-01-04 15:58:47 -0500
commitb6a0355568ee327bef8957b9a2498897b96e1278 (patch)
treec2b4ac0c55ecfc2c60495e85e88e64c0f2bb6d8f /src/core/hle/kernel/mutex.cpp
parentKernel/Mutex: Implemented priority inheritance. (diff)
downloadyuzu-b6a0355568ee327bef8957b9a2498897b96e1278.tar.gz
yuzu-b6a0355568ee327bef8957b9a2498897b96e1278.tar.xz
yuzu-b6a0355568ee327bef8957b9a2498897b96e1278.zip
Kernel/Mutex: Update a mutex priority when a thread stops waiting on it.
Diffstat (limited to 'src/core/hle/kernel/mutex.cpp')
-rw-r--r--src/core/hle/kernel/mutex.cpp35
1 files changed, 22 insertions, 13 deletions
diff --git a/src/core/hle/kernel/mutex.cpp b/src/core/hle/kernel/mutex.cpp
index e83717e80..84ff65150 100644
--- a/src/core/hle/kernel/mutex.cpp
+++ b/src/core/hle/kernel/mutex.cpp
@@ -28,6 +28,23 @@ static void UpdateThreadPriority(Thread* thread) {
28 thread->SetPriority(best_priority); 28 thread->SetPriority(best_priority);
29} 29}
30 30
31/**
32 * Elevate the mutex priority to the best priority
33 * among the priorities of all its waiting threads.
34 */
35static void UpdateMutexPriority(Mutex* mutex) {
36 s32 best_priority = THREADPRIO_LOWEST;
37 for (auto& waiter : mutex->GetWaitingThreads()) {
38 if (waiter->current_priority < best_priority)
39 best_priority = waiter->current_priority;
40 }
41
42 if (best_priority != mutex->priority) {
43 mutex->priority = best_priority;
44 UpdateThreadPriority(mutex->holding_thread.get());
45 }
46}
47
31void ReleaseThreadMutexes(Thread* thread) { 48void ReleaseThreadMutexes(Thread* thread) {
32 for (auto& mtx : thread->held_mutexes) { 49 for (auto& mtx : thread->held_mutexes) {
33 mtx->lock_count = 0; 50 mtx->lock_count = 0;
@@ -93,20 +110,12 @@ void Mutex::Release() {
93 110
94void Mutex::AddWaitingThread(SharedPtr<Thread> thread) { 111void Mutex::AddWaitingThread(SharedPtr<Thread> thread) {
95 WaitObject::AddWaitingThread(thread); 112 WaitObject::AddWaitingThread(thread);
113 UpdateMutexPriority(this);
114}
96 115
97 // Elevate the mutex priority to the best priority 116void Mutex::RemoveWaitingThread(Thread* thread) {
98 // among the priorities of all its waiting threads. 117 WaitObject::RemoveWaitingThread(thread);
99 118 UpdateMutexPriority(this);
100 s32 best_priority = THREADPRIO_LOWEST;
101 for (auto& waiter : GetWaitingThreads()) {
102 if (waiter->current_priority < best_priority)
103 best_priority = waiter->current_priority;
104 }
105
106 if (best_priority != priority) {
107 priority = best_priority;
108 UpdateThreadPriority(holding_thread.get());
109 }
110} 119}
111 120
112} // namespace 121} // namespace