151c0b2f7Stbbdev /*
22110128eSsarathnandu Copyright (c) 2005-2023 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"
228827ea7dSLong Nguyen #include "oneapi/tbb/scalable_allocator.h"
2351c0b2f7Stbbdev
2451c0b2f7Stbbdev #undef UNICODE
2551c0b2f7Stbbdev
2651c0b2f7Stbbdev #if USE_PTHREAD
2751c0b2f7Stbbdev #include <dlfcn.h> // dlopen
2851c0b2f7Stbbdev #elif USE_WINTHREAD
2951c0b2f7Stbbdev #include <windows.h>
3051c0b2f7Stbbdev #endif
3151c0b2f7Stbbdev
3251c0b2f7Stbbdev namespace rml {
3351c0b2f7Stbbdev namespace internal {
3451c0b2f7Stbbdev
3551c0b2f7Stbbdev #if TBB_USE_DEBUG
3651c0b2f7Stbbdev #define DEBUG_SUFFIX "_debug"
3751c0b2f7Stbbdev #else
3851c0b2f7Stbbdev #define DEBUG_SUFFIX
3951c0b2f7Stbbdev #endif /* TBB_USE_DEBUG */
4051c0b2f7Stbbdev
4151c0b2f7Stbbdev // MALLOCLIB_NAME is the name of the oneTBB memory allocator library.
4251c0b2f7Stbbdev #if _WIN32||_WIN64
4351c0b2f7Stbbdev #define MALLOCLIB_NAME "tbbmalloc" DEBUG_SUFFIX ".dll"
4451c0b2f7Stbbdev #elif __APPLE__
4526b42567SIlya Isaev #define MALLOCLIB_NAME "libtbbmalloc" DEBUG_SUFFIX ".2.dylib"
4651c0b2f7Stbbdev #elif __FreeBSD__ || __NetBSD__ || __OpenBSD__ || __sun || _AIX || __ANDROID__
4751c0b2f7Stbbdev #define MALLOCLIB_NAME "libtbbmalloc" DEBUG_SUFFIX ".so"
48734f0bc0SPablo Romero #elif __unix__
4951c0b2f7Stbbdev #define MALLOCLIB_NAME "libtbbmalloc" DEBUG_SUFFIX __TBB_STRING(.so.2)
5051c0b2f7Stbbdev #else
5151c0b2f7Stbbdev #error Unknown OS
5251c0b2f7Stbbdev #endif
5351c0b2f7Stbbdev
init_tbbmalloc()5451c0b2f7Stbbdev void init_tbbmalloc() {
5551c0b2f7Stbbdev #if __TBB_USE_ITT_NOTIFY
5651c0b2f7Stbbdev MallocInitializeITT();
5751c0b2f7Stbbdev #endif
5851c0b2f7Stbbdev
5951c0b2f7Stbbdev /* Preventing TBB allocator library from unloading to prevent
6051c0b2f7Stbbdev resource leak, as memory is not released on the library unload.
6151c0b2f7Stbbdev */
6251c0b2f7Stbbdev #if USE_WINTHREAD && !__TBB_SOURCE_DIRECTLY_INCLUDED && !__TBB_WIN8UI_SUPPORT
6351c0b2f7Stbbdev // Prevent Windows from displaying message boxes if it fails to load library
6451c0b2f7Stbbdev UINT prev_mode = SetErrorMode (SEM_FAILCRITICALERRORS);
6551c0b2f7Stbbdev HMODULE lib;
6651c0b2f7Stbbdev BOOL ret = GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
6751c0b2f7Stbbdev |GET_MODULE_HANDLE_EX_FLAG_PIN,
6851c0b2f7Stbbdev (LPCTSTR)&scalable_malloc, &lib);
6951c0b2f7Stbbdev MALLOC_ASSERT(lib && ret, "Allocator can't find itself.");
702110128eSsarathnandu tbb::detail::suppress_unused_warning(ret);
7151c0b2f7Stbbdev SetErrorMode (prev_mode);
7251c0b2f7Stbbdev #endif /* USE_PTHREAD && !__TBB_SOURCE_DIRECTLY_INCLUDED */
7351c0b2f7Stbbdev }
7451c0b2f7Stbbdev
7551c0b2f7Stbbdev #if !__TBB_SOURCE_DIRECTLY_INCLUDED
7651c0b2f7Stbbdev #if USE_WINTHREAD
DllMain(HINSTANCE,DWORD callReason,LPVOID lpvReserved)7751c0b2f7Stbbdev extern "C" BOOL WINAPI DllMain( HINSTANCE /*hInst*/, DWORD callReason, LPVOID lpvReserved)
7851c0b2f7Stbbdev {
7951c0b2f7Stbbdev if (callReason==DLL_THREAD_DETACH)
8051c0b2f7Stbbdev {
8151c0b2f7Stbbdev __TBB_mallocThreadShutdownNotification();
8251c0b2f7Stbbdev }
8351c0b2f7Stbbdev else if (callReason==DLL_PROCESS_DETACH)
8451c0b2f7Stbbdev {
8557f524caSIlya Isaev __TBB_mallocProcessShutdownNotification(lpvReserved != nullptr);
8651c0b2f7Stbbdev }
8751c0b2f7Stbbdev return TRUE;
8851c0b2f7Stbbdev }
8951c0b2f7Stbbdev #else /* !USE_WINTHREAD */
9051c0b2f7Stbbdev struct RegisterProcessShutdownNotification {
9151c0b2f7Stbbdev // Work around non-reentrancy in dlopen() on Android
RegisterProcessShutdownNotificationrml::internal::RegisterProcessShutdownNotification9251c0b2f7Stbbdev RegisterProcessShutdownNotification() {
9351c0b2f7Stbbdev // prevents unloading, POSIX case
9451c0b2f7Stbbdev
9551c0b2f7Stbbdev // We need better support for the library pinning
9651c0b2f7Stbbdev // when dlopen can't find TBBmalloc library.
9751c0b2f7Stbbdev // for example: void *ret = dlopen(MALLOCLIB_NAME, RTLD_NOW);
9851c0b2f7Stbbdev // MALLOC_ASSERT(ret, "Allocator can't load itself.");
9951c0b2f7Stbbdev dlopen(MALLOCLIB_NAME, RTLD_NOW);
10051c0b2f7Stbbdev }
101568a7e58SKrzysztof Filipek
102*3b378356SKrzysztof Filipek RegisterProcessShutdownNotification(RegisterProcessShutdownNotification&) = delete;
103*3b378356SKrzysztof Filipek RegisterProcessShutdownNotification& operator=(const RegisterProcessShutdownNotification&) = delete;
104*3b378356SKrzysztof Filipek
~RegisterProcessShutdownNotificationrml::internal::RegisterProcessShutdownNotification10551c0b2f7Stbbdev ~RegisterProcessShutdownNotification() {
10651c0b2f7Stbbdev __TBB_mallocProcessShutdownNotification(false);
10751c0b2f7Stbbdev }
10851c0b2f7Stbbdev };
10951c0b2f7Stbbdev
11051c0b2f7Stbbdev static RegisterProcessShutdownNotification reg;
11151c0b2f7Stbbdev #endif /* !USE_WINTHREAD */
11251c0b2f7Stbbdev #endif /* !__TBB_SOURCE_DIRECTLY_INCLUDED */
11351c0b2f7Stbbdev
11451c0b2f7Stbbdev } } // namespaces
11551c0b2f7Stbbdev
116