extern "C" BOOL WINAPI DllMain( HINSTANCE /*hInst*/, DWORD callReason, LPVOID ) { if (callReason==DLL_THREAD_DETACH) { __TBB_mallocThreadShutdownNotification(); } else if (callReason==DLL_PROCESS_DETACH) { __TBB_mallocProcessShutdownNotification(); } return TRUE; }
/* Preventing TBB allocator library from unloading to prevent resource leak, as memory is not released on the library unload. */ #if USE_WINTHREAD && !__TBB_SOURCE_DIRECTLY_INCLUDED && !__TBB_WIN8UI_SUPPORT // Prevent Windows from displaying message boxes if it fails to load library UINT prev_mode = SetErrorMode (SEM_FAILCRITICALERRORS); HMODULE lib; BOOL ret = GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |GET_MODULE_HANDLE_EX_FLAG_PIN, (LPCTSTR)&scalable_malloc, &lib); MALLOC_ASSERT(lib && ret, "Allocator can't find itself."); SetErrorMode (prev_mode); #endif /* USE_PTHREAD && !__TBB_SOURCE_DIRECTLY_INCLUDED */ } #if !__TBB_SOURCE_DIRECTLY_INCLUDED #if USE_WINTHREAD extern "C" BOOL WINAPI DllMain( HINSTANCE /*hInst*/, DWORD callReason, LPVOID ) { if (callReason==DLL_THREAD_DETACH) { __TBB_mallocThreadShutdownNotification(); } else if (callReason==DLL_PROCESS_DETACH) { __TBB_mallocProcessShutdownNotification(); } return TRUE; } #else /* !USE_WINTHREAD */ struct RegisterProcessShutdownNotification { // Work around non-reentrancy in dlopen() on Android #if !__TBB_USE_DLOPEN_REENTRANCY_WORKAROUND RegisterProcessShutdownNotification() { // prevents unloading, POSIX case dlopen(MALLOCLIB_NAME, RTLD_NOW); } #endif /* !__ANDROID__ */ ~RegisterProcessShutdownNotification() { __TBB_mallocProcessShutdownNotification(); }
int main(void) { size_t i, j; int curr_mode, res; void *p1, *p2; atexit( MyExit ); for ( curr_mode = 0; curr_mode<=1; curr_mode++) { assert(ExpectedResultHugePages == scalable_allocation_mode(TBBMALLOC_USE_HUGE_PAGES, !curr_mode)); p1 = scalable_malloc(10*1024*1024); assert(p1); assert(ExpectedResultHugePages == scalable_allocation_mode(TBBMALLOC_USE_HUGE_PAGES, curr_mode)); scalable_free(p1); } /* note that huge pages (if supported) are still enabled at this point */ #if __TBB_SOURCE_DIRECTLY_INCLUDED assert(TBBMALLOC_OK == scalable_allocation_mode(TBBMALLOC_INTERNAL_SOURCE_INCLUDED, 0)); #endif for( i=0; i<=1<<16; ++i) { p1 = scalable_malloc(i); if( !p1 ) printf("Warning: there should be memory but scalable_malloc returned NULL\n"); scalable_free(p1); } p1 = p2 = NULL; for( i=1024*1024; ; i/=2 ) { scalable_free(p1); p1 = scalable_realloc(p2, i); p2 = scalable_calloc(i, 32); if (p2) { if (i<sizeof(size_t)) { for (j=0; j<i; j++) assert(0==*((char*)p2+j)); } else { for (j=0; j<i; j+=sizeof(size_t)) assert(0==*((size_t*)p2+j)); } } scalable_free(p2); p2 = scalable_malloc(i); if (i==0) break; } for( i=1; i<1024*1024; i*=2 ) { scalable_free(p1); p1 = scalable_realloc(p2, i); p2 = scalable_malloc(i); } scalable_free(p1); scalable_free(p2); res = scalable_allocation_command(TBBMALLOC_CLEAN_ALL_BUFFERS, NULL); assert(res == TBBMALLOC_OK); res = scalable_allocation_command(TBBMALLOC_CLEAN_THREAD_BUFFERS, NULL); /* expect all caches cleaned before, so got nothing from CLEAN_THREAD_BUFFERS */ assert(res == TBBMALLOC_NO_EFFECT); /* check that invalid param argument give expected result*/ res = scalable_allocation_command(TBBMALLOC_CLEAN_THREAD_BUFFERS, (void*)(intptr_t)1); assert(res == TBBMALLOC_INVALID_PARAM); __TBB_mallocProcessShutdownNotification(); printf("done\n"); return 0; }
/* test that it's possible to call allocation function from atexit after mallocProcessShutdownNotification() called */ static void MyExit(void) { void *p = scalable_malloc(32); assert(p); scalable_free(p); __TBB_mallocProcessShutdownNotification(); }