KCriticalSection.cs 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. using System.Threading;
  2. namespace Ryujinx.HLE.HOS.Kernel.Threading
  3. {
  4. class KCriticalSection
  5. {
  6. private readonly KernelContext _context;
  7. public object LockObj { get; private set; }
  8. private int _recursionCount;
  9. public KCriticalSection(KernelContext context)
  10. {
  11. _context = context;
  12. LockObj = new object();
  13. }
  14. public void Enter()
  15. {
  16. Monitor.Enter(LockObj);
  17. _recursionCount++;
  18. }
  19. public void Leave()
  20. {
  21. if (_recursionCount == 0)
  22. {
  23. return;
  24. }
  25. bool doContextSwitch = false;
  26. if (--_recursionCount == 0)
  27. {
  28. if (_context.Scheduler.ThreadReselectionRequested)
  29. {
  30. _context.Scheduler.SelectThreads();
  31. }
  32. Monitor.Exit(LockObj);
  33. if (_context.Scheduler.MultiCoreScheduling)
  34. {
  35. lock (_context.Scheduler.CoreContexts)
  36. {
  37. for (int core = 0; core < KScheduler.CpuCoresCount; core++)
  38. {
  39. KCoreContext coreContext = _context.Scheduler.CoreContexts[core];
  40. if (coreContext.ContextSwitchNeeded)
  41. {
  42. KThread currentThread = coreContext.CurrentThread;
  43. if (currentThread == null)
  44. {
  45. // Nothing is running, we can perform the context switch immediately.
  46. coreContext.ContextSwitch();
  47. }
  48. else if (currentThread.IsCurrentHostThread())
  49. {
  50. // Thread running on the current core, context switch will block.
  51. doContextSwitch = true;
  52. }
  53. else
  54. {
  55. // Thread running on another core, request a interrupt.
  56. currentThread.Context.RequestInterrupt();
  57. }
  58. }
  59. }
  60. }
  61. }
  62. else
  63. {
  64. doContextSwitch = true;
  65. }
  66. }
  67. else
  68. {
  69. Monitor.Exit(LockObj);
  70. }
  71. if (doContextSwitch)
  72. {
  73. _context.Scheduler.ContextSwitch();
  74. }
  75. }
  76. }
  77. }