From 429ff94dc55b4189bebcf1b0e6b5e8034d45095d Mon Sep 17 00:00:00 2001 From: Billy Laws Date: Mon, 6 Jan 2025 18:56:58 +0000 Subject: [PATCH 1/2] Windows: Only deinit the thread CRT when destroying the current thread The thread termination callback can be called for other threads in the process, not just the current one, in which case we cannot call DeinitCRT. Deinitializing the CRT of another thread would be awkward so just skip that and accept the small leak for now. --- Source/Windows/ARM64EC/Module.cpp | 18 ++++++++++-------- Source/Windows/WOW64/Module.cpp | 16 +++++++++------- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/Source/Windows/ARM64EC/Module.cpp b/Source/Windows/ARM64EC/Module.cpp index a24963412a..523b5bcae1 100644 --- a/Source/Windows/ARM64EC/Module.cpp +++ b/Source/Windows/ARM64EC/Module.cpp @@ -816,20 +816,22 @@ NTSTATUS ThreadTerm(HANDLE Thread, LONG ExitCode) { auto* OldThreadState = CPUArea.ThreadState(); CPUArea.ThreadState() = nullptr; - { - THREAD_BASIC_INFORMATION Info; - if (NTSTATUS Err = NtQueryInformationThread(Thread, ThreadBasicInformation, &Info, sizeof(Info), nullptr); Err) { - return Err; - } + THREAD_BASIC_INFORMATION Info; + if (NTSTATUS Err = NtQueryInformationThread(Thread, ThreadBasicInformation, &Info, sizeof(Info), nullptr); Err) { + return Err; + } - const auto ThreadTID = reinterpret_cast(Info.ClientId.UniqueThread); + const auto ThreadTID = reinterpret_cast(Info.ClientId.UniqueThread); + { std::scoped_lock Lock(ThreadCreationMutex); Threads.erase(ThreadTID); } CTX->DestroyThread(OldThreadState); - ::VirtualFree(reinterpret_cast(GetCPUArea().EmulatorStackLimit()), 0, MEM_RELEASE); - FEX::Windows::DeinitCRTThread(); + ::VirtualFree(reinterpret_cast(CPUArea.EmulatorStackLimit()), 0, MEM_RELEASE); + if (ThreadTID == GetCurrentThreadId()) { + FEX::Windows::DeinitCRTThread(); + } return STATUS_SUCCESS; } diff --git a/Source/Windows/WOW64/Module.cpp b/Source/Windows/WOW64/Module.cpp index ebf5f01b70..df56d2bb09 100644 --- a/Source/Windows/WOW64/Module.cpp +++ b/Source/Windows/WOW64/Module.cpp @@ -517,19 +517,21 @@ void BTCpuThreadTerm(HANDLE Thread, LONG ExitCode) { return; } - { - THREAD_BASIC_INFORMATION Info; - if (NTSTATUS Err = NtQueryInformationThread(Thread, ThreadBasicInformation, &Info, sizeof(Info), nullptr); Err) { - return; - } + THREAD_BASIC_INFORMATION Info; + if (NTSTATUS Err = NtQueryInformationThread(Thread, ThreadBasicInformation, &Info, sizeof(Info), nullptr); Err) { + return; + } - const auto ThreadTID = reinterpret_cast(Info.ClientId.UniqueThread); + const auto ThreadTID = reinterpret_cast(Info.ClientId.UniqueThread); + { std::scoped_lock Lock(ThreadCreationMutex); Threads.erase(ThreadTID); } CTX->DestroyThread(TLS.ThreadState()); - FEX::Windows::DeinitCRTThread(); + if (ThreadTID == GetCurrentThreadId()) { + FEX::Windows::DeinitCRTThread(); + } } void* BTCpuGetBopCode() { From c00cef6dc14e9de9df304bc5ece154070f0ad06f Mon Sep 17 00:00:00 2001 From: Billy Laws Date: Mon, 6 Jan 2025 18:59:39 +0000 Subject: [PATCH 2/2] WOW64: Fix warning --- Source/Windows/WOW64/Module.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/Source/Windows/WOW64/Module.cpp b/Source/Windows/WOW64/Module.cpp index df56d2bb09..9e6cec16da 100644 --- a/Source/Windows/WOW64/Module.cpp +++ b/Source/Windows/WOW64/Module.cpp @@ -137,7 +137,6 @@ bool IsDispatcherAddress(uint64_t Address) { } bool IsAddressInJit(uint64_t Address) { - const auto& Config = SignalDelegator->GetConfig(); if (IsDispatcherAddress(Address)) { return true; }