aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Core/OsHle/Svc/SvcThreadSync.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Ryujinx.Core/OsHle/Svc/SvcThreadSync.cs')
-rw-r--r--Ryujinx.Core/OsHle/Svc/SvcThreadSync.cs78
1 files changed, 78 insertions, 0 deletions
diff --git a/Ryujinx.Core/OsHle/Svc/SvcThreadSync.cs b/Ryujinx.Core/OsHle/Svc/SvcThreadSync.cs
new file mode 100644
index 00000000..dec13f75
--- /dev/null
+++ b/Ryujinx.Core/OsHle/Svc/SvcThreadSync.cs
@@ -0,0 +1,78 @@
+using ChocolArm64.State;
+using Ryujinx.Core.OsHle.Handles;
+
+namespace Ryujinx.Core.OsHle.Svc
+{
+ partial class SvcHandler
+ {
+ private void SvcArbitrateLock(AThreadState ThreadState)
+ {
+ int OwnerThreadHandle = (int)ThreadState.X0;
+ long MutexAddress = (long)ThreadState.X1;
+ int RequestingThreadHandle = (int)ThreadState.X2;
+
+ HThread RequestingThread = Ns.Os.Handles.GetData<HThread>(RequestingThreadHandle);
+
+ Mutex M = new Mutex(Process, MutexAddress, OwnerThreadHandle);
+
+ M = Ns.Os.Mutexes.GetOrAdd(MutexAddress, M);
+
+ M.WaitForLock(RequestingThread, RequestingThreadHandle);
+
+ ThreadState.X0 = (int)SvcResult.Success;
+ }
+
+ private void SvcArbitrateUnlock(AThreadState ThreadState)
+ {
+ long MutexAddress = (long)ThreadState.X0;
+
+ if (Ns.Os.Mutexes.TryGetValue(MutexAddress, out Mutex M))
+ {
+ M.Unlock();
+ }
+
+ ThreadState.X0 = (int)SvcResult.Success;
+ }
+
+ 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;
+
+ HThread Thread = Ns.Os.Handles.GetData<HThread>(ThreadHandle);
+
+ Mutex M = new Mutex(Process, MutexAddress, ThreadHandle);
+
+ M = Ns.Os.Mutexes.GetOrAdd(MutexAddress, M);
+
+ M.GiveUpLock(ThreadHandle);
+
+ CondVar Cv = new CondVar(Process, CondVarAddress, Timeout);
+
+ Cv = Ns.Os.CondVars.GetOrAdd(CondVarAddress, Cv);
+
+ Cv.WaitForSignal(Thread);
+
+ M.WaitForLock(Thread, ThreadHandle);
+
+ ThreadState.X0 = (int)SvcResult.Success;
+ }
+
+ private void SvcSignalProcessWideKey(AThreadState ThreadState)
+ {
+ long CondVarAddress = (long)ThreadState.X0;
+ int Count = (int)ThreadState.X1;
+
+ HThread CurrThread = Process.GetThread(ThreadState.Tpidr);
+
+ if (Ns.Os.CondVars.TryGetValue(CondVarAddress, out CondVar Cv))
+ {
+ Cv.SetSignal(CurrThread, Count);
+ }
+
+ ThreadState.X0 = (int)SvcResult.Success;
+ }
+ }
+} \ No newline at end of file