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