SvcThreadSync.cs 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. using ChocolArm64.State;
  2. using Ryujinx.Core.OsHle.Handles;
  3. namespace Ryujinx.Core.OsHle.Svc
  4. {
  5. partial class SvcHandler
  6. {
  7. private void SvcArbitrateLock(AThreadState ThreadState)
  8. {
  9. int OwnerThreadHandle = (int)ThreadState.X0;
  10. long MutexAddress = (long)ThreadState.X1;
  11. int RequestingThreadHandle = (int)ThreadState.X2;
  12. HThread RequestingThread = Ns.Os.Handles.GetData<HThread>(RequestingThreadHandle);
  13. Mutex M = new Mutex(Process, MutexAddress, OwnerThreadHandle);
  14. M = Ns.Os.Mutexes.GetOrAdd(MutexAddress, M);
  15. M.WaitForLock(RequestingThread, RequestingThreadHandle);
  16. ThreadState.X0 = (int)SvcResult.Success;
  17. }
  18. private void SvcArbitrateUnlock(AThreadState ThreadState)
  19. {
  20. long MutexAddress = (long)ThreadState.X0;
  21. if (Ns.Os.Mutexes.TryGetValue(MutexAddress, out Mutex M))
  22. {
  23. M.Unlock();
  24. }
  25. ThreadState.X0 = (int)SvcResult.Success;
  26. }
  27. private void SvcWaitProcessWideKeyAtomic(AThreadState ThreadState)
  28. {
  29. long MutexAddress = (long)ThreadState.X0;
  30. long CondVarAddress = (long)ThreadState.X1;
  31. int ThreadHandle = (int)ThreadState.X2;
  32. long Timeout = (long)ThreadState.X3;
  33. HThread Thread = Ns.Os.Handles.GetData<HThread>(ThreadHandle);
  34. Mutex M = new Mutex(Process, MutexAddress, ThreadHandle);
  35. M = Ns.Os.Mutexes.GetOrAdd(MutexAddress, M);
  36. M.GiveUpLock(ThreadHandle);
  37. CondVar Cv = new CondVar(Process, CondVarAddress, Timeout);
  38. Cv = Ns.Os.CondVars.GetOrAdd(CondVarAddress, Cv);
  39. Cv.WaitForSignal(Thread);
  40. M.WaitForLock(Thread, ThreadHandle);
  41. ThreadState.X0 = (int)SvcResult.Success;
  42. }
  43. private void SvcSignalProcessWideKey(AThreadState ThreadState)
  44. {
  45. long CondVarAddress = (long)ThreadState.X0;
  46. int Count = (int)ThreadState.X1;
  47. HThread CurrThread = Process.GetThread(ThreadState.Tpidr);
  48. if (Ns.Os.CondVars.TryGetValue(CondVarAddress, out CondVar Cv))
  49. {
  50. Cv.SetSignal(CurrThread, Count);
  51. }
  52. ThreadState.X0 = (int)SvcResult.Success;
  53. }
  54. }
  55. }