From 46572d027dc9620ed2b2a50277e6afd2a115ab81 Mon Sep 17 00:00:00 2001 From: Subv Date: Fri, 20 Apr 2018 20:15:16 -0500 Subject: Kernel: Implemented mutex priority inheritance. Verified with a hwtest and implemented based on reverse engineering. Thread A's priority will get bumped to the highest priority among all the threads that are waiting for a mutex that A holds. Once A releases the mutex and ownership is transferred to B, A's priority will return to normal and B's priority will be bumped. --- src/core/hle/kernel/svc.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src/core/hle/kernel/svc.cpp') diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 082c36caf..a3015cf7a 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -621,6 +621,8 @@ static ResultCode WaitProcessWideKeyAtomic(VAddr mutex_addr, VAddr condition_var current_thread->WakeAfterDelay(nano_seconds); + // Note: Deliberately don't attempt to inherit the lock owner's priority. + Core::System::GetInstance().PrepareReschedule(); return RESULT_SUCCESS; } @@ -651,6 +653,11 @@ static ResultCode SignalProcessWideKey(VAddr condition_variable_addr, s32 target ASSERT(thread->status == THREADSTATUS_WAIT_MUTEX); thread->ResumeFromWait(); + auto lock_owner = thread->lock_owner; + if (lock_owner) + lock_owner->RemoveMutexWaiter(thread); + + thread->lock_owner = nullptr; thread->mutex_wait_address = 0; thread->condvar_wait_address = 0; thread->wait_handle = 0; @@ -666,6 +673,8 @@ static ResultCode SignalProcessWideKey(VAddr condition_variable_addr, s32 target // Signal that the mutex now has a waiting thread. Memory::Write32(thread->mutex_wait_address, mutex_val | Mutex::MutexHasWaitersFlag); + owner->AddMutexWaiter(thread); + Core::System::GetInstance().PrepareReschedule(); } -- cgit v1.2.3