xref: /oneTBB/src/tbbmalloc/tbbmalloc.cpp (revision 8dcbd5b1)
1 /*
2     Copyright (c) 2005-2020 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 
23 #undef UNICODE
24 
25 #if USE_PTHREAD
26 #include <dlfcn.h> // dlopen
27 #elif USE_WINTHREAD
28 #include <windows.h>
29 #endif
30 
31 namespace rml {
32 namespace internal {
33 
34 #if TBB_USE_DEBUG
35 #define DEBUG_SUFFIX "_debug"
36 #else
37 #define DEBUG_SUFFIX
38 #endif /* TBB_USE_DEBUG */
39 
40 // MALLOCLIB_NAME is the name of the oneTBB memory allocator library.
41 #if _WIN32||_WIN64
42 #define MALLOCLIB_NAME "tbbmalloc" DEBUG_SUFFIX ".dll"
43 #elif __APPLE__
44 #define MALLOCLIB_NAME "libtbbmalloc" DEBUG_SUFFIX ".dylib"
45 #elif __FreeBSD__ || __NetBSD__ || __OpenBSD__ || __sun || _AIX || __ANDROID__
46 #define MALLOCLIB_NAME "libtbbmalloc" DEBUG_SUFFIX ".so"
47 #elif __linux__
48 #define MALLOCLIB_NAME "libtbbmalloc" DEBUG_SUFFIX  __TBB_STRING(.so.2)
49 #else
50 #error Unknown OS
51 #endif
52 
53 void init_tbbmalloc() {
54 #if __TBB_USE_ITT_NOTIFY
55     MallocInitializeITT();
56 #endif
57 
58 /* Preventing TBB allocator library from unloading to prevent
59    resource leak, as memory is not released on the library unload.
60 */
61 #if USE_WINTHREAD && !__TBB_SOURCE_DIRECTLY_INCLUDED && !__TBB_WIN8UI_SUPPORT
62     // Prevent Windows from displaying message boxes if it fails to load library
63     UINT prev_mode = SetErrorMode (SEM_FAILCRITICALERRORS);
64     HMODULE lib;
65     BOOL ret = GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
66                                  |GET_MODULE_HANDLE_EX_FLAG_PIN,
67                                  (LPCTSTR)&scalable_malloc, &lib);
68     MALLOC_ASSERT(lib && ret, "Allocator can't find itself.");
69     SetErrorMode (prev_mode);
70 #endif /* USE_PTHREAD && !__TBB_SOURCE_DIRECTLY_INCLUDED */
71 }
72 
73 #if !__TBB_SOURCE_DIRECTLY_INCLUDED
74 #if USE_WINTHREAD
75 extern "C" BOOL WINAPI DllMain( HINSTANCE /*hInst*/, DWORD callReason, LPVOID lpvReserved)
76 {
77     if (callReason==DLL_THREAD_DETACH)
78     {
79         __TBB_mallocThreadShutdownNotification();
80     }
81     else if (callReason==DLL_PROCESS_DETACH)
82     {
83         __TBB_mallocProcessShutdownNotification(lpvReserved != NULL);
84     }
85     return TRUE;
86 }
87 #else /* !USE_WINTHREAD */
88 struct RegisterProcessShutdownNotification {
89 // Work around non-reentrancy in dlopen() on Android
90 #if !__TBB_USE_DLOPEN_REENTRANCY_WORKAROUND
91     RegisterProcessShutdownNotification() {
92         // prevents unloading, POSIX case
93 
94         // We need better support for the library pinning
95         // when dlopen can't find TBBmalloc library.
96         // for example: void *ret = dlopen(MALLOCLIB_NAME, RTLD_NOW);
97         // MALLOC_ASSERT(ret, "Allocator can't load itself.");
98         dlopen(MALLOCLIB_NAME, RTLD_NOW);
99     }
100 #endif /* !__TBB_USE_DLOPEN_REENTRANCY_WORKAROUND */
101     ~RegisterProcessShutdownNotification() {
102         __TBB_mallocProcessShutdownNotification(false);
103     }
104 };
105 
106 static RegisterProcessShutdownNotification reg;
107 #endif /* !USE_WINTHREAD */
108 #endif /* !__TBB_SOURCE_DIRECTLY_INCLUDED */
109 
110 } } // namespaces
111 
112