static int __itt_lib_version(lib_t lib) { if (lib == NULL) return 0; if (__itt_get_proc(lib, "__itt_api_init")) return 2; if (__itt_get_proc(lib, "__itt_api_version")) return 1; return 0; }
ITT_EXTERN_C void _N_(fini_ittlib)(void) { __itt_api_fini_t* __itt_api_fini_ptr; static volatile TIDT current_thread = 0; if (__itt_ittapi_global.api_initialized) { __itt_mutex_lock(&__itt_ittapi_global.mutex); if (__itt_ittapi_global.api_initialized) { if (current_thread == 0) { current_thread = __itt_thread_id(); __itt_api_fini_ptr = (__itt_api_fini_t*)__itt_get_proc(__itt_ittapi_global.lib, "__itt_api_fini"); if (__itt_api_fini_ptr) __itt_api_fini_ptr(&__itt_ittapi_global); __itt_nullify_all_pointers(); /* TODO: !!! not safe !!! don't support unload so far. * if (__itt_ittapi_global.lib != NULL) * __itt_unload_lib(__itt_ittapi_global.lib); * __itt_ittapi_global.lib = NULL; */ __itt_ittapi_global.api_initialized = 0; current_thread = 0; } } __itt_mutex_unlock(&__itt_ittapi_global.mutex); } }
static int __itt_is_legacy_lib(lib_t lib) { if (lib == NULL) return 0; // if unknown assume NO if (__itt_get_proc(lib, "__itt_api_version")) return 0; // New interface - NO return 1; // It's legacy otherwise }
ITT_EXTERN_C int _N_(init_ittlib)(const char* lib_name, __itt_group_id init_groups) { register int i; __itt_group_id groups; #ifdef ITT_COMPLETE_GROUP __itt_group_id zero_group = __itt_group_none; #endif /* ITT_COMPLETE_GROUP */ static volatile TIDT current_thread = 0; if (!__itt_ittapi_global.api_initialized) { #ifndef ITT_SIMPLE_INIT ITT_MUTEX_INIT_AND_LOCK(__itt_ittapi_global); #endif /* ITT_SIMPLE_INIT */ if (!__itt_ittapi_global.api_initialized) { if (current_thread == 0) { current_thread = __itt_thread_id(); __itt_ittapi_global.thread_list->tid = current_thread; if (lib_name == NULL) lib_name = __itt_get_lib_name(); groups = __itt_get_groups(); if (groups != __itt_group_none || lib_name != NULL) { __itt_ittapi_global.lib = __itt_load_lib((lib_name == NULL) ? ittnotify_lib_name : lib_name); if (__itt_ittapi_global.lib != NULL) { __itt_api_init_t* __itt_api_init_ptr; int lib_version = __itt_lib_version(__itt_ittapi_global.lib); switch (lib_version) { case 0: groups = __itt_group_legacy; case 1: /* Fill all pointers from dynamic library */ for (i = 0; __itt_ittapi_global.api_list_ptr[i].name != NULL; i++) { if (__itt_ittapi_global.api_list_ptr[i].group & groups & init_groups) { *__itt_ittapi_global.api_list_ptr[i].func_ptr = (void*)__itt_get_proc(__itt_ittapi_global.lib, __itt_ittapi_global.api_list_ptr[i].name); if (*__itt_ittapi_global.api_list_ptr[i].func_ptr == NULL) { /* Restore pointers for function with static implementation */ *__itt_ittapi_global.api_list_ptr[i].func_ptr = __itt_ittapi_global.api_list_ptr[i].null_func; __itt_report_error(__itt_error_no_symbol, lib_name, __itt_ittapi_global.api_list_ptr[i].name); #ifdef ITT_COMPLETE_GROUP zero_group = (__itt_group_id)(zero_group | __itt_ittapi_global.api_list_ptr[i].group); #endif /* ITT_COMPLETE_GROUP */ } } else *__itt_ittapi_global.api_list_ptr[i].func_ptr = __itt_ittapi_global.api_list_ptr[i].null_func; } if (groups == __itt_group_legacy) { /* Compatibility with legacy tools */ ITTNOTIFY_NAME(thread_ignore) = ITTNOTIFY_NAME(thr_ignore); #if ITT_PLATFORM==ITT_PLATFORM_WIN ITTNOTIFY_NAME(sync_createA) = ITTNOTIFY_NAME(sync_set_nameA); ITTNOTIFY_NAME(sync_createW) = ITTNOTIFY_NAME(sync_set_nameW); #else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */ ITTNOTIFY_NAME(sync_create) = ITTNOTIFY_NAME(sync_set_name); #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ ITTNOTIFY_NAME(sync_prepare) = ITTNOTIFY_NAME(notify_sync_prepare); ITTNOTIFY_NAME(sync_cancel) = ITTNOTIFY_NAME(notify_sync_cancel); ITTNOTIFY_NAME(sync_acquired) = ITTNOTIFY_NAME(notify_sync_acquired); ITTNOTIFY_NAME(sync_releasing) = ITTNOTIFY_NAME(notify_sync_releasing); } #ifdef ITT_COMPLETE_GROUP for (i = 0; __itt_ittapi_global.api_list_ptr[i].name != NULL; i++) if (__itt_ittapi_global.api_list_ptr[i].group & zero_group) *__itt_ittapi_global.api_list_ptr[i].func_ptr = __itt_ittapi_global.api_list_ptr[i].null_func; #endif /* ITT_COMPLETE_GROUP */ break; case 2: __itt_api_init_ptr = (__itt_api_init_t*)__itt_get_proc(__itt_ittapi_global.lib, "__itt_api_init"); if (__itt_api_init_ptr) __itt_api_init_ptr(&__itt_ittapi_global, init_groups); break; } } else { __itt_nullify_all_pointers(); __itt_report_error(__itt_error_no_module, lib_name, #if ITT_PLATFORM==ITT_PLATFORM_WIN __itt_system_error() #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ dlerror() #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ ); } } else { __itt_nullify_all_pointers(); } __itt_ittapi_global.api_initialized = 1; current_thread = 0; /* !!! Just to avoid unused code elimination !!! */ if (__itt_fini_ittlib_ptr == _N_(fini_ittlib)) current_thread = 0; } } #ifndef ITT_SIMPLE_INIT __itt_mutex_unlock(&__itt_ittapi_global.mutex); #endif /* ITT_SIMPLE_INIT */ } /* Evaluating if any function ptr is non empty and it's in init_groups */ for (i = 0; __itt_ittapi_global.api_list_ptr[i].name != NULL; i++) if (*__itt_ittapi_global.api_list_ptr[i].func_ptr != __itt_ittapi_global.api_list_ptr[i].null_func && __itt_ittapi_global.api_list_ptr[i].group & init_groups) return 1; return 0; }
static int _N_(init_ittlib)(const char* lib_name, __itt_group_id groups) { int i, ret = 0; static volatile TIDT current_thread = 0; if (!ittnotify_init) { #ifndef ITT_SIMPLE_INIT static mutex_t mutex; static volatile int inter_counter = 0; static volatile int mutex_initialized = 0; if (!mutex_initialized) { if (__itt_interlocked_increment(&inter_counter) == 1) { __itt_mutex_init(&mutex); mutex_initialized = 1; } else while (!mutex_initialized) __itt_thread_yield(); } __itt_mutex_lock(&mutex); #endif /* ITT_SIMPLE_INIT */ if (!ittnotify_init) { if (current_thread == 0) { current_thread = __itt_thread_id(); if (groups == __itt_group_none) groups = __itt_get_groups(); if (groups == __itt_group_none) { // Clear all pointers for (i = 0; func_map[i].name != NULL; i++ ) *func_map[i].func_ptr = NULL; } else { __itt_group_id zero_group = __itt_group_none; if (lib_name == NULL) lib_name = __itt_get_lib_name(); ittnotify_lib = __itt_load_lib(lib_name); if (ittnotify_lib != NULL) { if (__itt_is_legacy_lib(ittnotify_lib)) groups = __itt_group_legacy; for (i = 0; func_map[i].name != NULL; i++) { if (func_map[i].group & groups) { *func_map[i].func_ptr = (void*)__itt_get_proc(ittnotify_lib, func_map[i].name); if (*func_map[i].func_ptr == NULL) { __itt_report_error(__itt_error_no_symbol, lib_name, func_map[i].name ); zero_group = (__itt_group_id)(zero_group | func_map[i].group); } } else *func_map[i].func_ptr = NULL; } if (groups == __itt_group_legacy) { // Compatibility with legacy tools ITTNOTIFY_NAME(sync_prepare) = ITTNOTIFY_NAME(notify_sync_prepare); ITTNOTIFY_NAME(sync_cancel) = ITTNOTIFY_NAME(notify_sync_cancel); ITTNOTIFY_NAME(sync_acquired) = ITTNOTIFY_NAME(notify_sync_acquired); ITTNOTIFY_NAME(sync_releasing) = ITTNOTIFY_NAME(notify_sync_releasing); } } else { // Clear all pointers for (i = 0; func_map[i].name != NULL; i++) *func_map[i].func_ptr = NULL; __itt_report_error(__itt_error_no_module, lib_name, #if ITT_PLATFORM==ITT_PLATFORM_WIN __itt_system_error() #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ dlerror() #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ ); } #ifdef ITT_COMPLETE_GROUP for (i = 0; func_map[i].name != NULL; i++) if (func_map[i].group & zero_group) *func_map[i].func_ptr = NULL; #endif /* ITT_COMPLETE_GROUP */ /* evaluating if any function ptr is non empty */ for (i = 0; func_map[i].name != NULL; i++) { if (*func_map[i].func_ptr != NULL) { ret = 1; break; } } } ittnotify_init = 1; current_thread = 0; } } #ifndef ITT_SIMPLE_INIT __itt_mutex_unlock(&mutex); #endif /* ITT_SIMPLE_INIT */ } return ret; }