CondVar.cs 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. using ChocolArm64.Memory;
  2. using Ryujinx.OsHle.Handles;
  3. using System.Collections.Generic;
  4. namespace Ryujinx.OsHle
  5. {
  6. class CondVar
  7. {
  8. private Process Process;
  9. private long CondVarAddress;
  10. private long Timeout;
  11. private List<HThread> WaitingThreads;
  12. public CondVar(Process Process, long CondVarAddress, long Timeout)
  13. {
  14. this.Process = Process;
  15. this.CondVarAddress = CondVarAddress;
  16. this.Timeout = Timeout;
  17. WaitingThreads = new List<HThread>();
  18. }
  19. public void WaitForSignal(HThread Thread)
  20. {
  21. int Count = ReadCondVarValue();
  22. if (Count <= 0)
  23. {
  24. //FIXME: We shouldn't need to do that?
  25. Process.Scheduler.Yield(Thread);
  26. return;
  27. }
  28. WriteCondVarValue(Count - 1);
  29. lock (WaitingThreads)
  30. {
  31. WaitingThreads.Add(Thread);
  32. }
  33. if (Timeout != -1)
  34. {
  35. Process.Scheduler.WaitForSignal(Thread, (int)(Timeout / 1000000));
  36. }
  37. else
  38. {
  39. Process.Scheduler.WaitForSignal(Thread);
  40. }
  41. }
  42. public void SetSignal(int Count)
  43. {
  44. lock (WaitingThreads)
  45. {
  46. if (Count == -1)
  47. {
  48. Process.Scheduler.Signal(WaitingThreads.ToArray());
  49. WriteCondVarValue(WaitingThreads.Count);
  50. WaitingThreads.Clear();
  51. }
  52. else
  53. {
  54. if (WaitingThreads.Count > 0)
  55. {
  56. int HighestPriority = WaitingThreads[0].Priority;
  57. int HighestPrioIndex = 0;
  58. for (int Index = 1; Index < WaitingThreads.Count; Index++)
  59. {
  60. if (HighestPriority > WaitingThreads[Index].Priority)
  61. {
  62. HighestPriority = WaitingThreads[Index].Priority;
  63. HighestPrioIndex = Index;
  64. }
  65. }
  66. Process.Scheduler.Signal(WaitingThreads[HighestPrioIndex]);
  67. WaitingThreads.RemoveAt(HighestPrioIndex);
  68. }
  69. WriteCondVarValue(Count);
  70. }
  71. }
  72. }
  73. private int ReadCondVarValue()
  74. {
  75. return AMemoryHelper.ReadInt32Exclusive(Process.Memory, CondVarAddress);
  76. }
  77. private void WriteCondVarValue(int Value)
  78. {
  79. AMemoryHelper.WriteInt32Exclusive(Process.Memory, CondVarAddress, Value);
  80. }
  81. }
  82. }