diff options
| author | gdkchan <gab.dark.100@gmail.com> | 2018-04-18 23:52:23 -0300 |
|---|---|---|
| committer | gdkchan <gab.dark.100@gmail.com> | 2018-04-18 23:52:36 -0300 |
| commit | b9af34f3dd1e7f5e38b038f182c9fd4a791fdfea (patch) | |
| tree | e86e7941f5d2871ed2d9bd702b38997c86fb2af8 /Ryujinx.Core/OsHle/Handles | |
| parent | e9a96e3522ee7620b525d210915a0e45510ea528 (diff) | |
[HLE/Kernel] Somewhat improved sync primitives
Diffstat (limited to 'Ryujinx.Core/OsHle/Handles')
| -rw-r--r-- | Ryujinx.Core/OsHle/Handles/KProcessScheduler.cs | 154 | ||||
| -rw-r--r-- | Ryujinx.Core/OsHle/Handles/KSynchronizationObject.cs | 6 | ||||
| -rw-r--r-- | Ryujinx.Core/OsHle/Handles/KThread.cs | 6 |
3 files changed, 56 insertions, 110 deletions
diff --git a/Ryujinx.Core/OsHle/Handles/KProcessScheduler.cs b/Ryujinx.Core/OsHle/Handles/KProcessScheduler.cs index 7ba78b3f..238febd0 100644 --- a/Ryujinx.Core/OsHle/Handles/KProcessScheduler.cs +++ b/Ryujinx.Core/OsHle/Handles/KProcessScheduler.cs @@ -7,6 +7,8 @@ namespace Ryujinx.Core.OsHle.Handles { class KProcessScheduler : IDisposable { + private const int LowestPriority = 0x40; + private class SchedulerThread : IDisposable { public KThread Thread { get; private set; } @@ -51,7 +53,7 @@ namespace Ryujinx.Core.OsHle.Handles } } - public SchedulerThread Pop(int MinPriority = 0x40) + public SchedulerThread Pop(int MinPriority = LowestPriority) { lock (Threads) { @@ -130,68 +132,47 @@ namespace Ryujinx.Core.OsHle.Handles return; } - if (!ActiveProcessors.Contains(Thread.ProcessorId)) + if (ActiveProcessors.Add(Thread.ProcessorId)) { - ActiveProcessors.Add(Thread.ProcessorId); - Thread.Thread.Execute(); - Logging.Debug(LogClass.KernelScheduler, $"{GetDbgThreadInfo(Thread)} running."); + PrintDbgThreadInfo(Thread, "running."); } else { WaitingToRun[Thread.ProcessorId].Push(SchedThread); - Logging.Debug(LogClass.KernelScheduler, $"{GetDbgThreadInfo(SchedThread.Thread)} waiting to run."); + PrintDbgThreadInfo(Thread, "waiting to run."); } } } - public void Suspend(int ProcessorId) + public void RemoveThread(KThread Thread) { + PrintDbgThreadInfo(Thread, "exited."); + lock (SchedLock) { - SchedulerThread SchedThread = WaitingToRun[ProcessorId].Pop(); + SchedulerThread NewThread = WaitingToRun[Thread.ProcessorId].Pop(); - if (SchedThread != null) - { - RunThread(SchedThread); - } - else + if (NewThread == null) { - ActiveProcessors.Remove(ProcessorId); - } - } - } + Logging.Debug(LogClass.KernelScheduler, $"Nothing to run on core {Thread.ProcessorId}!"); - public void Resume(KThread CurrThread) - { - SchedulerThread SchedThread; - - Logging.Debug(LogClass.KernelScheduler, $"{GetDbgThreadInfo(CurrThread)} entering ipc delay wait state."); - - lock (SchedLock) - { - if (!AllThreads.TryGetValue(CurrThread, out SchedThread)) - { - Logging.Error(LogClass.KernelScheduler, $"{GetDbgThreadInfo(CurrThread)} was not found on the scheduler queue!"); + ActiveProcessors.Remove(Thread.ProcessorId); return; } - } - TryResumingExecution(SchedThread); + RunThread(NewThread); + } } - public bool WaitForSignal(KThread Thread, int Timeout = -1) + public void Suspend(int ProcessorId) { - SchedulerThread SchedThread; - - Logging.Debug(LogClass.KernelScheduler, $"{GetDbgThreadInfo(Thread)} entering signal wait state."); - lock (SchedLock) { - SchedThread = WaitingToRun[Thread.ProcessorId].Pop(); + SchedulerThread SchedThread = WaitingToRun[ProcessorId].Pop(); if (SchedThread != null) { @@ -199,88 +180,67 @@ namespace Ryujinx.Core.OsHle.Handles } else { - ActiveProcessors.Remove(Thread.ProcessorId); - } - - if (!AllThreads.TryGetValue(Thread, out SchedThread)) - { - Logging.Error(LogClass.KernelScheduler, $"{GetDbgThreadInfo(Thread)} was not found on the scheduler queue!"); + Logging.Debug(LogClass.KernelScheduler, $"Nothing to run on core {ProcessorId}!"); - return false; + ActiveProcessors.Remove(ProcessorId); } } - - bool Result; - - if (Timeout >= 0) - { - Logging.Debug(LogClass.KernelScheduler, $"{GetDbgThreadInfo(Thread)} has wait timeout of {Timeout}ms."); - - Result = SchedThread.WaitEvent.WaitOne(Timeout); - } - else - { - Result = SchedThread.WaitEvent.WaitOne(); - } - - TryResumingExecution(SchedThread); - - return Result; } - private void TryResumingExecution(SchedulerThread SchedThread) + public void Yield(KThread Thread) { - KThread Thread = SchedThread.Thread; + PrintDbgThreadInfo(Thread, "yielded execution."); lock (SchedLock) { - if (ActiveProcessors.Add(Thread.ProcessorId)) + SchedulerThread SchedThread = WaitingToRun[Thread.ProcessorId].Pop(Thread.Priority); + + if (SchedThread == null) { - Logging.Debug(LogClass.KernelScheduler, $"{GetDbgThreadInfo(Thread)} resuming execution..."); + PrintDbgThreadInfo(Thread, "resumed because theres nothing better to run."); return; } - WaitingToRun[Thread.ProcessorId].Push(SchedThread); + RunThread(SchedThread); } - SchedThread.WaitEvent.WaitOne(); - - Logging.Debug(LogClass.KernelScheduler, $"{GetDbgThreadInfo(Thread)} resuming execution..."); + Resume(Thread); } - public void Yield(KThread Thread) + public void Resume(KThread Thread) { SchedulerThread SchedThread; - Logging.Debug(LogClass.KernelScheduler, $"{GetDbgThreadInfo(Thread)} yielded execution."); - - lock (SchedLock) + if (!AllThreads.TryGetValue(Thread, out SchedThread)) { - SchedThread = WaitingToRun[Thread.ProcessorId].Pop(Thread.Priority); + throw new InvalidOperationException(); + } - if (SchedThread == null) - { - Logging.Debug(LogClass.KernelScheduler, $"{GetDbgThreadInfo(Thread)} resumed because theres nothing better to run."); + TryResumingExecution(SchedThread); + } - return; - } - - RunThread(SchedThread); + private void TryResumingExecution(SchedulerThread SchedThread) + { + KThread Thread = SchedThread.Thread; - if (!AllThreads.TryGetValue(Thread, out SchedThread)) + lock (SchedLock) + { + if (ActiveProcessors.Add(Thread.ProcessorId)) { - Logging.Error(LogClass.KernelScheduler, $"{GetDbgThreadInfo(Thread)} was not found on the scheduler queue!"); + PrintDbgThreadInfo(Thread, "resuming execution..."); return; } + PrintDbgThreadInfo(Thread, "entering wait state..."); + WaitingToRun[Thread.ProcessorId].Push(SchedThread); } SchedThread.WaitEvent.WaitOne(); - Logging.Debug(LogClass.KernelScheduler, $"{GetDbgThreadInfo(Thread)} resuming execution..."); + PrintDbgThreadInfo(Thread, "resuming execution..."); } private void RunThread(SchedulerThread SchedThread) @@ -291,32 +251,16 @@ namespace Ryujinx.Core.OsHle.Handles } else { - Logging.Debug(LogClass.KernelScheduler, $"{GetDbgThreadInfo(SchedThread.Thread)} running."); - } - } - - public void Signal(params KThread[] Threads) - { - lock (SchedLock) - { - foreach (KThread Thread in Threads) - { - if (AllThreads.TryGetValue(Thread, out SchedulerThread SchedThread)) - { - if (!WaitingToRun[Thread.ProcessorId].HasThread(SchedThread)) - { - Logging.Debug(LogClass.KernelScheduler, $"{GetDbgThreadInfo(Thread)} signaled."); - - SchedThread.WaitEvent.Set(); - } - } - } + PrintDbgThreadInfo(SchedThread.Thread, "running."); } } - private string GetDbgThreadInfo(KThread Thread) + private void PrintDbgThreadInfo(KThread Thread, string Message) { - return $"Thread {Thread.ThreadId} (core {Thread.ProcessorId}) prio {Thread.Priority}"; + Logging.Debug(LogClass.KernelScheduler, "(" + + "ThreadId: " + Thread.ThreadId + ", " + + "ProcessorId: " + Thread.ProcessorId + ", " + + "Priority: " + Thread.Priority + ") " + Message); } public void Dispose() diff --git a/Ryujinx.Core/OsHle/Handles/KSynchronizationObject.cs b/Ryujinx.Core/OsHle/Handles/KSynchronizationObject.cs index 015b814a..3f78b965 100644 --- a/Ryujinx.Core/OsHle/Handles/KSynchronizationObject.cs +++ b/Ryujinx.Core/OsHle/Handles/KSynchronizationObject.cs @@ -5,11 +5,11 @@ namespace Ryujinx.Core.OsHle.Handles { class KSynchronizationObject : IDisposable { - public ManualResetEvent Handle { get; private set; } + public ManualResetEvent WaitEvent { get; private set; } public KSynchronizationObject() { - Handle = new ManualResetEvent(false); + WaitEvent = new ManualResetEvent(false); } public void Dispose() @@ -21,7 +21,7 @@ namespace Ryujinx.Core.OsHle.Handles { if (Disposing) { - Handle.Dispose(); + WaitEvent.Dispose(); } } } diff --git a/Ryujinx.Core/OsHle/Handles/KThread.cs b/Ryujinx.Core/OsHle/Handles/KThread.cs index aa1b27be..9742f492 100644 --- a/Ryujinx.Core/OsHle/Handles/KThread.cs +++ b/Ryujinx.Core/OsHle/Handles/KThread.cs @@ -6,8 +6,10 @@ namespace Ryujinx.Core.OsHle.Handles { public AThread Thread { get; private set; } - public int ProcessorId { get; private set; } - public int Priority { get; set; } + public int ProcessorId { get; private set; } + + public int Priority { get; set; } + public int Handle { get; set; } public int ThreadId => Thread.ThreadId; |
