aboutsummaryrefslogtreecommitdiff
path: root/ARMeilleure/Translation/Translator.cs
diff options
context:
space:
mode:
Diffstat (limited to 'ARMeilleure/Translation/Translator.cs')
-rw-r--r--ARMeilleure/Translation/Translator.cs99
1 files changed, 34 insertions, 65 deletions
diff --git a/ARMeilleure/Translation/Translator.cs b/ARMeilleure/Translation/Translator.cs
index 389adf29..ee8e3e8b 100644
--- a/ARMeilleure/Translation/Translator.cs
+++ b/ARMeilleure/Translation/Translator.cs
@@ -44,15 +44,11 @@ namespace ARMeilleure.Translation
private readonly IJitMemoryAllocator _allocator;
private readonly ConcurrentQueue<KeyValuePair<ulong, TranslatedFunction>> _oldFuncs;
- private readonly ConcurrentDictionary<ulong, object> _backgroundSet;
- private readonly ConcurrentStack<RejitRequest> _backgroundStack;
- private readonly AutoResetEvent _backgroundTranslatorEvent;
- private readonly ReaderWriterLock _backgroundTranslatorLock;
-
internal TranslatorCache<TranslatedFunction> Functions { get; }
internal AddressTable<ulong> FunctionTable { get; }
internal EntryTable<uint> CountTable { get; }
internal TranslatorStubs Stubs { get; }
+ internal TranslatorQueue Queue { get; }
internal IMemoryManager Memory { get; }
private volatile int _threadCount;
@@ -67,10 +63,7 @@ namespace ARMeilleure.Translation
_oldFuncs = new ConcurrentQueue<KeyValuePair<ulong, TranslatedFunction>>();
- _backgroundSet = new ConcurrentDictionary<ulong, object>();
- _backgroundStack = new ConcurrentStack<RejitRequest>();
- _backgroundTranslatorEvent = new AutoResetEvent(false);
- _backgroundTranslatorLock = new ReaderWriterLock();
+ Queue = new TranslatorQueue();
JitCache.Initialize(allocator);
@@ -87,43 +80,6 @@ namespace ARMeilleure.Translation
}
}
- private void TranslateStackedSubs()
- {
- while (_threadCount != 0)
- {
- _backgroundTranslatorLock.AcquireReaderLock(Timeout.Infinite);
-
- if (_backgroundStack.TryPop(out RejitRequest request) &&
- _backgroundSet.TryRemove(request.Address, out _))
- {
- TranslatedFunction func = Translate(request.Address, request.Mode, highCq: true);
-
- Functions.AddOrUpdate(request.Address, func.GuestSize, func, (key, oldFunc) =>
- {
- EnqueueForDeletion(key, oldFunc);
- return func;
- });
-
- if (PtcProfiler.Enabled)
- {
- PtcProfiler.UpdateEntry(request.Address, request.Mode, highCq: true);
- }
-
- RegisterFunction(request.Address, func);
-
- _backgroundTranslatorLock.ReleaseReaderLock();
- }
- else
- {
- _backgroundTranslatorLock.ReleaseReaderLock();
- _backgroundTranslatorEvent.WaitOne();
- }
- }
-
- // Wake up any other background translator threads, to encourage them to exit.
- _backgroundTranslatorEvent.Set();
- }
-
public void Execute(State.ExecutionContext context, ulong address)
{
if (Interlocked.Increment(ref _threadCount) == 1)
@@ -155,7 +111,7 @@ namespace ARMeilleure.Translation
{
bool last = i != 0 && i == unboundedThreadCount - 1;
- Thread backgroundTranslatorThread = new Thread(TranslateStackedSubs)
+ Thread backgroundTranslatorThread = new Thread(BackgroundTranslate)
{
Name = "CPU.BackgroundTranslatorThread." + i,
Priority = last ? ThreadPriority.Lowest : ThreadPriority.Normal
@@ -186,10 +142,9 @@ namespace ARMeilleure.Translation
if (Interlocked.Decrement(ref _threadCount) == 0)
{
- _backgroundTranslatorEvent.Set();
-
ClearJitCache();
+ Queue.Dispose();
Stubs.Dispose();
FunctionTable.Dispose();
CountTable.Dispose();
@@ -317,6 +272,27 @@ namespace ARMeilleure.Translation
return new TranslatedFunction(func, counter, funcSize, highCq);
}
+ private void BackgroundTranslate()
+ {
+ while (_threadCount != 0 && Queue.TryDequeue(out RejitRequest request))
+ {
+ TranslatedFunction func = Translate(request.Address, request.Mode, highCq: true);
+
+ Functions.AddOrUpdate(request.Address, func.GuestSize, func, (key, oldFunc) =>
+ {
+ EnqueueForDeletion(key, oldFunc);
+ return func;
+ });
+
+ if (PtcProfiler.Enabled)
+ {
+ PtcProfiler.UpdateEntry(request.Address, request.Mode, highCq: true);
+ }
+
+ RegisterFunction(request.Address, func);
+ }
+ }
+
private struct Range
{
public ulong Start { get; }
@@ -504,11 +480,7 @@ namespace ARMeilleure.Translation
internal void EnqueueForRejit(ulong guestAddress, ExecutionMode mode)
{
- if (_backgroundSet.TryAdd(guestAddress, null))
- {
- _backgroundStack.Push(new RejitRequest(guestAddress, mode));
- _backgroundTranslatorEvent.Set();
- }
+ Queue.Enqueue(guestAddress, mode);
}
private void EnqueueForDeletion(ulong guestAddress, TranslatedFunction func)
@@ -542,26 +514,23 @@ namespace ARMeilleure.Translation
private void ClearRejitQueue(bool allowRequeue)
{
- _backgroundTranslatorLock.AcquireWriterLock(Timeout.Infinite);
+ if (!allowRequeue)
+ {
+ Queue.Clear();
+
+ return;
+ }
- if (allowRequeue)
+ lock (Queue.Sync)
{
- while (_backgroundStack.TryPop(out var request))
+ while (Queue.Count > 0 && Queue.TryDequeue(out RejitRequest request))
{
if (Functions.TryGetValue(request.Address, out var func) && func.CallCounter != null)
{
Volatile.Write(ref func.CallCounter.Value, 0);
}
-
- _backgroundSet.TryRemove(request.Address, out _);
}
}
- else
- {
- _backgroundStack.Clear();
- }
-
- _backgroundTranslatorLock.ReleaseWriterLock();
}
}
}