diff options
| author | 2018-04-20 20:15:16 -0500 | |
|---|---|---|
| committer | 2018-04-23 11:23:44 -0500 | |
| commit | 46572d027dc9620ed2b2a50277e6afd2a115ab81 (patch) | |
| tree | 72562a37575252e8f4c0160a3067b415027fdf4b /src/core/hle/kernel/svc.cpp | |
| parent | Kernel: Use 0x2C as default main thread priority for homebrew and lone NRO/NSOs (diff) | |
| download | yuzu-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.cpp | 9 |
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 | ||