diff --git a/AThread.cs b/AThread.cs index 4fc79d5..7b8360f 100644 --- a/AThread.cs +++ b/AThread.cs @@ -18,8 +18,6 @@ namespace ChocolArm64 public event EventHandler WorkFinished; - public int ThreadId => ThreadState.ThreadId; - private int IsExecuting; public AThread(ATranslator Translator, AMemory Memory, long EntryPoint) diff --git a/Memory/AMemory.cs b/Memory/AMemory.cs index 1b4ff6f..566e6b5 100644 --- a/Memory/AMemory.cs +++ b/Memory/AMemory.cs @@ -41,7 +41,7 @@ namespace ChocolArm64.Memory } } - private Dictionary Monitors; + private Dictionary Monitors; private ConcurrentDictionary ObservedPages; @@ -53,7 +53,7 @@ namespace ChocolArm64.Memory public AMemory(IntPtr Ram) { - Monitors = new Dictionary(); + Monitors = new Dictionary(); ObservedPages = new ConcurrentDictionary(); @@ -75,7 +75,7 @@ namespace ChocolArm64.Memory { ClearExclusive(State); - Monitors.Remove(State.ThreadId); + Monitors.Remove(State); } } @@ -93,11 +93,11 @@ namespace ChocolArm64.Memory } } - if (!Monitors.TryGetValue(ThreadState.ThreadId, out ArmMonitor ThreadMon)) + if (!Monitors.TryGetValue(ThreadState, out ArmMonitor ThreadMon)) { ThreadMon = new ArmMonitor(); - Monitors.Add(ThreadState.ThreadId, ThreadMon); + Monitors.Add(ThreadState, ThreadMon); } ThreadMon.Position = Position; @@ -113,7 +113,7 @@ namespace ChocolArm64.Memory Monitor.Enter(Monitors); - if (!Monitors.TryGetValue(ThreadState.ThreadId, out ArmMonitor ThreadMon)) + if (!Monitors.TryGetValue(ThreadState, out ArmMonitor ThreadMon)) { return false; } @@ -130,7 +130,7 @@ namespace ChocolArm64.Memory public void ClearExclusiveForStore(AThreadState ThreadState) { - if (Monitors.TryGetValue(ThreadState.ThreadId, out ArmMonitor ThreadMon)) + if (Monitors.TryGetValue(ThreadState, out ArmMonitor ThreadMon)) { ThreadMon.ExState = false; } @@ -142,7 +142,7 @@ namespace ChocolArm64.Memory { lock (Monitors) { - if (Monitors.TryGetValue(ThreadState.ThreadId, out ArmMonitor ThreadMon)) + if (Monitors.TryGetValue(ThreadState, out ArmMonitor ThreadMon)) { ThreadMon.ExState = false; } diff --git a/State/AThreadState.cs b/State/AThreadState.cs index a84e324..7b69d81 100644 --- a/State/AThreadState.cs +++ b/State/AThreadState.cs @@ -40,9 +40,6 @@ namespace ChocolArm64.State public bool Zero; public bool Negative; - public int ProcessId; - public int ThreadId; - public bool Running { get; set; } public long TpidrEl0 { get; set; } @@ -100,6 +97,11 @@ namespace ChocolArm64.State TickCounter.Start(); } + internal bool Synchronize() + { + return Running; + } + internal void OnBreak(long Position, int Imm) { Break?.Invoke(this, new AInstExceptionEventArgs(Position, Imm)); diff --git a/Translation/AILEmitterCtx.cs b/Translation/AILEmitterCtx.cs index 3fa46e9..40e33ba 100644 --- a/Translation/AILEmitterCtx.cs +++ b/Translation/AILEmitterCtx.cs @@ -110,6 +110,8 @@ namespace ChocolArm64.Translation if (OpcIndex == 0) { MarkLabel(GetLabel(CurrBlock.Position)); + + EmitSynchronization(); } CurrOp.Emitter(this); @@ -117,6 +119,25 @@ namespace ChocolArm64.Translation ILBlock.Add(new AILBarrier()); } + private void EmitSynchronization() + { + EmitLdarg(ATranslatedSub.StateArgIdx); + + EmitPrivateCall(typeof(AThreadState), nameof(AThreadState.Synchronize)); + + EmitLdc_I4(0); + + AILLabel LblContinue = new AILLabel(); + + Emit(OpCodes.Bne_Un_S, LblContinue); + + EmitLdc_I8(0); + + Emit(OpCodes.Ret); + + MarkLabel(LblContinue); + } + public bool TryOptEmitSubroutineCall() { if (CurrBlock.Next == null)