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