KConditionVariable.cs 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. using System.Collections.Generic;
  2. using System.Threading;
  3. namespace Ryujinx.HLE.HOS.Kernel.Threading
  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. }