From ca13db7d8442159f8683e8d360fd72da82974a11 Mon Sep 17 00:00:00 2001 From: gdkchan Date: Mon, 12 Mar 2018 01:04:52 -0300 Subject: [PATCH] Allow more than one process, free resources on process dispose, implement SvcExitThread --- AThread.cs | 29 ++++++++--------------------- ATranslator.cs | 8 +------- Instruction/AInstEmitException.cs | 16 ++++++++++++++++ State/AThreadState.cs | 2 ++ 4 files changed, 27 insertions(+), 28 deletions(-) diff --git a/AThread.cs b/AThread.cs index cec2681..62f9d2d 100644 --- a/AThread.cs +++ b/AThread.cs @@ -14,43 +14,30 @@ namespace ChocolArm64 private ATranslator Translator; - private ThreadPriority Priority; - private Thread Work; public event EventHandler WorkFinished; public int ThreadId => ThreadState.ThreadId; - public bool IsAlive => Work.IsAlive; + private int IsExecuting; - private bool IsExecuting; - - private object ExecuteLock; - - public AThread(ATranslator Translator, AMemory Memory, ThreadPriority Priority, long EntryPoint) + public AThread(ATranslator Translator, AMemory Memory, long EntryPoint) { this.Translator = Translator; this.Memory = Memory; - this.Priority = Priority; this.EntryPoint = EntryPoint; ThreadState = new AThreadState(); - ExecuteLock = new object(); - } - public void StopExecution() => Translator.StopExecution(); + ThreadState.Running = true; + } public bool Execute() { - lock (ExecuteLock) + if (Interlocked.Exchange(ref IsExecuting, 1) == 1) { - if (IsExecuting) - { - return false; - } - - IsExecuting = true; + return false; } Work = new Thread(delegate() @@ -62,11 +49,11 @@ namespace ChocolArm64 WorkFinished?.Invoke(this, EventArgs.Empty); }); - Work.Priority = Priority; - Work.Start(); return true; } + + public void StopExecution() => ThreadState.Running = false; } } \ No newline at end of file diff --git a/ATranslator.cs b/ATranslator.cs index 1f4a922..02c18ef 100644 --- a/ATranslator.cs +++ b/ATranslator.cs @@ -22,8 +22,6 @@ namespace ChocolArm64 public bool EnableCpuTrace { get; set; } - private bool KeepRunning; - public ATranslator(IReadOnlyDictionary SymbolTable = null) { SubBlocks = new HashSet(); @@ -38,12 +36,8 @@ namespace ChocolArm64 { this.SymbolTable = new ConcurrentDictionary(); } - - KeepRunning = true; } - internal void StopExecution() => KeepRunning = false; - internal void ExecuteSubroutine(AThread Thread, long Position) { do @@ -70,7 +64,7 @@ namespace ChocolArm64 Position = Sub.Execute(Thread.ThreadState, Thread.Memory); } - while (Position != 0 && KeepRunning); + while (Position != 0 && Thread.ThreadState.Running); } internal bool TryGetCachedSub(AOpCode OpCode, out ATranslatedSub Sub) diff --git a/Instruction/AInstEmitException.cs b/Instruction/AInstEmitException.cs index fe348ed..3964c94 100644 --- a/Instruction/AInstEmitException.cs +++ b/Instruction/AInstEmitException.cs @@ -34,6 +34,22 @@ namespace ChocolArm64.Instruction Context.EmitCall(MthdInfo); + //Check if the thread should still be running, if it isn't then we return 0 + //to force a return to the dispatcher and then exit the thread. + Context.EmitLdarg(ATranslatedSub.StateArgIdx); + + Context.EmitCallPropGet(typeof(AThreadState), nameof(AThreadState.Running)); + + AILLabel LblEnd = new AILLabel(); + + Context.Emit(OpCodes.Brtrue_S, LblEnd); + + Context.EmitLdc_I8(0); + + Context.Emit(OpCodes.Ret); + + Context.MarkLabel(LblEnd); + if (Context.CurrBlock.Next != null) { Context.EmitLoadState(Context.CurrBlock.Next); diff --git a/State/AThreadState.cs b/State/AThreadState.cs index d86f5bf..ec8621b 100644 --- a/State/AThreadState.cs +++ b/State/AThreadState.cs @@ -29,6 +29,8 @@ namespace ChocolArm64.State public int ProcessId; public int ThreadId; + public bool Running { get; set; } + public long TpidrEl0 { get; set; } public long Tpidr { get; set; }