| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120 |
- using ChocolArm64.State;
- using Ryujinx.Core.OsHle.Handles;
- using static Ryujinx.Core.OsHle.ErrorCode;
- namespace Ryujinx.Core.OsHle.Kernel
- {
- partial class SvcHandler
- {
- private void SvcArbitrateLock(AThreadState ThreadState)
- {
- int OwnerThreadHandle = (int)ThreadState.X0;
- long MutexAddress = (long)ThreadState.X1;
- int RequestingThreadHandle = (int)ThreadState.X2;
- KThread OwnerThread = Process.HandleTable.GetData<KThread>(OwnerThreadHandle);
- if (OwnerThread == null)
- {
- Logging.Warn(LogClass.KernelSvc, $"Invalid owner thread handle 0x{OwnerThreadHandle:x8}!");
- ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidHandle);
- return;
- }
- KThread RequestingThread = Process.HandleTable.GetData<KThread>(RequestingThreadHandle);
- if (RequestingThread == null)
- {
- Logging.Warn(LogClass.KernelSvc, $"Invalid requesting thread handle 0x{RequestingThreadHandle:x8}!");
- ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidHandle);
- return;
- }
- MutualExclusion Mutex = GetMutex(MutexAddress);
- Mutex.WaitForLock(RequestingThread, OwnerThreadHandle);
- ThreadState.X0 = 0;
- }
- private void SvcArbitrateUnlock(AThreadState ThreadState)
- {
- long MutexAddress = (long)ThreadState.X0;
- GetMutex(MutexAddress).Unlock();
- Process.Scheduler.Yield(Process.GetThread(ThreadState.Tpidr));
- ThreadState.X0 = 0;
- }
- 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;
- KThread Thread = Process.HandleTable.GetData<KThread>(ThreadHandle);
- if (Thread == null)
- {
- Logging.Warn(LogClass.KernelSvc, $"Invalid thread handle 0x{ThreadHandle:x8}!");
- ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidHandle);
- }
- MutualExclusion Mutex = GetMutex(MutexAddress);
- Mutex.Unlock();
- if (!GetCondVar(CondVarAddress).WaitForSignal(Thread, Timeout))
- {
- ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.Timeout);
- return;
- }
- Mutex.WaitForLock(Thread);
- ThreadState.X0 = 0;
- }
- private void SvcSignalProcessWideKey(AThreadState ThreadState)
- {
- long CondVarAddress = (long)ThreadState.X0;
- int Count = (int)ThreadState.X1;
- KThread CurrThread = Process.GetThread(ThreadState.Tpidr);
- GetCondVar(CondVarAddress).SetSignal(CurrThread, Count);
- ThreadState.X0 = 0;
- }
- private MutualExclusion GetMutex(long MutexAddress)
- {
- MutualExclusion MutexFactory(long Key)
- {
- return new MutualExclusion(Process, MutexAddress);
- }
- return Mutexes.GetOrAdd(MutexAddress, MutexFactory);
- }
- private ConditionVariable GetCondVar(long CondVarAddress)
- {
- ConditionVariable CondVarFactory(long Key)
- {
- return new ConditionVariable(Process, CondVarAddress);
- }
- return CondVars.GetOrAdd(CondVarAddress, CondVarFactory);
- }
- }
- }
|