SvcThreadSync.cs 2.5 KB

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