mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-12-27 18:51:52 +01:00
Fix PI update KThread::waiterMutex
deadlock
It was determined that deadlocks inside `KThread::UpdatePriorityInheritance` would not only arise from the first level of locking with `waitingOn->waiterMutex` but also the second level of locking with `nextThread->waiterMutex` which has now also been fixed to fallback when facing contention.
This commit is contained in:
parent
86f6fc510e
commit
7966bfa9f6
@ -296,7 +296,9 @@ namespace skyline::kernel::type {
|
||||
waitingOn->priority = ownerPriority;
|
||||
|
||||
lock.unlock();
|
||||
|
||||
waiterLock.lock();
|
||||
waiterLock.unlock();
|
||||
|
||||
lock.lock();
|
||||
waitingOn = waitThread;
|
||||
@ -307,7 +309,23 @@ namespace skyline::kernel::type {
|
||||
auto nextThread{waitingOn->waitThread};
|
||||
if (nextThread) {
|
||||
// We need to update the location of the owner thread in the waiter queue of the thread it's waiting on
|
||||
std::scoped_lock nextWaiterLock{nextThread->waiterMutex};
|
||||
std::unique_lock nextWaiterLock{nextThread->waiterMutex, std::try_to_lock};
|
||||
if (!nextWaiterLock) {
|
||||
// We want to avoid a deadlock here from the thread holding nextThread->waiterMutex waiting for waiterMutex or waitingOn->waiterMutex
|
||||
waitingOn->priority = ownerPriority;
|
||||
|
||||
lock.unlock();
|
||||
waiterLock.unlock();
|
||||
|
||||
nextWaiterLock.lock();
|
||||
nextWaiterLock.unlock();
|
||||
|
||||
lock.lock();
|
||||
waitingOn = waitThread;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
auto &piWaiters{nextThread->waiters};
|
||||
piWaiters.erase(std::find(piWaiters.begin(), piWaiters.end(), waitingOn));
|
||||
piWaiters.insert(std::upper_bound(piWaiters.begin(), piWaiters.end(), currentPriority, KThread::IsHigherPriority), waitingOn);
|
||||
|
Loading…
Reference in New Issue
Block a user