summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/svc.cpp
diff options
context:
space:
mode:
authorGravatar Subv2018-04-20 20:15:16 -0500
committerGravatar Subv2018-04-23 11:23:44 -0500
commit46572d027dc9620ed2b2a50277e6afd2a115ab81 (patch)
tree72562a37575252e8f4c0160a3067b415027fdf4b /src/core/hle/kernel/svc.cpp
parentKernel: Use 0x2C as default main thread priority for homebrew and lone NRO/NSOs (diff)
downloadyuzu-46572d027dc9620ed2b2a50277e6afd2a115ab81.tar.gz
yuzu-46572d027dc9620ed2b2a50277e6afd2a115ab81.tar.xz
yuzu-46572d027dc9620ed2b2a50277e6afd2a115ab81.zip
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.
Diffstat (limited to 'src/core/hle/kernel/svc.cpp')
-rw-r--r--src/core/hle/kernel/svc.cpp9
1 files changed, 9 insertions, 0 deletions
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
621 621
622 current_thread->WakeAfterDelay(nano_seconds); 622 current_thread->WakeAfterDelay(nano_seconds);
623 623
624 // Note: Deliberately don't attempt to inherit the lock owner's priority.
625
624 Core::System::GetInstance().PrepareReschedule(); 626 Core::System::GetInstance().PrepareReschedule();
625 return RESULT_SUCCESS; 627 return RESULT_SUCCESS;
626} 628}
@@ -651,6 +653,11 @@ static ResultCode SignalProcessWideKey(VAddr condition_variable_addr, s32 target
651 ASSERT(thread->status == THREADSTATUS_WAIT_MUTEX); 653 ASSERT(thread->status == THREADSTATUS_WAIT_MUTEX);
652 thread->ResumeFromWait(); 654 thread->ResumeFromWait();
653 655
656 auto lock_owner = thread->lock_owner;
657 if (lock_owner)
658 lock_owner->RemoveMutexWaiter(thread);
659
660 thread->lock_owner = nullptr;
654 thread->mutex_wait_address = 0; 661 thread->mutex_wait_address = 0;
655 thread->condvar_wait_address = 0; 662 thread->condvar_wait_address = 0;
656 thread->wait_handle = 0; 663 thread->wait_handle = 0;
@@ -666,6 +673,8 @@ static ResultCode SignalProcessWideKey(VAddr condition_variable_addr, s32 target
666 // Signal that the mutex now has a waiting thread. 673 // Signal that the mutex now has a waiting thread.
667 Memory::Write32(thread->mutex_wait_address, mutex_val | Mutex::MutexHasWaitersFlag); 674 Memory::Write32(thread->mutex_wait_address, mutex_val | Mutex::MutexHasWaitersFlag);
668 675
676 owner->AddMutexWaiter(thread);
677
669 Core::System::GetInstance().PrepareReschedule(); 678 Core::System::GetInstance().PrepareReschedule();
670 } 679 }
671 680