From ba71141bdcb4742ee8707b9c354365d9ea142ca9 Mon Sep 17 00:00:00 2001 From: gdkchan Date: Wed, 10 May 2023 21:46:38 -0300 Subject: [PATCH] Ensure background translation threads exited before disposing JIT (#4874) --- src/ARMeilleure/Translation/Translator.cs | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/ARMeilleure/Translation/Translator.cs b/src/ARMeilleure/Translation/Translator.cs index f349c5eb..234be2ac 100644 --- a/src/ARMeilleure/Translation/Translator.cs +++ b/src/ARMeilleure/Translation/Translator.cs @@ -54,6 +54,7 @@ namespace ARMeilleure.Translation internal TranslatorQueue Queue { get; } internal IMemoryManager Memory { get; } + private Thread[] _backgroundTranslationThreads; private volatile int _threadCount; // FIXME: Remove this once the init logic of the emulator will be redone. @@ -127,18 +128,22 @@ namespace ARMeilleure.Translation int unboundedThreadCount = Math.Max(1, (Environment.ProcessorCount - 6) / 3); int threadCount = Math.Min(4, unboundedThreadCount); + Thread[] backgroundTranslationThreads = new Thread[threadCount]; + for (int i = 0; i < threadCount; i++) { bool last = i != 0 && i == unboundedThreadCount - 1; - Thread backgroundTranslatorThread = new Thread(BackgroundTranslate) + backgroundTranslationThreads[i] = new Thread(BackgroundTranslate) { Name = "CPU.BackgroundTranslatorThread." + i, Priority = last ? ThreadPriority.Lowest : ThreadPriority.Normal }; - backgroundTranslatorThread.Start(); + backgroundTranslationThreads[i].Start(); } + + Interlocked.Exchange(ref _backgroundTranslationThreads, backgroundTranslationThreads); } Statistics.InitializeTimer(); @@ -162,9 +167,20 @@ namespace ARMeilleure.Translation if (Interlocked.Decrement(ref _threadCount) == 0) { + Queue.Dispose(); + + Thread[] backgroundTranslationThreads = Interlocked.Exchange(ref _backgroundTranslationThreads, null); + + if (backgroundTranslationThreads != null) + { + foreach (Thread thread in backgroundTranslationThreads) + { + thread.Join(); + } + } + ClearJitCache(); - Queue.Dispose(); Stubs.Dispose(); FunctionTable.Dispose(); CountTable.Dispose();