diff options
Diffstat (limited to 'Ryujinx.HLE/HOS/Kernel/Threading')
-rw-r--r-- | Ryujinx.HLE/HOS/Kernel/Threading/HleScheduler.cs | 18 | ||||
-rw-r--r-- | Ryujinx.HLE/HOS/Kernel/Threading/KCoreContext.cs | 6 | ||||
-rw-r--r-- | Ryujinx.HLE/HOS/Kernel/Threading/KCriticalSection.cs | 10 | ||||
-rw-r--r-- | Ryujinx.HLE/HOS/Kernel/Threading/KScheduler.cs | 2 | ||||
-rw-r--r-- | Ryujinx.HLE/HOS/Kernel/Threading/KThread.cs | 64 |
5 files changed, 65 insertions, 35 deletions
diff --git a/Ryujinx.HLE/HOS/Kernel/Threading/HleScheduler.cs b/Ryujinx.HLE/HOS/Kernel/Threading/HleScheduler.cs index 42eed26a..0b951134 100644 --- a/Ryujinx.HLE/HOS/Kernel/Threading/HleScheduler.cs +++ b/Ryujinx.HLE/HOS/Kernel/Threading/HleScheduler.cs @@ -36,12 +36,12 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading { KCoreContext coreContext = CoreContexts[core]; - if (coreContext.ContextSwitchNeeded && (coreContext.CurrentThread?.Context.IsCurrentThread() ?? false)) + if (coreContext.ContextSwitchNeeded && (coreContext.CurrentThread?.IsCurrentHostThread() ?? false)) { coreContext.ContextSwitch(); } - if (coreContext.CurrentThread?.Context.IsCurrentThread() ?? false) + if (coreContext.CurrentThread?.IsCurrentHostThread() ?? false) { selectedCount++; } @@ -70,14 +70,14 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading { // If this is not the thread that is currently executing, we need // to request an interrupt to allow safely starting another thread. - if (!currentThread.Context.IsCurrentThread()) + if (!currentThread.IsCurrentHostThread()) { currentThread.Context.RequestInterrupt(); return; } - CoreManager.Reset(currentThread.Context.Work); + CoreManager.Reset(currentThread.HostThread); } // Advance current core and try picking a thread, @@ -92,9 +92,9 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading if (coreContext.CurrentThread != null) { - CoreManager.Set(coreContext.CurrentThread.Context.Work); + CoreManager.Set(coreContext.CurrentThread.HostThread); - coreContext.CurrentThread.Context.Execute(); + coreContext.CurrentThread.Execute(); break; } @@ -134,14 +134,14 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading public void ExitThread(KThread thread) { - thread.Context.StopExecution(); + thread.Context.Running = false; - CoreManager.Exit(thread.Context.Work); + CoreManager.Exit(thread.HostThread); } public void RemoveThread(KThread thread) { - CoreManager.RemoveThread(thread.Context.Work); + CoreManager.RemoveThread(thread.HostThread); } } }
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Kernel/Threading/KCoreContext.cs b/Ryujinx.HLE/HOS/Kernel/Threading/KCoreContext.cs index 97907177..0aa12b0d 100644 --- a/Ryujinx.HLE/HOS/Kernel/Threading/KCoreContext.cs +++ b/Ryujinx.HLE/HOS/Kernel/Threading/KCoreContext.cs @@ -58,7 +58,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading if (CurrentThread != null) { - _coreManager.Reset(CurrentThread.Context.Work); + _coreManager.Reset(CurrentThread.HostThread); } CurrentThread = SelectedThread; @@ -70,9 +70,9 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading CurrentThread.TotalTimeRunning += currentTime - CurrentThread.LastScheduledTime; CurrentThread.LastScheduledTime = currentTime; - _coreManager.Set(CurrentThread.Context.Work); + _coreManager.Set(CurrentThread.HostThread); - CurrentThread.Context.Execute(); + CurrentThread.Execute(); } } } diff --git a/Ryujinx.HLE/HOS/Kernel/Threading/KCriticalSection.cs b/Ryujinx.HLE/HOS/Kernel/Threading/KCriticalSection.cs index 39c857b5..b7013bb7 100644 --- a/Ryujinx.HLE/HOS/Kernel/Threading/KCriticalSection.cs +++ b/Ryujinx.HLE/HOS/Kernel/Threading/KCriticalSection.cs @@ -1,4 +1,4 @@ -using ChocolArm64; +using ARMeilleure; using System.Threading; namespace Ryujinx.HLE.HOS.Kernel.Threading @@ -53,14 +53,14 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading if (coreContext.ContextSwitchNeeded) { - CpuThread currentHleThread = coreContext.CurrentThread?.Context; + KThread currentThread = coreContext.CurrentThread; - if (currentHleThread == null) + if (currentThread == null) { // Nothing is running, we can perform the context switch immediately. coreContext.ContextSwitch(); } - else if (currentHleThread.IsCurrentThread()) + else if (currentThread.IsCurrentHostThread()) { // Thread running on the current core, context switch will block. doContextSwitch = true; @@ -68,7 +68,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading else { // Thread running on another core, request a interrupt. - currentHleThread.RequestInterrupt(); + currentThread.Context.RequestInterrupt(); } } } diff --git a/Ryujinx.HLE/HOS/Kernel/Threading/KScheduler.cs b/Ryujinx.HLE/HOS/Kernel/Threading/KScheduler.cs index 8d2cdfce..dd5422b8 100644 --- a/Ryujinx.HLE/HOS/Kernel/Threading/KScheduler.cs +++ b/Ryujinx.HLE/HOS/Kernel/Threading/KScheduler.cs @@ -203,7 +203,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading { for (int core = 0; core < CpuCoresCount; core++) { - if (CoreContexts[core].CurrentThread?.Context.IsCurrentThread() ?? false) + if (CoreContexts[core].CurrentThread?.IsCurrentHostThread() ?? false) { return CoreContexts[core].CurrentThread; } diff --git a/Ryujinx.HLE/HOS/Kernel/Threading/KThread.cs b/Ryujinx.HLE/HOS/Kernel/Threading/KThread.cs index 50c71ea9..54d5d06c 100644 --- a/Ryujinx.HLE/HOS/Kernel/Threading/KThread.cs +++ b/Ryujinx.HLE/HOS/Kernel/Threading/KThread.cs @@ -1,5 +1,5 @@ -using ChocolArm64; -using ChocolArm64.Memory; +using ARMeilleure.Memory; +using ARMeilleure.State; using Ryujinx.Common.Logging; using Ryujinx.HLE.HOS.Kernel.Common; using Ryujinx.HLE.HOS.Kernel.Process; @@ -7,12 +7,17 @@ using System; using System.Collections.Generic; using System.Linq; using System.Text; +using System.Threading; namespace Ryujinx.HLE.HOS.Kernel.Threading { class KThread : KSynchronizationObject, IKFutureSchedulerObject { - public CpuThread Context { get; private set; } + private int _hostThreadRunning; + + public Thread HostThread { get; private set; } + + public IExecutionContext Context { get; private set; } public long AffinityMask { get; set; } @@ -152,30 +157,35 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading is64Bits = true; } - Context = new CpuThread(owner.Translator, owner.CpuMemory, (long)entrypoint); + HostThread = new Thread(() => ThreadStart(entrypoint)); - bool isAarch32 = (Owner.MmuFlags & 1) == 0; + if (System.UseLegacyJit) + { + Context = new ChocolArm64.State.CpuThreadState(); + } + else + { + Context = new ARMeilleure.State.ExecutionContext(); + } - Context.ThreadState.Aarch32 = isAarch32; + bool isAarch32 = (Owner.MmuFlags & 1) == 0; - Context.ThreadState.X0 = argsPtr; + Context.SetX(0, argsPtr); if (isAarch32) { - Context.ThreadState.X13 = (uint)stackTop; + Context.SetX(13, (uint)stackTop); } else { - Context.ThreadState.X31 = stackTop; + Context.SetX(31, stackTop); } - Context.ThreadState.CntfrqEl0 = 19200000; - Context.ThreadState.Tpidr = (long)_tlsAddress; + Context.CntfrqEl0 = 19200000; + Context.Tpidr = (long)_tlsAddress; owner.SubscribeThreadEventHandlers(Context); - Context.WorkFinished += ThreadFinishedHandler; - ThreadUid = System.GetThreadUid(); _hasBeenInitialized = true; @@ -1002,8 +1012,8 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading public void SetEntryArguments(long argsPtr, int threadHandle) { - Context.ThreadState.X0 = (ulong)argsPtr; - Context.ThreadState.X1 = (ulong)threadHandle; + Context.SetX(0, (ulong)argsPtr); + Context.SetX(1, (ulong)threadHandle); } public void TimeUp() @@ -1013,7 +1023,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading public string GetGuestStackTrace() { - return Owner.Debugger.GetGuestStackTrace(Context.ThreadState); + return Owner.Debugger.GetGuestStackTrace(Context); } public void PrintGuestStackTrace() @@ -1026,12 +1036,32 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading Logger.PrintInfo(LogClass.Cpu, trace.ToString()); } - private void ThreadFinishedHandler(object sender, EventArgs e) + public void Execute() + { + if (Interlocked.CompareExchange(ref _hostThreadRunning, 1, 0) == 0) + { + HostThread.Start(); + } + } + + private void ThreadStart(ulong entrypoint) + { + Owner.Translator.Execute(Context, entrypoint); + + ThreadExit(); + } + + private void ThreadExit() { System.Scheduler.ExitThread(this); System.Scheduler.RemoveThread(this); } + public bool IsCurrentHostThread() + { + return Thread.CurrentThread == HostThread; + } + public override bool IsSignaled() { return _hasExited; |