Some improvements to SetThreadCoreMask, simplified implementation of wait lists
This commit is contained in:
parent
9e50ed53e6
commit
ee0b14ba08
5 changed files with 199 additions and 325 deletions
|
@ -1,5 +1,5 @@
|
|||
using ChocolArm64;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Ryujinx.Core.OsHle.Handles
|
||||
{
|
||||
|
@ -14,16 +14,15 @@ namespace Ryujinx.Core.OsHle.Handles
|
|||
|
||||
private Process Process;
|
||||
|
||||
public KThread NextMutexThread { get; set; }
|
||||
public KThread NextCondVarThread { get; set; }
|
||||
public List<KThread> MutexWaiters { get; private set; }
|
||||
|
||||
public KThread MutexOwner { get; set; }
|
||||
|
||||
public int ActualPriority { get; private set; }
|
||||
public int WantedPriority { get; private set; }
|
||||
|
||||
public int IdealCore { get; set; }
|
||||
public int ActualCore { get; set; }
|
||||
public int IdealCore { get; set; }
|
||||
|
||||
public int WaitHandle { get; set; }
|
||||
|
||||
|
@ -39,6 +38,8 @@ namespace Ryujinx.Core.OsHle.Handles
|
|||
this.Process = Process;
|
||||
this.IdealCore = IdealCore;
|
||||
|
||||
MutexWaiters = new List<KThread>();
|
||||
|
||||
CoreMask = 1 << IdealCore;
|
||||
|
||||
ActualPriority = WantedPriority = Priority;
|
||||
|
@ -57,148 +58,25 @@ namespace Ryujinx.Core.OsHle.Handles
|
|||
|
||||
int CurrPriority = WantedPriority;
|
||||
|
||||
if (NextMutexThread != null && CurrPriority > NextMutexThread.WantedPriority)
|
||||
lock (Process.ThreadSyncLock)
|
||||
{
|
||||
CurrPriority = NextMutexThread.WantedPriority;
|
||||
foreach (KThread Thread in MutexWaiters)
|
||||
{
|
||||
if (CurrPriority > Thread.WantedPriority)
|
||||
{
|
||||
CurrPriority = Thread.WantedPriority;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (CurrPriority != OldPriority)
|
||||
{
|
||||
ActualPriority = CurrPriority;
|
||||
|
||||
UpdateWaitLists();
|
||||
Process.Scheduler.Resort(this);
|
||||
|
||||
MutexOwner?.UpdatePriority();
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateWaitLists()
|
||||
{
|
||||
UpdateMutexList();
|
||||
UpdateCondVarList();
|
||||
|
||||
Process.Scheduler.Resort(this);
|
||||
}
|
||||
|
||||
private void UpdateMutexList()
|
||||
{
|
||||
KThread OwnerThread = MutexOwner;
|
||||
|
||||
if (OwnerThread == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//The MutexOwner field should only be non-null when the thread is
|
||||
//waiting for the lock, and the lock belongs to another thread.
|
||||
if (OwnerThread == this)
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
lock (OwnerThread)
|
||||
{
|
||||
//Remove itself from the list.
|
||||
KThread CurrThread = OwnerThread;
|
||||
|
||||
while (CurrThread.NextMutexThread != null)
|
||||
{
|
||||
if (CurrThread.NextMutexThread == this)
|
||||
{
|
||||
CurrThread.NextMutexThread = NextMutexThread;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
CurrThread = CurrThread.NextMutexThread;
|
||||
}
|
||||
|
||||
//Re-add taking new priority into account.
|
||||
CurrThread = OwnerThread;
|
||||
|
||||
while (CurrThread.NextMutexThread != null)
|
||||
{
|
||||
if (CurrThread.NextMutexThread.ActualPriority > ActualPriority)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
CurrThread = CurrThread.NextMutexThread;
|
||||
}
|
||||
|
||||
NextMutexThread = CurrThread.NextMutexThread;
|
||||
|
||||
CurrThread.NextMutexThread = this;
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateCondVarList()
|
||||
{
|
||||
lock (Process.ThreadArbiterListLock)
|
||||
{
|
||||
if (Process.ThreadArbiterListHead == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//Remove itself from the list.
|
||||
bool Found;
|
||||
|
||||
KThread CurrThread = Process.ThreadArbiterListHead;
|
||||
|
||||
if (Found = (Process.ThreadArbiterListHead == this))
|
||||
{
|
||||
Process.ThreadArbiterListHead = Process.ThreadArbiterListHead.NextCondVarThread;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (CurrThread.NextCondVarThread != null)
|
||||
{
|
||||
if (CurrThread.NextCondVarThread == this)
|
||||
{
|
||||
CurrThread.NextCondVarThread = NextCondVarThread;
|
||||
|
||||
Found = true;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
CurrThread = CurrThread.NextCondVarThread;
|
||||
}
|
||||
}
|
||||
|
||||
if (!Found)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//Re-add taking new priority into account.
|
||||
if (Process.ThreadArbiterListHead == null ||
|
||||
Process.ThreadArbiterListHead.ActualPriority > ActualPriority)
|
||||
{
|
||||
NextCondVarThread = Process.ThreadArbiterListHead;
|
||||
|
||||
Process.ThreadArbiterListHead = this;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
CurrThread = Process.ThreadArbiterListHead;
|
||||
|
||||
while (CurrThread.NextCondVarThread != null)
|
||||
{
|
||||
if (CurrThread.NextCondVarThread.ActualPriority > ActualPriority)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
CurrThread = CurrThread.NextCondVarThread;
|
||||
}
|
||||
|
||||
NextCondVarThread = CurrThread.NextCondVarThread;
|
||||
|
||||
CurrThread.NextCondVarThread = this;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue