KConditionVariable.cs 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. using System.Collections.Generic;
  2. using System.Threading;
  3. namespace Ryujinx.HLE.HOS.Kernel
  4. {
  5. static class KConditionVariable
  6. {
  7. public static void Wait(Horizon System, LinkedList<KThread> ThreadList, object Mutex, long Timeout)
  8. {
  9. KThread CurrentThread = System.Scheduler.GetCurrentThread();
  10. System.CriticalSection.Enter();
  11. Monitor.Exit(Mutex);
  12. CurrentThread.Withholder = ThreadList;
  13. CurrentThread.Reschedule(ThreadSchedState.Paused);
  14. CurrentThread.WithholderNode = ThreadList.AddLast(CurrentThread);
  15. if (CurrentThread.ShallBeTerminated ||
  16. CurrentThread.SchedFlags == ThreadSchedState.TerminationPending)
  17. {
  18. ThreadList.Remove(CurrentThread.WithholderNode);
  19. CurrentThread.Reschedule(ThreadSchedState.Running);
  20. CurrentThread.Withholder = null;
  21. System.CriticalSection.Leave();
  22. }
  23. else
  24. {
  25. if (Timeout > 0)
  26. {
  27. System.TimeManager.ScheduleFutureInvocation(CurrentThread, Timeout);
  28. }
  29. System.CriticalSection.Leave();
  30. if (Timeout > 0)
  31. {
  32. System.TimeManager.UnscheduleFutureInvocation(CurrentThread);
  33. }
  34. }
  35. Monitor.Enter(Mutex);
  36. }
  37. public static void NotifyAll(Horizon System, LinkedList<KThread> ThreadList)
  38. {
  39. System.CriticalSection.Enter();
  40. LinkedListNode<KThread> Node = ThreadList.First;
  41. for (; Node != null; Node = ThreadList.First)
  42. {
  43. KThread Thread = Node.Value;
  44. ThreadList.Remove(Thread.WithholderNode);
  45. Thread.Withholder = null;
  46. Thread.Reschedule(ThreadSchedState.Running);
  47. }
  48. System.CriticalSection.Leave();
  49. }
  50. }
  51. }