mirror of
https://git.ryujinx.app/projects/Kenji-NX.git
synced 2026-09-29 09:58:02 +02:00
Memory changes 2.2
A few more internal changes to the RangeList systems. * No longer using a QuickAccess dictionary. * The performance of the dictionary wasn't much faster than just doing binary searches. * Using just binary searches allows us to take advantage of span and array returns as they're are faster than linked lists when iterating or copying the overlaps. Small code optimizations. Fixes a few leftover crashes.
This commit is contained in:
@@ -873,7 +873,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
||||
{
|
||||
lock (_threadingLock)
|
||||
{
|
||||
thread.ProcessListNode = _threads.AddLast(thread);
|
||||
_threads.AddLast(thread.ProcessListNode);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1235,7 +1235,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
|
||||
{
|
||||
thread.Suspend(ThreadSchedState.ThreadPauseFlag);
|
||||
thread.Context.RequestInterrupt();
|
||||
if (!thread.DebugHalt.WaitOne(TimeSpan.FromMilliseconds(50)))
|
||||
if (!thread.DebugHalt.Wait(TimeSpan.FromMilliseconds(50)))
|
||||
{
|
||||
Logger.Warning?.Print(LogClass.Kernel, $"Failed to suspend thread {thread.ThreadUid} in time.");
|
||||
}
|
||||
|
||||
@@ -13,16 +13,8 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
|
||||
|
||||
Monitor.Exit(mutex);
|
||||
|
||||
currentThread.Withholder = threadList;
|
||||
|
||||
currentThread.Reschedule(ThreadSchedState.Paused);
|
||||
|
||||
currentThread.WithholderNode = threadList.AddLast(currentThread);
|
||||
|
||||
if (currentThread.TerminationRequested)
|
||||
{
|
||||
threadList.Remove(currentThread.WithholderNode);
|
||||
|
||||
currentThread.Reschedule(ThreadSchedState.Running);
|
||||
|
||||
currentThread.Withholder = null;
|
||||
@@ -31,6 +23,12 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
|
||||
}
|
||||
else
|
||||
{
|
||||
currentThread.Withholder = threadList;
|
||||
|
||||
currentThread.Reschedule(ThreadSchedState.Paused);
|
||||
|
||||
threadList.AddLast(currentThread.WithholderNode);
|
||||
|
||||
if (timeout > 0)
|
||||
{
|
||||
context.TimeManager.ScheduleFutureInvocation(currentThread, timeout);
|
||||
|
||||
@@ -50,7 +50,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
|
||||
// even if they are not scheduled on guest cores.
|
||||
if (currentThread != null && !currentThread.IsSchedulable && currentThread.Context.Running)
|
||||
{
|
||||
currentThread.SchedulerWaitEvent.WaitOne();
|
||||
currentThread.SchedulerWaitEvent.Wait();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -194,7 +194,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
|
||||
return;
|
||||
}
|
||||
|
||||
thread.SiblingsPerCore[core] = SuggestedQueue(prio, core).AddFirst(thread);
|
||||
SuggestedQueue(prio, core).AddFirst(thread.SiblingsPerCore[core]);
|
||||
|
||||
_suggestedPrioritiesPerCore[core] |= 1L << prio;
|
||||
}
|
||||
@@ -223,7 +223,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
|
||||
return;
|
||||
}
|
||||
|
||||
thread.SiblingsPerCore[core] = ScheduledQueue(prio, core).AddLast(thread);
|
||||
ScheduledQueue(prio, core).AddLast(thread.SiblingsPerCore[core]);
|
||||
|
||||
_scheduledPrioritiesPerCore[core] |= 1L << prio;
|
||||
}
|
||||
@@ -235,7 +235,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
|
||||
return;
|
||||
}
|
||||
|
||||
thread.SiblingsPerCore[core] = ScheduledQueue(prio, core).AddFirst(thread);
|
||||
ScheduledQueue(prio, core).AddFirst(thread.SiblingsPerCore[core]);
|
||||
|
||||
_scheduledPrioritiesPerCore[core] |= 1L << prio;
|
||||
}
|
||||
@@ -251,7 +251,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
|
||||
|
||||
queue.Remove(thread.SiblingsPerCore[core]);
|
||||
|
||||
thread.SiblingsPerCore[core] = queue.AddLast(thread);
|
||||
queue.AddLast(thread.SiblingsPerCore[core]);
|
||||
|
||||
return queue.First?.Value;
|
||||
}
|
||||
|
||||
@@ -321,11 +321,12 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
|
||||
if (nextThread == null)
|
||||
{
|
||||
ActivateIdleThread();
|
||||
currentThread.SchedulerWaitEvent.WaitOne();
|
||||
currentThread.SchedulerWaitEvent.Wait();
|
||||
}
|
||||
else
|
||||
{
|
||||
WaitHandle.SignalAndWait(nextThread.SchedulerWaitEvent, currentThread.SchedulerWaitEvent);
|
||||
nextThread.SchedulerWaitEvent.Set();
|
||||
currentThread.SchedulerWaitEvent.Wait();
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@@ -39,9 +39,9 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
|
||||
|
||||
public const int MaxWaitSyncObjects = 64;
|
||||
|
||||
private ManualResetEvent _schedulerWaitEvent;
|
||||
private ManualResetEventSlim _schedulerWaitEvent;
|
||||
|
||||
public ManualResetEvent SchedulerWaitEvent => _schedulerWaitEvent;
|
||||
public ManualResetEventSlim SchedulerWaitEvent => _schedulerWaitEvent;
|
||||
|
||||
public Thread HostThread { get; private set; }
|
||||
|
||||
@@ -93,6 +93,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
|
||||
private LinkedListNode<KThread> _mutexWaiterNode;
|
||||
|
||||
private readonly LinkedList<KThread> _pinnedWaiters;
|
||||
private LinkedListNode<KThread> _pinnedWaiterNode;
|
||||
|
||||
public KThread MutexOwner { get; private set; }
|
||||
|
||||
@@ -135,7 +136,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
|
||||
|
||||
private readonly Lock _activityOperationLock = new();
|
||||
|
||||
internal readonly ManualResetEvent DebugHalt = new(false);
|
||||
internal readonly ManualResetEventSlim DebugHalt = new(false);
|
||||
|
||||
public KThread(KernelContext context) : base(context)
|
||||
{
|
||||
@@ -144,8 +145,18 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
|
||||
|
||||
SiblingsPerCore = new LinkedListNode<KThread>[KScheduler.CpuCoresCount];
|
||||
|
||||
for (int i = 0; i < SiblingsPerCore.Length; i++)
|
||||
{
|
||||
SiblingsPerCore[i] = new LinkedListNode<KThread>(this);
|
||||
}
|
||||
|
||||
_mutexWaiters = [];
|
||||
_pinnedWaiters = [];
|
||||
|
||||
WithholderNode = new LinkedListNode<KThread>(this);
|
||||
ProcessListNode = new LinkedListNode<KThread>(this);
|
||||
_mutexWaiterNode = new LinkedListNode<KThread>(this);
|
||||
_pinnedWaiterNode = new LinkedListNode<KThread>(this);
|
||||
}
|
||||
|
||||
public Result Initialize(
|
||||
@@ -631,7 +642,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
|
||||
break;
|
||||
}
|
||||
|
||||
_pinnedWaiters.AddLast(currentThread);
|
||||
_pinnedWaiters.AddLast(_pinnedWaiterNode);
|
||||
|
||||
currentThread.Reschedule(ThreadSchedState.Paused);
|
||||
}
|
||||
@@ -848,7 +859,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
|
||||
return KernelResult.ThreadTerminating;
|
||||
}
|
||||
|
||||
_pinnedWaiters.AddLast(currentThread);
|
||||
_pinnedWaiters.AddLast(_pinnedWaiterNode);
|
||||
|
||||
currentThread.Reschedule(ThreadSchedState.Paused);
|
||||
}
|
||||
@@ -1262,7 +1273,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
|
||||
{
|
||||
if (_schedulerWaitEvent == null)
|
||||
{
|
||||
var schedulerWaitEvent = new ManualResetEvent(false);
|
||||
var schedulerWaitEvent = new ManualResetEventSlim(false);
|
||||
|
||||
if (Interlocked.Exchange(ref _schedulerWaitEvent, schedulerWaitEvent) == null)
|
||||
{
|
||||
@@ -1277,7 +1288,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
|
||||
|
||||
private void ThreadStart()
|
||||
{
|
||||
_schedulerWaitEvent.WaitOne();
|
||||
_schedulerWaitEvent.Wait();
|
||||
DebugHalt.Reset();
|
||||
KernelStatic.SetKernelContext(KernelContext, this);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user