diff --git a/ChocolArm64/ATranslator.cs b/ChocolArm64/ATranslator.cs index 2d9fcb1415..960f039171 100644 --- a/ChocolArm64/ATranslator.cs +++ b/ChocolArm64/ATranslator.cs @@ -7,7 +7,10 @@ using ChocolArm64.Translation; using System; using System.Collections.Concurrent; using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; using System.Reflection.Emit; +using System.Threading; namespace ChocolArm64 { @@ -21,10 +24,14 @@ namespace ChocolArm64 public bool EnableCpuTrace { get; set; } + public AsyncTier1Translator AsyncTranslator; + public ATranslator(IReadOnlyDictionary SymbolTable = null) { CachedSubs = new ConcurrentDictionary(); + AsyncTranslator = new AsyncTier1Translator(); + if (SymbolTable != null) { this.SymbolTable = new ConcurrentDictionary(SymbolTable); @@ -85,6 +92,11 @@ namespace ChocolArm64 if (Sub.ShouldReJit()) { + if (!AsyncTranslator.InTranslation(Position)) + { + AsyncTranslator.Enqueue(Position, this, State, Memory); + } + TranslateTier1(State, Memory, Position); } @@ -142,7 +154,7 @@ namespace ChocolArm64 return Subroutine; } - private void TranslateTier1(AThreadState State, AMemory Memory, long Position) + internal void TranslateTier1(AThreadState State, AMemory Memory, long Position) { (ABlock[] Graph, ABlock Root) Cfg = ADecoder.DecodeSubroutine(State, this, Memory, Position); diff --git a/ChocolArm64/AsyncTier1Translator.cs b/ChocolArm64/AsyncTier1Translator.cs new file mode 100644 index 0000000000..dab5a9f9e2 --- /dev/null +++ b/ChocolArm64/AsyncTier1Translator.cs @@ -0,0 +1,59 @@ +using ChocolArm64.Memory; +using ChocolArm64.State; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; + +namespace ChocolArm64 +{ + public class AsyncTier1Translator + { + + private struct QueueObj + { + public long Position; + public ATranslator Translator; + public AThreadState State; + public AMemory Memory; + + public QueueObj(long Position, ATranslator Translator, AThreadState State, AMemory Memory) + { + this.Position = Position; + this.Translator = Translator; + this.State = State; + this.Memory = Memory; + } + } + + Thread Thread; + BlockingCollection Queue = new BlockingCollection(); + + public AsyncTier1Translator() + { + Thread = new Thread(Run); + Thread.Start(); + } + + public void Run() + { + while (true) + { + QueueObj QObj = Queue.Take(); + QObj.Translator.TranslateTier1(QObj.State, QObj.Memory, QObj.Position); + } + } + + public void Enqueue(long Position, ATranslator Translator, AThreadState State, AMemory Memory) + { + Queue.Add(new QueueObj(Position, Translator, State, Memory)); + } + + public bool InTranslation(long Position) + { + return Queue.Where(QObj => QObj.Position == Position).Count() > 0; + } + } +} diff --git a/Ryujinx.sln b/Ryujinx.sln index cd04dabc20..dd6858548f 100644 --- a/Ryujinx.sln +++ b/Ryujinx.sln @@ -15,11 +15,14 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Graphics", "Ryujinx EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Audio", "Ryujinx.Audio\Ryujinx.Audio.csproj", "{5C1D818E-682A-46A5-9D54-30006E26C270}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ryujinx.ShaderTools", "Ryujinx.ShaderTools\Ryujinx.ShaderTools.csproj", "{3AB294D0-2230-468F-9EB3-BDFCAEAE99A5}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.ShaderTools", "Ryujinx.ShaderTools\Ryujinx.ShaderTools.csproj", "{3AB294D0-2230-468F-9EB3-BDFCAEAE99A5}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Luea", "Ryujinx.LLE\Luea.csproj", "{8E7D36DD-9626-47E2-8EF5-8F2F66751C9C}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Luea", "Ryujinx.LLE\Luea.csproj", "{8E7D36DD-9626-47E2-8EF5-8F2F66751C9C}" EndProject Global + GlobalSection(Performance) = preSolution + HasPerformanceSessions = true + EndGlobalSection GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Release|Any CPU = Release|Any CPU @@ -64,4 +67,10 @@ Global GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {110169B3-3328-4730-8AB0-BA05BEF75C1A} EndGlobalSection + GlobalSection(Performance) = preSolution + HasPerformanceSessions = true + EndGlobalSection + GlobalSection(Performance) = preSolution + HasPerformanceSessions = true + EndGlobalSection EndGlobal