Made initial implementation of the thread scheduler, refactor Svc to avoid passing many arguments

This commit is contained in:
gdkchan 2018-02-13 23:43:08 -03:00
parent 598d1fd3ae
commit f68696dc4a
19 changed files with 740 additions and 252 deletions

View file

@ -10,8 +10,13 @@ namespace ChocolArm64
public ARegisters Registers { get; private set; }
public AMemory Memory { get; private set; }
public long EntryPoint { get; private set; }
private ATranslator Translator;
private Thread Work;
private ThreadPriority Priority;
private Thread Work;
public event EventHandler WorkFinished;
@ -19,25 +24,35 @@ namespace ChocolArm64
public bool IsAlive => Work.IsAlive;
public long EntryPoint { get; private set; }
public int Priority { get; private set; }
private bool IsExecuting;
public AThread(AMemory Memory, long EntryPoint = 0, int Priority = 0)
private object ExecuteLock;
public AThread(AMemory Memory, ThreadPriority Priority, long EntryPoint)
{
this.Memory = Memory;
this.EntryPoint = EntryPoint;
this.Priority = Priority;
this.EntryPoint = EntryPoint;
Registers = new ARegisters();
Translator = new ATranslator(this);
Registers = new ARegisters();
Translator = new ATranslator(this);
ExecuteLock = new object();
}
public void StopExecution() => Translator.StopExecution();
public void Execute() => Execute(EntryPoint);
public void Execute(long EntryPoint)
public bool Execute()
{
lock (ExecuteLock)
{
if (IsExecuting)
{
return false;
}
IsExecuting = true;
}
Work = new Thread(delegate()
{
Translator.ExecuteSubroutine(EntryPoint);
@ -47,28 +62,11 @@ namespace ChocolArm64
WorkFinished?.Invoke(this, EventArgs.Empty);
});
if (Priority < 12)
{
Work.Priority = ThreadPriority.Highest;
}
else if (Priority < 24)
{
Work.Priority = ThreadPriority.AboveNormal;
}
else if (Priority < 36)
{
Work.Priority = ThreadPriority.Normal;
}
else if (Priority < 48)
{
Work.Priority = ThreadPriority.BelowNormal;
}
else
{
Work.Priority = ThreadPriority.Lowest;
}
Work.Priority = Priority;
Work.Start();
return true;
}
}
}

View file

@ -197,38 +197,38 @@ namespace ChocolArm64.Instruction
return ValueF;
}
public static float Int32ToDouble(int Value, int FBits)
public static double Int32ToDouble(int Value, int FBits)
{
float ValueF = Value;
double ValueF = Value;
if (FBits != 0) ValueF *= 1 / MathF.Pow(2, FBits);
if (FBits != 0) ValueF *= 1 / Math.Pow(2, FBits);
return ValueF;
}
public static float Int64ToDouble(long Value, int FBits)
public static double Int64ToDouble(long Value, int FBits)
{
float ValueF = Value;
double ValueF = Value;
if (FBits != 0) ValueF *= 1 / MathF.Pow(2, FBits);
if (FBits != 0) ValueF *= 1 / Math.Pow(2, FBits);
return ValueF;
}
public static float UInt32ToDouble(uint Value, int FBits)
public static double UInt32ToDouble(uint Value, int FBits)
{
float ValueF = Value;
double ValueF = Value;
if (FBits != 0) ValueF *= 1 / MathF.Pow(2, FBits);
if (FBits != 0) ValueF *= 1 / Math.Pow(2, FBits);
return ValueF;
}
public static float UInt64ToDouble(ulong Value, int FBits)
public static double UInt64ToDouble(ulong Value, int FBits)
{
float ValueF = Value;
double ValueF = Value;
if (FBits != 0) ValueF *= 1 / MathF.Pow(2, FBits);
if (FBits != 0) ValueF *= 1 / Math.Pow(2, FBits);
return ValueF;
}

View file

@ -66,10 +66,10 @@ namespace ChocolArm64.Memory
public void SetExclusive(ARegisters Registers, long Position)
{
Position &= ~ErgMask;
lock (Monitors)
{
Position &= ~ErgMask;
if (Monitors.TryGetValue(Registers.ThreadId, out ExMonitor Monitor))
{
ExAddrs.Remove(Monitor.Position);
@ -88,10 +88,10 @@ namespace ChocolArm64.Memory
public bool TestExclusive(ARegisters Registers, long Position)
{
Position &= ~ErgMask;
lock (Monitors)
{
Position &= ~ErgMask;
if (!Monitors.TryGetValue(Registers.ThreadId, out ExMonitor Monitor))
{
return false;
@ -113,6 +113,26 @@ namespace ChocolArm64.Memory
}
}
public bool AcquireAddress(long Position)
{
Position &= ~ErgMask;
lock (Monitors)
{
return ExAddrs.Add(Position);
}
}
public void ReleaseAddress(long Position)
{
Position &= ~ErgMask;
lock (Monitors)
{
ExAddrs.Remove(Position);
}
}
public sbyte ReadSByte(long Position) => (sbyte)ReadByte (Position);
public short ReadInt16(long Position) => (short)ReadUInt16(Position);
public int ReadInt32(long Position) => (int)ReadUInt32(Position);

View file

@ -1,5 +1,6 @@
using System.IO;
using System.Text;
using System.Threading;
namespace ChocolArm64.Memory
{
@ -20,6 +21,32 @@ namespace ChocolArm64.Memory
}
}
public static int ReadInt32Exclusive(AMemory Memory, long Position)
{
while (!Memory.AcquireAddress(Position))
{
Thread.Yield();
}
int Value = Memory.ReadInt32(Position);
Memory.ReleaseAddress(Position);
return Value;
}
public static void WriteInt32Exclusive(AMemory Memory, long Position, int Value)
{
while (!Memory.AcquireAddress(Position))
{
Thread.Yield();
}
Memory.WriteInt32(Position, Value);
Memory.ReleaseAddress(Position);
}
public static byte[] ReadBytes(AMemory Memory, long Position, int Size)
{
byte[] Data = new byte[Size];