Allow more than one process, free resources on process dispose, implement SvcExitThread

This commit is contained in:
gdkchan 2018-03-12 01:04:52 -03:00
parent c497e20d36
commit ca13db7d84
4 changed files with 27 additions and 28 deletions

View file

@ -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;
} }
} }

View file

@ -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)

View file

@ -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);

View file

@ -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; }