xref: /oneTBB/src/tbbmalloc/tbbmalloc.cpp (revision b15aabb3)
151c0b2f7Stbbdev /*
2*b15aabb3Stbbdev     Copyright (c) 2005-2021 Intel Corporation
351c0b2f7Stbbdev 
451c0b2f7Stbbdev     Licensed under the Apache License, Version 2.0 (the "License");
551c0b2f7Stbbdev     you may not use this file except in compliance with the License.
651c0b2f7Stbbdev     You may obtain a copy of the License at
751c0b2f7Stbbdev 
851c0b2f7Stbbdev         http://www.apache.org/licenses/LICENSE-2.0
951c0b2f7Stbbdev 
1051c0b2f7Stbbdev     Unless required by applicable law or agreed to in writing, software
1151c0b2f7Stbbdev     distributed under the License is distributed on an "AS IS" BASIS,
1251c0b2f7Stbbdev     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1351c0b2f7Stbbdev     See the License for the specific language governing permissions and
1451c0b2f7Stbbdev     limitations under the License.
1551c0b2f7Stbbdev */
1651c0b2f7Stbbdev 
1751c0b2f7Stbbdev #include "TypeDefinitions.h" // Customize.h and proxy.h get included
1851c0b2f7Stbbdev #include "tbbmalloc_internal_api.h"
1951c0b2f7Stbbdev 
2051c0b2f7Stbbdev #include "../tbb/assert_impl.h" // Out-of-line TBB assertion handling routines are instantiated here.
2149e08aacStbbdev #include "oneapi/tbb/version.h"
2251c0b2f7Stbbdev 
2351c0b2f7Stbbdev #undef UNICODE
2451c0b2f7Stbbdev 
2551c0b2f7Stbbdev #if USE_PTHREAD
2651c0b2f7Stbbdev #include <dlfcn.h> // dlopen
2751c0b2f7Stbbdev #elif USE_WINTHREAD
2851c0b2f7Stbbdev #include <windows.h>
2951c0b2f7Stbbdev #endif
3051c0b2f7Stbbdev 
3151c0b2f7Stbbdev namespace rml {
3251c0b2f7Stbbdev namespace internal {
3351c0b2f7Stbbdev 
3451c0b2f7Stbbdev #if TBB_USE_DEBUG
3551c0b2f7Stbbdev #define DEBUG_SUFFIX "_debug"
3651c0b2f7Stbbdev #else
3751c0b2f7Stbbdev #define DEBUG_SUFFIX
3851c0b2f7Stbbdev #endif /* TBB_USE_DEBUG */
3951c0b2f7Stbbdev 
4051c0b2f7Stbbdev // MALLOCLIB_NAME is the name of the oneTBB memory allocator library.
4151c0b2f7Stbbdev #if _WIN32||_WIN64
4251c0b2f7Stbbdev #define MALLOCLIB_NAME "tbbmalloc" DEBUG_SUFFIX ".dll"
4351c0b2f7Stbbdev #elif __APPLE__
4451c0b2f7Stbbdev #define MALLOCLIB_NAME "libtbbmalloc" DEBUG_SUFFIX ".dylib"
4551c0b2f7Stbbdev #elif __FreeBSD__ || __NetBSD__ || __OpenBSD__ || __sun || _AIX || __ANDROID__
4651c0b2f7Stbbdev #define MALLOCLIB_NAME "libtbbmalloc" DEBUG_SUFFIX ".so"
4751c0b2f7Stbbdev #elif __linux__
4851c0b2f7Stbbdev #define MALLOCLIB_NAME "libtbbmalloc" DEBUG_SUFFIX  __TBB_STRING(.so.2)
4951c0b2f7Stbbdev #else
5051c0b2f7Stbbdev #error Unknown OS
5151c0b2f7Stbbdev #endif
5251c0b2f7Stbbdev 
5351c0b2f7Stbbdev void init_tbbmalloc() {
5451c0b2f7Stbbdev #if __TBB_USE_ITT_NOTIFY
5551c0b2f7Stbbdev     MallocInitializeITT();
5651c0b2f7Stbbdev #endif
5751c0b2f7Stbbdev 
5851c0b2f7Stbbdev /* Preventing TBB allocator library from unloading to prevent
5951c0b2f7Stbbdev    resource leak, as memory is not released on the library unload.
6051c0b2f7Stbbdev */
6151c0b2f7Stbbdev #if USE_WINTHREAD && !__TBB_SOURCE_DIRECTLY_INCLUDED && !__TBB_WIN8UI_SUPPORT
6251c0b2f7Stbbdev     // Prevent Windows from displaying message boxes if it fails to load library
6351c0b2f7Stbbdev     UINT prev_mode = SetErrorMode (SEM_FAILCRITICALERRORS);
6451c0b2f7Stbbdev     HMODULE lib;
6551c0b2f7Stbbdev     BOOL ret = GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
6651c0b2f7Stbbdev                                  |GET_MODULE_HANDLE_EX_FLAG_PIN,
6751c0b2f7Stbbdev                                  (LPCTSTR)&scalable_malloc, &lib);
6851c0b2f7Stbbdev     MALLOC_ASSERT(lib && ret, "Allocator can't find itself.");
6951c0b2f7Stbbdev     SetErrorMode (prev_mode);
7051c0b2f7Stbbdev #endif /* USE_PTHREAD && !__TBB_SOURCE_DIRECTLY_INCLUDED */
7151c0b2f7Stbbdev }
7251c0b2f7Stbbdev 
7351c0b2f7Stbbdev #if !__TBB_SOURCE_DIRECTLY_INCLUDED
7451c0b2f7Stbbdev #if USE_WINTHREAD
7551c0b2f7Stbbdev extern "C" BOOL WINAPI DllMain( HINSTANCE /*hInst*/, DWORD callReason, LPVOID lpvReserved)
7651c0b2f7Stbbdev {
7751c0b2f7Stbbdev     if (callReason==DLL_THREAD_DETACH)
7851c0b2f7Stbbdev     {
7951c0b2f7Stbbdev         __TBB_mallocThreadShutdownNotification();
8051c0b2f7Stbbdev     }
8151c0b2f7Stbbdev     else if (callReason==DLL_PROCESS_DETACH)
8251c0b2f7Stbbdev     {
8351c0b2f7Stbbdev         __TBB_mallocProcessShutdownNotification(lpvReserved != NULL);
8451c0b2f7Stbbdev     }
8551c0b2f7Stbbdev     return TRUE;
8651c0b2f7Stbbdev }
8751c0b2f7Stbbdev #else /* !USE_WINTHREAD */
8851c0b2f7Stbbdev struct RegisterProcessShutdownNotification {
8951c0b2f7Stbbdev // Work around non-reentrancy in dlopen() on Android
9051c0b2f7Stbbdev #if !__TBB_USE_DLOPEN_REENTRANCY_WORKAROUND
9151c0b2f7Stbbdev     RegisterProcessShutdownNotification() {
9251c0b2f7Stbbdev         // prevents unloading, POSIX case
9351c0b2f7Stbbdev 
9451c0b2f7Stbbdev         // We need better support for the library pinning
9551c0b2f7Stbbdev         // when dlopen can't find TBBmalloc library.
9651c0b2f7Stbbdev         // for example: void *ret = dlopen(MALLOCLIB_NAME, RTLD_NOW);
9751c0b2f7Stbbdev         // MALLOC_ASSERT(ret, "Allocator can't load itself.");
9851c0b2f7Stbbdev         dlopen(MALLOCLIB_NAME, RTLD_NOW);
9951c0b2f7Stbbdev     }
10051c0b2f7Stbbdev #endif /* !__TBB_USE_DLOPEN_REENTRANCY_WORKAROUND */
10151c0b2f7Stbbdev     ~RegisterProcessShutdownNotification() {
10251c0b2f7Stbbdev         __TBB_mallocProcessShutdownNotification(false);
10351c0b2f7Stbbdev     }
10451c0b2f7Stbbdev };
10551c0b2f7Stbbdev 
10651c0b2f7Stbbdev static RegisterProcessShutdownNotification reg;
10751c0b2f7Stbbdev #endif /* !USE_WINTHREAD */
10851c0b2f7Stbbdev #endif /* !__TBB_SOURCE_DIRECTLY_INCLUDED */
10951c0b2f7Stbbdev 
11051c0b2f7Stbbdev } } // namespaces
11151c0b2f7Stbbdev 
112