diff options
| author | gdkchan <gab.dark.100@gmail.com> | 2018-04-19 16:18:30 -0300 |
|---|---|---|
| committer | gdkchan <gab.dark.100@gmail.com> | 2018-04-19 16:18:30 -0300 |
| commit | 03002f6537e3208e6951bc9092e958985e200c7d (patch) | |
| tree | e3e4eea4eba155d82168915ad7c3a507e3a20f59 /Ryujinx.Core/OsHle/Handles | |
| parent | 33ae6e544bd477da629e3f4ab4925f457ecfbbb7 (diff) | |
Add SvcSetThreadActivity, tweak SignalProcessWideKey, add fmul32i shader instructions and other small fixes
Diffstat (limited to 'Ryujinx.Core/OsHle/Handles')
| -rw-r--r-- | Ryujinx.Core/OsHle/Handles/KProcessScheduler.cs | 83 |
1 files changed, 72 insertions, 11 deletions
diff --git a/Ryujinx.Core/OsHle/Handles/KProcessScheduler.cs b/Ryujinx.Core/OsHle/Handles/KProcessScheduler.cs index 1300d218..2f694600 100644 --- a/Ryujinx.Core/OsHle/Handles/KProcessScheduler.cs +++ b/Ryujinx.Core/OsHle/Handles/KProcessScheduler.cs @@ -15,11 +15,15 @@ namespace Ryujinx.Core.OsHle.Handles public AutoResetEvent WaitEvent { get; private set; } + public bool Active { get; set; } + public SchedulerThread(KThread Thread) { this.Thread = Thread; WaitEvent = new AutoResetEvent(false); + + Active = true; } public void Dispose() @@ -98,7 +102,10 @@ namespace Ryujinx.Core.OsHle.Handles public bool Remove(SchedulerThread SchedThread) { - return Threads.Remove(SchedThread); + lock (Threads) + { + return Threads.Remove(SchedThread); + } } } @@ -180,6 +187,55 @@ namespace Ryujinx.Core.OsHle.Handles } } + public void SetThreadActivity(KThread Thread, bool Active) + { + if (!AllThreads.TryGetValue(Thread, out SchedulerThread SchedThread)) + { + throw new InvalidOperationException(); + } + + lock (SchedLock) + { + bool OldState = SchedThread.Active; + + SchedThread.Active = Active; + + if (!OldState && Active) + { + if (ActiveProcessors.Add(Thread.ProcessorId)) + { + RunThread(SchedThread); + } + else + { + WaitingToRun[Thread.ProcessorId].Push(SchedThread); + + PrintDbgThreadInfo(Thread, "entering wait state..."); + } + } + else if (OldState && !Active) + { + if (Thread.Thread.IsCurrentThread()) + { + Suspend(Thread.ProcessorId); + + PrintDbgThreadInfo(Thread, "entering inactive wait state..."); + } + else + { + WaitingToRun[Thread.ProcessorId].Remove(SchedThread); + } + } + } + + if (!Active && Thread.Thread.IsCurrentThread()) + { + SchedThread.WaitEvent.WaitOne(); + + PrintDbgThreadInfo(Thread, "resuming execution..."); + } + } + public void Suspend(int ProcessorId) { lock (SchedLock) @@ -222,9 +278,7 @@ namespace Ryujinx.Core.OsHle.Handles public void Resume(KThread Thread) { - SchedulerThread SchedThread; - - if (!AllThreads.TryGetValue(Thread, out SchedThread)) + if (!AllThreads.TryGetValue(Thread, out SchedulerThread SchedThread)) { throw new InvalidOperationException(); } @@ -236,18 +290,25 @@ namespace Ryujinx.Core.OsHle.Handles { KThread Thread = SchedThread.Thread; - lock (SchedLock) + if (SchedThread.Active) { - if (ActiveProcessors.Add(Thread.ProcessorId)) + lock (SchedLock) { - PrintDbgThreadInfo(Thread, "resuming execution..."); + if (ActiveProcessors.Add(Thread.ProcessorId)) + { + PrintDbgThreadInfo(Thread, "resuming execution..."); - return; - } + return; + } - PrintDbgThreadInfo(Thread, "entering wait state..."); + WaitingToRun[Thread.ProcessorId].Push(SchedThread); - WaitingToRun[Thread.ProcessorId].Push(SchedThread); + PrintDbgThreadInfo(Thread, "entering wait state..."); + } + } + else + { + PrintDbgThreadInfo(Thread, "entering inactive wait state..."); } SchedThread.WaitEvent.WaitOne(); |
