aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Core/OsHle/Kernel
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2018-04-19 16:18:30 -0300
committergdkchan <gab.dark.100@gmail.com>2018-04-19 16:18:30 -0300
commit03002f6537e3208e6951bc9092e958985e200c7d (patch)
treee3e4eea4eba155d82168915ad7c3a507e3a20f59 /Ryujinx.Core/OsHle/Kernel
parent33ae6e544bd477da629e3f4ab4925f457ecfbbb7 (diff)
Add SvcSetThreadActivity, tweak SignalProcessWideKey, add fmul32i shader instructions and other small fixes
Diffstat (limited to 'Ryujinx.Core/OsHle/Kernel')
-rw-r--r--Ryujinx.Core/OsHle/Kernel/ConditionVariable.cs21
-rw-r--r--Ryujinx.Core/OsHle/Kernel/SvcHandler.cs3
-rw-r--r--Ryujinx.Core/OsHle/Kernel/SvcThread.cs23
3 files changed, 40 insertions, 7 deletions
diff --git a/Ryujinx.Core/OsHle/Kernel/ConditionVariable.cs b/Ryujinx.Core/OsHle/Kernel/ConditionVariable.cs
index 91ed9158..f7657376 100644
--- a/Ryujinx.Core/OsHle/Kernel/ConditionVariable.cs
+++ b/Ryujinx.Core/OsHle/Kernel/ConditionVariable.cs
@@ -57,7 +57,7 @@ namespace Ryujinx.Core.OsHle.Kernel
Count = Process.Memory.ReadInt32(CondVarAddress);
- if (Count > 0)
+ if (Result && Count > 0)
{
Process.Memory.WriteInt32(CondVarAddress, Count - 1);
}
@@ -73,10 +73,10 @@ namespace Ryujinx.Core.OsHle.Kernel
{
if (Count < 0)
{
- Process.Memory.WriteInt32(CondVarAddress, WaitingThreads.Count);
-
foreach ((_, AutoResetEvent WaitEvent) in WaitingThreads)
{
+ IncrementCondVarValue();
+
WaitEvent.Set();
}
@@ -84,8 +84,6 @@ namespace Ryujinx.Core.OsHle.Kernel
}
else
{
- Process.Memory.WriteInt32(CondVarAddress, Count);
-
while (WaitingThreads.Count > 0 && Count-- > 0)
{
int HighestPriority = WaitingThreads[0].Thread.Priority;
@@ -101,6 +99,8 @@ namespace Ryujinx.Core.OsHle.Kernel
}
}
+ IncrementCondVarValue();
+
WaitingThreads[HighestPrioIndex].WaitEvent.Set();
WaitingThreads.RemoveAt(HighestPrioIndex);
@@ -111,6 +111,17 @@ namespace Ryujinx.Core.OsHle.Kernel
Process.Scheduler.Yield(Thread);
}
+ private void IncrementCondVarValue()
+ {
+ AcquireCondVarValue();
+
+ int Count = Process.Memory.ReadInt32(CondVarAddress);
+
+ Process.Memory.WriteInt32(CondVarAddress, Count + 1);
+
+ ReleaseCondVarValue();
+ }
+
private void AcquireCondVarValue()
{
if (!OwnsCondVarValue)
diff --git a/Ryujinx.Core/OsHle/Kernel/SvcHandler.cs b/Ryujinx.Core/OsHle/Kernel/SvcHandler.cs
index fa772988..16ef8697 100644
--- a/Ryujinx.Core/OsHle/Kernel/SvcHandler.cs
+++ b/Ryujinx.Core/OsHle/Kernel/SvcHandler.cs
@@ -63,7 +63,8 @@ namespace Ryujinx.Core.OsHle.Kernel
{ 0x25, SvcGetThreadId },
{ 0x26, SvcBreak },
{ 0x27, SvcOutputDebugString },
- { 0x29, SvcGetInfo }
+ { 0x29, SvcGetInfo },
+ { 0x32, SvcSetThreadActivity }
};
this.Ns = Ns;
diff --git a/Ryujinx.Core/OsHle/Kernel/SvcThread.cs b/Ryujinx.Core/OsHle/Kernel/SvcThread.cs
index 2534c9d9..06147b28 100644
--- a/Ryujinx.Core/OsHle/Kernel/SvcThread.cs
+++ b/Ryujinx.Core/OsHle/Kernel/SvcThread.cs
@@ -147,7 +147,28 @@ namespace Ryujinx.Core.OsHle.Kernel
}
else
{
- Logging.Warn(LogClass.KernelSvc, $"Tried to GetThreadId on invalid thread handle 0x{Handle:x8}!");
+ Logging.Warn(LogClass.KernelSvc, $"Invalid thread handle 0x{Handle:x8}!");
+
+ ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidHandle);
+ }
+ }
+
+ private void SvcSetThreadActivity(AThreadState ThreadState)
+ {
+ int Handle = (int)ThreadState.X0;
+ bool Active = (int)ThreadState.X1 != 0;
+
+ KThread CurrThread = Process.HandleTable.GetData<KThread>(Handle);
+
+ if (CurrThread != null)
+ {
+ Process.Scheduler.SetThreadActivity(CurrThread, Active);
+
+ ThreadState.X0 = 0;
+ }
+ else
+ {
+ Logging.Warn(LogClass.KernelSvc, $"Invalid thread handle 0x{Handle:x8}!");
ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidHandle);
}