Allow more than one process, free resources on process dispose, implement SvcExitThread
This commit is contained in:
parent
c497e20d36
commit
ca13db7d84
4 changed files with 27 additions and 28 deletions
27
AThread.cs
27
AThread.cs
|
@ -14,45 +14,32 @@ namespace ChocolArm64
|
||||||
|
|
||||||
private ATranslator Translator;
|
private ATranslator Translator;
|
||||||
|
|
||||||
private ThreadPriority Priority;
|
|
||||||
|
|
||||||
private Thread Work;
|
private Thread Work;
|
||||||
|
|
||||||
public event EventHandler WorkFinished;
|
public event EventHandler WorkFinished;
|
||||||
|
|
||||||
public int ThreadId => ThreadState.ThreadId;
|
public int ThreadId => ThreadState.ThreadId;
|
||||||
|
|
||||||
public bool IsAlive => Work.IsAlive;
|
private int IsExecuting;
|
||||||
|
|
||||||
private bool IsExecuting;
|
public AThread(ATranslator Translator, AMemory Memory, long EntryPoint)
|
||||||
|
|
||||||
private object ExecuteLock;
|
|
||||||
|
|
||||||
public AThread(ATranslator Translator, AMemory Memory, ThreadPriority Priority, long EntryPoint)
|
|
||||||
{
|
{
|
||||||
this.Translator = Translator;
|
this.Translator = Translator;
|
||||||
this.Memory = Memory;
|
this.Memory = Memory;
|
||||||
this.Priority = Priority;
|
|
||||||
this.EntryPoint = EntryPoint;
|
this.EntryPoint = EntryPoint;
|
||||||
|
|
||||||
ThreadState = new AThreadState();
|
ThreadState = new AThreadState();
|
||||||
ExecuteLock = new object();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void StopExecution() => Translator.StopExecution();
|
ThreadState.Running = true;
|
||||||
|
}
|
||||||
|
|
||||||
public bool Execute()
|
public bool Execute()
|
||||||
{
|
{
|
||||||
lock (ExecuteLock)
|
if (Interlocked.Exchange(ref IsExecuting, 1) == 1)
|
||||||
{
|
|
||||||
if (IsExecuting)
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
IsExecuting = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Work = new Thread(delegate()
|
Work = new Thread(delegate()
|
||||||
{
|
{
|
||||||
Translator.ExecuteSubroutine(this, EntryPoint);
|
Translator.ExecuteSubroutine(this, EntryPoint);
|
||||||
|
@ -62,11 +49,11 @@ namespace ChocolArm64
|
||||||
WorkFinished?.Invoke(this, EventArgs.Empty);
|
WorkFinished?.Invoke(this, EventArgs.Empty);
|
||||||
});
|
});
|
||||||
|
|
||||||
Work.Priority = Priority;
|
|
||||||
|
|
||||||
Work.Start();
|
Work.Start();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void StopExecution() => ThreadState.Running = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -22,8 +22,6 @@ namespace ChocolArm64
|
||||||
|
|
||||||
public bool EnableCpuTrace { get; set; }
|
public bool EnableCpuTrace { get; set; }
|
||||||
|
|
||||||
private bool KeepRunning;
|
|
||||||
|
|
||||||
public ATranslator(IReadOnlyDictionary<long, string> SymbolTable = null)
|
public ATranslator(IReadOnlyDictionary<long, string> SymbolTable = null)
|
||||||
{
|
{
|
||||||
SubBlocks = new HashSet<long>();
|
SubBlocks = new HashSet<long>();
|
||||||
|
@ -38,12 +36,8 @@ namespace ChocolArm64
|
||||||
{
|
{
|
||||||
this.SymbolTable = new ConcurrentDictionary<long, string>();
|
this.SymbolTable = new ConcurrentDictionary<long, string>();
|
||||||
}
|
}
|
||||||
|
|
||||||
KeepRunning = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void StopExecution() => KeepRunning = false;
|
|
||||||
|
|
||||||
internal void ExecuteSubroutine(AThread Thread, long Position)
|
internal void ExecuteSubroutine(AThread Thread, long Position)
|
||||||
{
|
{
|
||||||
do
|
do
|
||||||
|
@ -70,7 +64,7 @@ namespace ChocolArm64
|
||||||
|
|
||||||
Position = Sub.Execute(Thread.ThreadState, Thread.Memory);
|
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)
|
internal bool TryGetCachedSub(AOpCode OpCode, out ATranslatedSub Sub)
|
||||||
|
|
|
@ -34,6 +34,22 @@ namespace ChocolArm64.Instruction
|
||||||
|
|
||||||
Context.EmitCall(MthdInfo);
|
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)
|
if (Context.CurrBlock.Next != null)
|
||||||
{
|
{
|
||||||
Context.EmitLoadState(Context.CurrBlock.Next);
|
Context.EmitLoadState(Context.CurrBlock.Next);
|
||||||
|
|
|
@ -29,6 +29,8 @@ namespace ChocolArm64.State
|
||||||
public int ProcessId;
|
public int ProcessId;
|
||||||
public int ThreadId;
|
public int ThreadId;
|
||||||
|
|
||||||
|
public bool Running { get; set; }
|
||||||
|
|
||||||
public long TpidrEl0 { get; set; }
|
public long TpidrEl0 { get; set; }
|
||||||
public long Tpidr { get; set; }
|
public long Tpidr { get; set; }
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue