KConditionVariable.cs 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  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(KernelContext context, LinkedList<KThread> threadList, object mutex, long timeout)
  8. {
  9. KThread currentThread = KernelStatic.GetCurrentThread();
  10. context.CriticalSection.Enter();
  11. Monitor.Exit(mutex);
  12. currentThread.Withholder = threadList;
  13. currentThread.Reschedule(ThreadSchedState.Paused);
  14. currentThread.WithholderNode = threadList.AddLast(currentThread);
  15. if (currentThread.TerminationRequested)
  16. {
  17. threadList.Remove(currentThread.WithholderNode);
  18. currentThread.Reschedule(ThreadSchedState.Running);
  19. currentThread.Withholder = null;
  20. context.CriticalSection.Leave();
  21. }
  22. else
  23. {
  24. if (timeout > 0)
  25. {
  26. context.TimeManager.ScheduleFutureInvocation(currentThread, timeout);
  27. }
  28. context.CriticalSection.Leave();
  29. if (timeout > 0)
  30. {
  31. context.TimeManager.UnscheduleFutureInvocation(currentThread);
  32. }
  33. }
  34. Monitor.Enter(mutex);
  35. }
  36. public static void NotifyAll(KernelContext context, LinkedList<KThread> threadList)
  37. {
  38. context.CriticalSection.Enter();
  39. LinkedListNode<KThread> node = threadList.First;
  40. for (; node != null; node = threadList.First)
  41. {
  42. KThread thread = node.Value;
  43. threadList.Remove(thread.WithholderNode);
  44. thread.Withholder = null;
  45. thread.Reschedule(ThreadSchedState.Running);
  46. }
  47. context.CriticalSection.Leave();
  48. }
  49. }
  50. }