SvcThreadSync.cs 2.3 KB

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