From 48278905d1470f89be31668c738397f569af156a Mon Sep 17 00:00:00 2001 From: gdkchan Date: Wed, 9 Dec 2020 19:20:05 -0300 Subject: 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 --- Ryujinx.HLE/HOS/Kernel/KernelContext.cs | 39 ++++++++++++++++++++++++++++----- 1 file changed, 34 insertions(+), 5 deletions(-) (limited to 'Ryujinx.HLE/HOS/Kernel/KernelContext.cs') diff --git a/Ryujinx.HLE/HOS/Kernel/KernelContext.cs b/Ryujinx.HLE/HOS/Kernel/KernelContext.cs index d19c43ee..cacb7fb3 100644 --- a/Ryujinx.HLE/HOS/Kernel/KernelContext.cs +++ b/Ryujinx.HLE/HOS/Kernel/KernelContext.cs @@ -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 Processes { get; } public ConcurrentDictionary 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(); } } -- cgit v1.2.3