From b8133c19971c7a2026af803003fafedbdb70488e Mon Sep 17 00:00:00 2001 From: gdkchan Date: Tue, 18 Sep 2018 20:36:43 -0300 Subject: Thread scheduler rewrite (#393) * Started to rewrite the thread scheduler * Add a single core-like scheduling mode, enabled by default * Clear exclusive monitor on context switch * Add SetThreadActivity, misc fixes * Implement WaitForAddress and SignalToAddress svcs, misc fixes * Misc fixes (on SetActivity and Arbiter), other tweaks * Rebased * Add missing null check * Rename multicore key on config, fix UpdatePriorityInheritance * Make scheduling data MLQs private * nit: Ordering --- Ryujinx.HLE/HOS/Kernel/KRecursiveLock.cs | 93 ++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 Ryujinx.HLE/HOS/Kernel/KRecursiveLock.cs (limited to 'Ryujinx.HLE/HOS/Kernel/KRecursiveLock.cs') diff --git a/Ryujinx.HLE/HOS/Kernel/KRecursiveLock.cs b/Ryujinx.HLE/HOS/Kernel/KRecursiveLock.cs new file mode 100644 index 00000000..a21531de --- /dev/null +++ b/Ryujinx.HLE/HOS/Kernel/KRecursiveLock.cs @@ -0,0 +1,93 @@ +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) + { + AThread 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(); + } + } + } +} \ No newline at end of file -- cgit v1.2.3