ryujinx-mirror/Ryujinx.Core/OsHle/Svc/SvcThreadSync.cs

85 lines
2.5 KiB
C#
Raw Normal View History

2018-02-04 23:08:20 +00:00
using ChocolArm64.State;
using Ryujinx.Core.OsHle.Handles;
2018-02-04 23:08:20 +00:00
using static Ryujinx.Core.OsHle.ErrorCode;
namespace Ryujinx.Core.OsHle.Svc
2018-02-04 23:08:20 +00:00
{
partial class SvcHandler
{
2018-02-18 19:28:07 +00:00
private void SvcArbitrateLock(AThreadState ThreadState)
2018-02-04 23:08:20 +00:00
{
2018-02-18 19:28:07 +00:00
int OwnerThreadHandle = (int)ThreadState.X0;
long MutexAddress = (long)ThreadState.X1;
int RequestingThreadHandle = (int)ThreadState.X2;
2018-02-04 23:08:20 +00:00
HThread RequestingThread = Process.HandleTable.GetData<HThread>(RequestingThreadHandle);
2018-02-04 23:08:20 +00:00
Mutex M = new Mutex(Process, MutexAddress, OwnerThreadHandle);
2018-02-04 23:08:20 +00:00
M = Ns.Os.Mutexes.GetOrAdd(MutexAddress, M);
M.WaitForLock(RequestingThread, RequestingThreadHandle);
2018-02-04 23:08:20 +00:00
ThreadState.X0 = 0;
2018-02-04 23:08:20 +00:00
}
2018-02-18 19:28:07 +00:00
private void SvcArbitrateUnlock(AThreadState ThreadState)
2018-02-04 23:08:20 +00:00
{
2018-02-18 19:28:07 +00:00
long MutexAddress = (long)ThreadState.X0;
2018-02-04 23:08:20 +00:00
if (Ns.Os.Mutexes.TryGetValue(MutexAddress, out Mutex M))
{
M.Unlock();
}
ThreadState.X0 = 0;
2018-02-04 23:08:20 +00:00
}
2018-02-18 19:28:07 +00:00
private void SvcWaitProcessWideKeyAtomic(AThreadState ThreadState)
2018-02-04 23:08:20 +00:00
{
2018-02-18 19:28:07 +00:00
long MutexAddress = (long)ThreadState.X0;
long CondVarAddress = (long)ThreadState.X1;
int ThreadHandle = (int)ThreadState.X2;
long Timeout = (long)ThreadState.X3;
2018-02-04 23:08:20 +00:00
HThread Thread = Process.HandleTable.GetData<HThread>(ThreadHandle);
2018-02-04 23:08:20 +00:00
2018-02-19 19:37:13 +00:00
Mutex M = new Mutex(Process, MutexAddress, ThreadHandle);
M = Ns.Os.Mutexes.GetOrAdd(MutexAddress, M);
M.GiveUpLock(ThreadHandle);
2018-02-04 23:08:20 +00:00
CondVar Cv = new CondVar(Process, CondVarAddress, Timeout);
2018-02-04 23:08:20 +00:00
Cv = Ns.Os.CondVars.GetOrAdd(CondVarAddress, Cv);
2018-02-04 23:08:20 +00:00
if (!Cv.WaitForSignal(Thread))
{
ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.Timeout);
return;
}
2018-02-04 23:08:20 +00:00
M.WaitForLock(Thread, ThreadHandle);
2018-02-04 23:08:20 +00:00
ThreadState.X0 = 0;
2018-02-04 23:08:20 +00:00
}
2018-02-18 19:28:07 +00:00
private void SvcSignalProcessWideKey(AThreadState ThreadState)
2018-02-04 23:08:20 +00:00
{
2018-02-18 19:28:07 +00:00
long CondVarAddress = (long)ThreadState.X0;
int Count = (int)ThreadState.X1;
2018-02-04 23:08:20 +00:00
2018-02-19 19:37:13 +00:00
HThread CurrThread = Process.GetThread(ThreadState.Tpidr);
2018-02-04 23:08:20 +00:00
if (Ns.Os.CondVars.TryGetValue(CondVarAddress, out CondVar Cv))
{
2018-02-19 19:37:13 +00:00
Cv.SetSignal(CurrThread, Count);
2018-02-04 23:08:20 +00:00
}
ThreadState.X0 = 0;
2018-02-04 23:08:20 +00:00
}
}
}