[llvm] [Support] On Windows, fix rpmalloc TLS destructor when running inside a DLL (PR #171465)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Dec 11 18:54:37 PST 2025
https://github.com/GkvJwa updated https://github.com/llvm/llvm-project/pull/171465
>From 6590a29489bf77fae913c8fb4bd46b69f55404bb Mon Sep 17 00:00:00 2001
From: GkvJwa <gkvjwa at gmail.com>
Date: Fri, 12 Dec 2025 10:52:03 +0800
Subject: [PATCH] [Support] On Windows, fix rpmalloc TLS destructor when
running inside a DLL
---
llvm/lib/Support/rpmalloc/rpmalloc.c | 44 ++++++++++++++++++++++++++++
1 file changed, 44 insertions(+)
diff --git a/llvm/lib/Support/rpmalloc/rpmalloc.c b/llvm/lib/Support/rpmalloc/rpmalloc.c
index b4282d9257e5f..a0f99f3e0184e 100644
--- a/llvm/lib/Support/rpmalloc/rpmalloc.c
+++ b/llvm/lib/Support/rpmalloc/rpmalloc.c
@@ -969,6 +969,50 @@ static void _rpmalloc_spin(void) {
}
#if defined(_WIN32) && (!defined(BUILD_DYNAMIC_LINK) || !BUILD_DYNAMIC_LINK)
+
+static void NTAPI RPMallocTlsOnThreadExit(PVOID module, DWORD reason,
+ PVOID reserved) {
+ switch (reason) {
+ case DLL_PROCESS_ATTACH:
+ break;
+ case DLL_PROCESS_DETACH:
+ rpmalloc_finalize();
+ break;
+ case DLL_THREAD_ATTACH:
+ break;
+ case DLL_THREAD_DETACH:
+ rpmalloc_thread_finalize(1);
+ break;
+ }
+}
+
+#ifdef _WIN64
+#pragma comment(linker, "/INCLUDE:_tls_used")
+#pragma comment(linker, "/INCLUDE:rpmalloc_tls_thread_exit_callback")
+
+// .CRT$XL* is an array of PIMAGE_TLS_CALLBACK on Windows. It is executed
+// alphabetically (A-Z) during CRT calls. As an allocator, the allocator must be
+// deinitialized last. Therefore, Y(.CRT$XLY) is used here.
+#pragma const_seg(".CRT$XLY")
+
+extern const PIMAGE_TLS_CALLBACK rpmalloc_tls_thread_exit_callback;
+const PIMAGE_TLS_CALLBACK rpmalloc_tls_thread_exit_callback =
+ RPMallocTlsOnThreadExit;
+
+// Reset const section
+#pragma const_seg()
+#else // _WIN64
+#pragma comment(linker, "/INCLUDE:__tls_used")
+#pragma comment(linker, "/INCLUDE:_rpmalloc_tls_thread_exit_callback")
+
+#pragma data_seg(".CRT$XLY")
+
+PIMAGE_TLS_CALLBACK rpmalloc_tls_thread_exit_callback = RPMallocTlsOnThreadExit;
+
+// Reset data section
+#pragma data_seg()
+#endif // _WIN64
+
static void NTAPI _rpmalloc_thread_destructor(void *value) {
#if ENABLE_OVERRIDE
// If this is called on main thread it means rpmalloc_finalize
More information about the llvm-commits
mailing list