| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293 |
- using ChocolArm64;
- using System.Threading;
- namespace Ryujinx.HLE.HOS.Kernel
- {
- class KRecursiveLock
- {
- private Horizon System;
- public object LockObj { get; private set; }
- private int RecursionCount;
- public KRecursiveLock(Horizon System)
- {
- this.System = System;
- LockObj = new object();
- }
- public void Lock()
- {
- Monitor.Enter(LockObj);
- RecursionCount++;
- }
- public void Unlock()
- {
- 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)
- {
- CpuThread CurrentHleThread = CoreContext.CurrentThread?.Context;
- if (CurrentHleThread == null)
- {
- //Nothing is running, we can perform the context switch immediately.
- CoreContext.ContextSwitch();
- }
- else if (CurrentHleThread.IsCurrentThread())
- {
- //Thread running on the current core, context switch will block.
- DoContextSwitch = true;
- }
- else
- {
- //Thread running on another core, request a interrupt.
- CurrentHleThread.RequestInterrupt();
- }
- }
- }
- }
- }
- else
- {
- DoContextSwitch = true;
- }
- }
- else
- {
- Monitor.Exit(LockObj);
- }
- if (DoContextSwitch)
- {
- System.Scheduler.ContextSwitch();
- }
- }
- }
- }
|