1 /* 2 Copyright (c) 2005-2023 Intel Corporation 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 #include "TypeDefinitions.h" // Customize.h and proxy.h get included 18 #include "tbbmalloc_internal_api.h" 19 20 #include "../tbb/assert_impl.h" // Out-of-line TBB assertion handling routines are instantiated here. 21 #include "oneapi/tbb/version.h" 22 #include "oneapi/tbb/scalable_allocator.h" 23 24 #undef UNICODE 25 26 #if USE_PTHREAD 27 #include <dlfcn.h> // dlopen 28 #elif USE_WINTHREAD 29 #include <windows.h> 30 #endif 31 32 namespace rml { 33 namespace internal { 34 35 #if TBB_USE_DEBUG 36 #define DEBUG_SUFFIX "_debug" 37 #else 38 #define DEBUG_SUFFIX 39 #endif /* TBB_USE_DEBUG */ 40 41 // MALLOCLIB_NAME is the name of the oneTBB memory allocator library. 42 #if _WIN32||_WIN64 43 #define MALLOCLIB_NAME "tbbmalloc" DEBUG_SUFFIX ".dll" 44 #elif __APPLE__ 45 #define MALLOCLIB_NAME "libtbbmalloc" DEBUG_SUFFIX ".2.dylib" 46 #elif __FreeBSD__ || __NetBSD__ || __OpenBSD__ || __sun || _AIX || __ANDROID__ 47 #define MALLOCLIB_NAME "libtbbmalloc" DEBUG_SUFFIX ".so" 48 #elif __unix__ 49 #define MALLOCLIB_NAME "libtbbmalloc" DEBUG_SUFFIX __TBB_STRING(.so.2) 50 #else 51 #error Unknown OS 52 #endif 53 54 void init_tbbmalloc() { 55 #if __TBB_USE_ITT_NOTIFY 56 MallocInitializeITT(); 57 #endif 58 59 /* Preventing TBB allocator library from unloading to prevent 60 resource leak, as memory is not released on the library unload. 61 */ 62 #if USE_WINTHREAD && !__TBB_SOURCE_DIRECTLY_INCLUDED && !__TBB_WIN8UI_SUPPORT 63 // Prevent Windows from displaying message boxes if it fails to load library 64 UINT prev_mode = SetErrorMode (SEM_FAILCRITICALERRORS); 65 HMODULE lib; 66 BOOL ret = GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS 67 |GET_MODULE_HANDLE_EX_FLAG_PIN, 68 (LPCTSTR)&scalable_malloc, &lib); 69 MALLOC_ASSERT(lib && ret, "Allocator can't find itself."); 70 tbb::detail::suppress_unused_warning(ret); 71 SetErrorMode (prev_mode); 72 #endif /* USE_PTHREAD && !__TBB_SOURCE_DIRECTLY_INCLUDED */ 73 } 74 75 #if !__TBB_SOURCE_DIRECTLY_INCLUDED 76 #if USE_WINTHREAD 77 extern "C" BOOL WINAPI DllMain( HINSTANCE /*hInst*/, DWORD callReason, LPVOID lpvReserved) 78 { 79 if (callReason==DLL_THREAD_DETACH) 80 { 81 __TBB_mallocThreadShutdownNotification(); 82 } 83 else if (callReason==DLL_PROCESS_DETACH) 84 { 85 __TBB_mallocProcessShutdownNotification(lpvReserved != nullptr); 86 } 87 return TRUE; 88 } 89 #else /* !USE_WINTHREAD */ 90 struct RegisterProcessShutdownNotification { 91 // Work around non-reentrancy in dlopen() on Android 92 RegisterProcessShutdownNotification() { 93 // prevents unloading, POSIX case 94 95 // We need better support for the library pinning 96 // when dlopen can't find TBBmalloc library. 97 // for example: void *ret = dlopen(MALLOCLIB_NAME, RTLD_NOW); 98 // MALLOC_ASSERT(ret, "Allocator can't load itself."); 99 dlopen(MALLOCLIB_NAME, RTLD_NOW); 100 } 101 102 RegisterProcessShutdownNotification(RegisterProcessShutdownNotification&) = delete; 103 RegisterProcessShutdownNotification& operator=(const RegisterProcessShutdownNotification&) = delete; 104 105 ~RegisterProcessShutdownNotification() { 106 __TBB_mallocProcessShutdownNotification(false); 107 } 108 }; 109 110 static RegisterProcessShutdownNotification reg; 111 #endif /* !USE_WINTHREAD */ 112 #endif /* !__TBB_SOURCE_DIRECTLY_INCLUDED */ 113 114 } } // namespaces 115 116