Rewrite scheduler context switch code (#1786)
* Rewrite scheduler context switch code * Fix race in UnmapIpcRestorePermission * Fix thread exit issue that could leave the scheduler in a invalid state * Change context switch method to not wait on guest thread, remove spin wait, use SignalAndWait to pass control * Remove multi-core setting (it is always on now) * Re-enable assert * Remove multicore from default config and schema * Fix race in KTimeManager
This commit is contained in:
parent
3484265d37
commit
48278905d1
37 changed files with 1080 additions and 1160 deletions
|
@ -19,6 +19,8 @@ namespace Ryujinx.HLE.HOS.Kernel
|
|||
|
||||
public bool KernelInitialized { get; }
|
||||
|
||||
public bool Running { get; private set; }
|
||||
|
||||
public Switch Device { get; }
|
||||
public MemoryBlock Memory { get; }
|
||||
public Syscall Syscall { get; }
|
||||
|
@ -34,7 +36,8 @@ namespace Ryujinx.HLE.HOS.Kernel
|
|||
public KSlabHeap UserSlabHeapPages { get; }
|
||||
|
||||
public KCriticalSection CriticalSection { get; }
|
||||
public KScheduler Scheduler { get; }
|
||||
public KScheduler[] Schedulers { get; }
|
||||
public KPriorityQueue PriorityQueue { get; }
|
||||
public KTimeManager TimeManager { get; }
|
||||
public KSynchronization Synchronization { get; }
|
||||
public KContextIdManager ContextIdManager { get; }
|
||||
|
@ -42,6 +45,8 @@ namespace Ryujinx.HLE.HOS.Kernel
|
|||
public ConcurrentDictionary<long, KProcess> Processes { get; }
|
||||
public ConcurrentDictionary<string, KAutoObject> AutoObjectNames { get; }
|
||||
|
||||
public bool ThreadReselectionRequested { get; set; }
|
||||
|
||||
private long _kipId;
|
||||
private long _processId;
|
||||
private long _threadUid;
|
||||
|
@ -51,6 +56,8 @@ namespace Ryujinx.HLE.HOS.Kernel
|
|||
Device = device;
|
||||
Memory = memory;
|
||||
|
||||
Running = true;
|
||||
|
||||
Syscall = new Syscall(this);
|
||||
|
||||
SyscallHandler = new SyscallHandler(this);
|
||||
|
@ -70,12 +77,18 @@ namespace Ryujinx.HLE.HOS.Kernel
|
|||
KernelConstants.UserSlabHeapSize);
|
||||
|
||||
CriticalSection = new KCriticalSection(this);
|
||||
Scheduler = new KScheduler(this);
|
||||
TimeManager = new KTimeManager();
|
||||
Schedulers = new KScheduler[KScheduler.CpuCoresCount];
|
||||
PriorityQueue = new KPriorityQueue();
|
||||
TimeManager = new KTimeManager(this);
|
||||
Synchronization = new KSynchronization(this);
|
||||
ContextIdManager = new KContextIdManager();
|
||||
|
||||
Scheduler.StartAutoPreemptionThread();
|
||||
for (int core = 0; core < KScheduler.CpuCoresCount; core++)
|
||||
{
|
||||
Schedulers[core] = new KScheduler(this, core);
|
||||
}
|
||||
|
||||
StartPreemptionThread();
|
||||
|
||||
KernelInitialized = true;
|
||||
|
||||
|
@ -86,6 +99,16 @@ namespace Ryujinx.HLE.HOS.Kernel
|
|||
_processId = KernelConstants.InitialProcessId;
|
||||
}
|
||||
|
||||
private void StartPreemptionThread()
|
||||
{
|
||||
void PreemptionThreadStart()
|
||||
{
|
||||
KScheduler.PreemptionThreadLoop(this);
|
||||
}
|
||||
|
||||
new Thread(PreemptionThreadStart) { Name = "HLE.PreemptionThread" }.Start();
|
||||
}
|
||||
|
||||
public long NewThreadUid()
|
||||
{
|
||||
return Interlocked.Increment(ref _threadUid) - 1;
|
||||
|
@ -103,7 +126,13 @@ namespace Ryujinx.HLE.HOS.Kernel
|
|||
|
||||
public void Dispose()
|
||||
{
|
||||
Scheduler.Dispose();
|
||||
Running = false;
|
||||
|
||||
for (int i = 0; i < KScheduler.CpuCoresCount; i++)
|
||||
{
|
||||
Schedulers[i].Dispose();
|
||||
}
|
||||
|
||||
TimeManager.Dispose();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue