From 07b763351588c37ea542bee555661fe66287e096 Mon Sep 17 00:00:00 2001 From: Igor Chorazewicz Date: Wed, 5 Jul 2023 21:02:22 +0000 Subject: [PATCH] [umf] create/destroy memory tracker in lib ctor/dtor instead of relying on global variable init/destruction on linux and on windows (when building UMF as a shared lib). In C++ no guarantee is made for initialization order of static variables across translation units. This is problematic when an application (e.g. SYCL) wants to do some cleanup in it's library destructor. Such application might want to specify priority for it's destructor (to make sure it's executed before any other library desturctor) but it doesn't seem to work for static variables. Memory tracker is still created as a global object when building UMF as a static lib on Windows - there is no __attribute__((destructor)) equivalent that would work for static library. --- .../unified_malloc_framework/CMakeLists.txt | 1 + .../src/memory_tracker.cpp | 29 +++++++++++++++++-- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/source/common/unified_malloc_framework/CMakeLists.txt b/source/common/unified_malloc_framework/CMakeLists.txt index 30991629cd..86d19f3099 100644 --- a/source/common/unified_malloc_framework/CMakeLists.txt +++ b/source/common/unified_malloc_framework/CMakeLists.txt @@ -16,6 +16,7 @@ if(UMF_BUILD_SHARED_LIBRARY) "Do not use the shared library in production software.") add_library(unified_malloc_framework SHARED ${UMF_SOURCES}) + target_compile_definitions(unified_malloc_framework PUBLIC UMF_SHARED_LIBRARY) else() add_library(unified_malloc_framework STATIC ${UMF_SOURCES}) diff --git a/source/common/unified_malloc_framework/src/memory_tracker.cpp b/source/common/unified_malloc_framework/src/memory_tracker.cpp index 74638579cc..adbe2aa5e9 100644 --- a/source/common/unified_malloc_framework/src/memory_tracker.cpp +++ b/source/common/unified_malloc_framework/src/memory_tracker.cpp @@ -18,6 +18,10 @@ #include #include +#ifdef _WIN32 +#include +#endif + // TODO: reimplement in C and optimize... struct umf_memory_tracker_t { enum umf_result_t add(void *pool, const void *ptr, size_t size) { @@ -84,11 +88,30 @@ umfMemoryTrackerRemove(umf_memory_tracker_handle_t hTracker, const void *ptr, extern "C" { -umf_memory_tracker_handle_t umfMemoryTrackerGet(void) { - static umf_memory_tracker_t tracker; - return &tracker; +#if defined(_WIN32) && defined(UMF_SHARED_LIBRARY) +umf_memory_tracker_t *tracker = nullptr; +BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { + if (fdwReason == DLL_PROCESS_DETACH) { + delete tracker; + } else if (fdwReason == DLL_PROCESS_ATTACH) { + tracker = new umf_memory_tracker_t; + } + return TRUE; +} +#elif defined(_WIN32) +umf_memory_tracker_t trackerInstance; +umf_memory_tracker_t *tracker = &trackerInstance; +#else +umf_memory_tracker_t *tracker = nullptr; +void __attribute__((constructor)) createLibTracker() { + tracker = new umf_memory_tracker_t; } +void __attribute__((destructor)) deleteLibTracker() { delete tracker; } +#endif + +umf_memory_tracker_handle_t umfMemoryTrackerGet(void) { return tracker; } + void *umfMemoryTrackerGetPool(umf_memory_tracker_handle_t hTracker, const void *ptr) { return hTracker->find(ptr);