diff options
author | gdkchan <gab.dark.100@gmail.com> | 2018-12-18 03:33:36 -0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-12-18 03:33:36 -0200 |
commit | 0039bb639493b2d1e2764cae380311ba8e87704b (patch) | |
tree | 63a912a95c8261775c2acb8a5b9ca0f10ad4ae33 /Ryujinx.HLE/HOS/Kernel/Threading/KCriticalSection.cs | |
parent | 2534a7f10c627810e6e0272b4cc9758e90f733c1 (diff) |
Refactor SVC handler (#540)
* Refactor SVC handler
* Get rid of KernelErr
* Split kernel code files into multiple folders
Diffstat (limited to 'Ryujinx.HLE/HOS/Kernel/Threading/KCriticalSection.cs')
-rw-r--r-- | Ryujinx.HLE/HOS/Kernel/Threading/KCriticalSection.cs | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/Ryujinx.HLE/HOS/Kernel/Threading/KCriticalSection.cs b/Ryujinx.HLE/HOS/Kernel/Threading/KCriticalSection.cs new file mode 100644 index 00000000..841d0d69 --- /dev/null +++ b/Ryujinx.HLE/HOS/Kernel/Threading/KCriticalSection.cs @@ -0,0 +1,93 @@ +using ChocolArm64; +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) + { + 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(); + } + } + } +}
\ No newline at end of file |