aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Core/OsHle/Handles
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2018-04-18 23:52:23 -0300
committergdkchan <gab.dark.100@gmail.com>2018-04-18 23:52:36 -0300
commitb9af34f3dd1e7f5e38b038f182c9fd4a791fdfea (patch)
treee86e7941f5d2871ed2d9bd702b38997c86fb2af8 /Ryujinx.Core/OsHle/Handles
parente9a96e3522ee7620b525d210915a0e45510ea528 (diff)
[HLE/Kernel] Somewhat improved sync primitives
Diffstat (limited to 'Ryujinx.Core/OsHle/Handles')
-rw-r--r--Ryujinx.Core/OsHle/Handles/KProcessScheduler.cs154
-rw-r--r--Ryujinx.Core/OsHle/Handles/KSynchronizationObject.cs6
-rw-r--r--Ryujinx.Core/OsHle/Handles/KThread.cs6
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;