ryujinx/Ryujinx/OsHle/Svc/SvcThreadSync.cs
2018-02-18 16:28:07 -03:00

79 lines
2.4 KiB
C#

using ChocolArm64.State;
using Ryujinx.OsHle.Handles;
namespace Ryujinx.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);
if (Ns.Os.Mutexes.TryGetValue(MutexAddress, out Mutex M))
{
M.GiveUpLock(ThreadHandle);
}
CondVar Cv = new CondVar(Process, CondVarAddress, Timeout);
Cv = Ns.Os.CondVars.GetOrAdd(CondVarAddress, Cv);
Cv.WaitForSignal(Thread);
M = new Mutex(Process, MutexAddress, ThreadHandle);
M = Ns.Os.Mutexes.GetOrAdd(MutexAddress, M);
M.WaitForLock(Thread, ThreadHandle);
ThreadState.X0 = (int)SvcResult.Success;
}
private void SvcSignalProcessWideKey(AThreadState ThreadState)
{
long CondVarAddress = (long)ThreadState.X0;
int Count = (int)ThreadState.X1;
if (Ns.Os.CondVars.TryGetValue(CondVarAddress, out CondVar Cv))
{
Cv.SetSignal(Count);
}
ThreadState.X0 = (int)SvcResult.Success;
}
}
}