aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2018-04-19 04:06:23 -0300
committergdkchan <gab.dark.100@gmail.com>2018-04-19 04:06:23 -0300
commit33ae6e544bd477da629e3f4ab4925f457ecfbbb7 (patch)
treecc303d3cbef41392aff1b4572eb534270644978c
parent62b2124c03694bdac5ffae7df8edfe2079bf1a9a (diff)
[HLE/Kernel] Fix SetThreadPriority, allow nano seconds values > int.MaxValue, fix on WaitProcessWideKeyAtomic (althrough looks like it still doesn't work properly
-rw-r--r--Ryujinx.Core/OsHle/Kernel/ConditionVariable.cs10
-rw-r--r--Ryujinx.Core/OsHle/Kernel/MutualExclusion.cs8
-rw-r--r--Ryujinx.Core/OsHle/Kernel/NsTimeConverter.cs19
-rw-r--r--Ryujinx.Core/OsHle/Kernel/SvcSystem.cs10
-rw-r--r--Ryujinx.Core/OsHle/Kernel/SvcThread.cs12
-rw-r--r--Ryujinx.Core/OsHle/Kernel/SvcThreadSync.cs12
6 files changed, 47 insertions, 24 deletions
diff --git a/Ryujinx.Core/OsHle/Kernel/ConditionVariable.cs b/Ryujinx.Core/OsHle/Kernel/ConditionVariable.cs
index 4e64a154..91ed9158 100644
--- a/Ryujinx.Core/OsHle/Kernel/ConditionVariable.cs
+++ b/Ryujinx.Core/OsHle/Kernel/ConditionVariable.cs
@@ -22,7 +22,7 @@ namespace Ryujinx.Core.OsHle.Kernel
WaitingThreads = new List<(KThread, AutoResetEvent)>();
}
- public bool WaitForSignal(KThread Thread, long Timeout)
+ public bool WaitForSignal(KThread Thread, ulong Timeout)
{
bool Result = true;
@@ -37,23 +37,19 @@ namespace Ryujinx.Core.OsHle.Kernel
WaitingThreads.Add((Thread, WaitEvent));
}
- Process.Scheduler.Suspend(Thread.ProcessorId);
-
- if (Timeout < 0)
+ if (Timeout == ulong.MaxValue)
{
Result = WaitEvent.WaitOne();
}
else
{
- Result = WaitEvent.WaitOne((int)(Timeout / 1000000));
+ Result = WaitEvent.WaitOne(NsTimeConverter.GetTimeMs(Timeout));
lock (WaitingThreads)
{
WaitingThreads.Remove((Thread, WaitEvent));
}
}
-
- Process.Scheduler.Resume(Thread);
}
}
diff --git a/Ryujinx.Core/OsHle/Kernel/MutualExclusion.cs b/Ryujinx.Core/OsHle/Kernel/MutualExclusion.cs
index aeaaf70f..9f05406b 100644
--- a/Ryujinx.Core/OsHle/Kernel/MutualExclusion.cs
+++ b/Ryujinx.Core/OsHle/Kernel/MutualExclusion.cs
@@ -12,6 +12,8 @@ namespace Ryujinx.Core.OsHle.Kernel
private long MutexAddress;
+ private int OwnerThreadHandle;
+
private List<(KThread Thread, AutoResetEvent WaitEvent)> WaitingThreads;
public MutualExclusion(Process Process, long MutexAddress)
@@ -24,8 +26,6 @@ namespace Ryujinx.Core.OsHle.Kernel
public void WaitForLock(KThread RequestingThread)
{
- int OwnerThreadHandle = Process.Memory.ReadInt32(MutexAddress) & ~MutexHasListenersMask;
-
WaitForLock(RequestingThread, OwnerThreadHandle);
}
@@ -80,10 +80,14 @@ namespace Ryujinx.Core.OsHle.Kernel
WaitingThreads.RemoveAt(HighestPrioIndex);
Process.Memory.WriteInt32(MutexAddress, HasListeners | Handle);
+
+ OwnerThreadHandle = Handle;
}
else
{
Process.Memory.WriteInt32(MutexAddress, 0);
+
+ OwnerThreadHandle = 0;
}
}
}
diff --git a/Ryujinx.Core/OsHle/Kernel/NsTimeConverter.cs b/Ryujinx.Core/OsHle/Kernel/NsTimeConverter.cs
new file mode 100644
index 00000000..84fb0b85
--- /dev/null
+++ b/Ryujinx.Core/OsHle/Kernel/NsTimeConverter.cs
@@ -0,0 +1,19 @@
+namespace Ryujinx.Core.OsHle.Kernel
+{
+ static class NsTimeConverter
+ {
+ public static int GetTimeMs(ulong Ns)
+ {
+ ulong Ms = Ns / 1_000_000;
+
+ if (Ms < int.MaxValue)
+ {
+ return (int)Ms;
+ }
+ else
+ {
+ return int.MaxValue;
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.Core/OsHle/Kernel/SvcSystem.cs b/Ryujinx.Core/OsHle/Kernel/SvcSystem.cs
index ebbbef4a..48e8ce38 100644
--- a/Ryujinx.Core/OsHle/Kernel/SvcSystem.cs
+++ b/Ryujinx.Core/OsHle/Kernel/SvcSystem.cs
@@ -83,9 +83,9 @@ namespace Ryujinx.Core.OsHle.Kernel
private void SvcWaitSynchronization(AThreadState ThreadState)
{
- long HandlesPtr = (long)ThreadState.X1;
- int HandlesCount = (int)ThreadState.X2;
- long Timeout = (long)ThreadState.X3;
+ long HandlesPtr = (long)ThreadState.X1;
+ int HandlesCount = (int)ThreadState.X2;
+ ulong Timeout = ThreadState.X3;
KThread CurrThread = Process.GetThread(ThreadState.Tpidr);
@@ -115,9 +115,9 @@ namespace Ryujinx.Core.OsHle.Kernel
ulong Result = 0;
- if (Timeout != -1)
+ if (Timeout != ulong.MaxValue)
{
- HandleIndex = WaitHandle.WaitAny(Handles, (int)(Timeout / 1000000));
+ HandleIndex = WaitHandle.WaitAny(Handles, NsTimeConverter.GetTimeMs(Timeout));
if (HandleIndex == WaitHandle.WaitTimeout)
{
diff --git a/Ryujinx.Core/OsHle/Kernel/SvcThread.cs b/Ryujinx.Core/OsHle/Kernel/SvcThread.cs
index 7418732f..2534c9d9 100644
--- a/Ryujinx.Core/OsHle/Kernel/SvcThread.cs
+++ b/Ryujinx.Core/OsHle/Kernel/SvcThread.cs
@@ -64,11 +64,11 @@ namespace Ryujinx.Core.OsHle.Kernel
private void SvcSleepThread(AThreadState ThreadState)
{
- ulong NanoSecs = ThreadState.X0;
+ ulong Ns = ThreadState.X0;
KThread CurrThread = Process.GetThread(ThreadState.Tpidr);
- if (NanoSecs == 0)
+ if (Ns == 0)
{
Process.Scheduler.Yield(CurrThread);
}
@@ -76,7 +76,7 @@ namespace Ryujinx.Core.OsHle.Kernel
{
Process.Scheduler.Suspend(CurrThread.ProcessorId);
- Thread.Sleep((int)(NanoSecs / 1000000));
+ Thread.Sleep(NsTimeConverter.GetTimeMs(Ns));
Process.Scheduler.Resume(CurrThread);
}
@@ -103,14 +103,14 @@ namespace Ryujinx.Core.OsHle.Kernel
private void SvcSetThreadPriority(AThreadState ThreadState)
{
- int Prio = (int)ThreadState.X0;
- int Handle = (int)ThreadState.X1;
+ int Handle = (int)ThreadState.X0;
+ int Priority = (int)ThreadState.X1;
KThread CurrThread = Process.HandleTable.GetData<KThread>(Handle);
if (CurrThread != null)
{
- CurrThread.Priority = Prio;
+ CurrThread.Priority = Priority;
ThreadState.X0 = 0;
}
diff --git a/Ryujinx.Core/OsHle/Kernel/SvcThreadSync.cs b/Ryujinx.Core/OsHle/Kernel/SvcThreadSync.cs
index e9d801b4..38d759d3 100644
--- a/Ryujinx.Core/OsHle/Kernel/SvcThreadSync.cs
+++ b/Ryujinx.Core/OsHle/Kernel/SvcThreadSync.cs
@@ -55,10 +55,10 @@ namespace Ryujinx.Core.OsHle.Kernel
private void SvcWaitProcessWideKeyAtomic(AThreadState ThreadState)
{
- long MutexAddress = (long)ThreadState.X0;
- long CondVarAddress = (long)ThreadState.X1;
- int ThreadHandle = (int)ThreadState.X2;
- long Timeout = (long)ThreadState.X3;
+ long MutexAddress = (long)ThreadState.X0;
+ long CondVarAddress = (long)ThreadState.X1;
+ int ThreadHandle = (int)ThreadState.X2;
+ ulong Timeout = ThreadState.X3;
KThread Thread = Process.HandleTable.GetData<KThread>(ThreadHandle);
@@ -69,6 +69,8 @@ namespace Ryujinx.Core.OsHle.Kernel
ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidHandle);
}
+ Process.Scheduler.Suspend(Thread.ProcessorId);
+
MutualExclusion Mutex = GetMutex(MutexAddress);
Mutex.Unlock();
@@ -82,6 +84,8 @@ namespace Ryujinx.Core.OsHle.Kernel
Mutex.WaitForLock(Thread);
+ Process.Scheduler.Resume(Thread);
+
ThreadState.X0 = 0;
}