| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293 |
- using ARMeilleure;
- using System.Threading;
- namespace Ryujinx.HLE.HOS.Kernel.Threading
- {
- class KCriticalSection
- {
- private Horizon _system;
- public object LockObj { get; private set; }
- private int _recursionCount;
- public KCriticalSection(Horizon system)
- {
- _system = system;
- LockObj = new object();
- }
- public void Enter()
- {
- Monitor.Enter(LockObj);
- _recursionCount++;
- }
- public void Leave()
- {
- if (_recursionCount == 0)
- {
- return;
- }
- bool doContextSwitch = false;
- if (--_recursionCount == 0)
- {
- if (_system.Scheduler.ThreadReselectionRequested)
- {
- _system.Scheduler.SelectThreads();
- }
- Monitor.Exit(LockObj);
- if (_system.Scheduler.MultiCoreScheduling)
- {
- lock (_system.Scheduler.CoreContexts)
- {
- for (int core = 0; core < KScheduler.CpuCoresCount; core++)
- {
- KCoreContext coreContext = _system.Scheduler.CoreContexts[core];
- if (coreContext.ContextSwitchNeeded)
- {
- KThread currentThread = coreContext.CurrentThread;
- if (currentThread == null)
- {
- // Nothing is running, we can perform the context switch immediately.
- coreContext.ContextSwitch();
- }
- else if (currentThread.IsCurrentHostThread())
- {
- // Thread running on the current core, context switch will block.
- doContextSwitch = true;
- }
- else
- {
- // Thread running on another core, request a interrupt.
- currentThread.Context.RequestInterrupt();
- }
- }
- }
- }
- }
- else
- {
- doContextSwitch = true;
- }
- }
- else
- {
- Monitor.Exit(LockObj);
- }
- if (doContextSwitch)
- {
- _system.Scheduler.ContextSwitch();
- }
- }
- }
- }
|