| |
| //===----------------------------------------------------------------------===// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file is dual licensed under the MIT and the University of Illinois Open |
| // Source Licenses. See LICENSE.txt for details. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include "ittnotify_config.h" |
| |
| #if ITT_PLATFORM==ITT_PLATFORM_WIN |
| #define PATH_MAX 512 |
| #else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */ |
| #include <limits.h> |
| #include <dlfcn.h> |
| #include <errno.h> |
| #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <stdarg.h> |
| #include <string.h> |
| |
| #define INTEL_NO_MACRO_BODY |
| #define INTEL_ITTNOTIFY_API_PRIVATE |
| #include "ittnotify.h" |
| #include "legacy/ittnotify.h" |
| |
| #include "disable_warnings.h" |
| |
| static const char api_version[] = API_VERSION "\0\n@(#) $Revision: 43375 $\n"; |
| |
| #define _N_(n) ITT_JOIN(INTEL_ITTNOTIFY_PREFIX,n) |
| |
| #if ITT_OS==ITT_OS_WIN |
| static const char* ittnotify_lib_name = "libittnotify.dll"; |
| #elif ITT_OS==ITT_OS_LINUX |
| static const char* ittnotify_lib_name = "libittnotify.so"; |
| #elif ITT_OS==ITT_OS_MAC |
| static const char* ittnotify_lib_name = "libittnotify.dylib"; |
| #else |
| #error Unsupported or unknown OS. |
| #endif |
| |
| #ifdef __ANDROID__ |
| #include <android/log.h> |
| #include <stdio.h> |
| #include <unistd.h> |
| #include <sys/types.h> |
| #include <sys/stat.h> |
| #include <fcntl.h> |
| #include <linux/limits.h> |
| |
| #ifdef ITT_ANDROID_LOG |
| #define ITT_ANDROID_LOG_TAG "INTEL_VTUNE_USERAPI" |
| #define ITT_ANDROID_LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, ITT_ANDROID_LOG_TAG, __VA_ARGS__)) |
| #define ITT_ANDROID_LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, ITT_ANDROID_LOG_TAG, __VA_ARGS__)) |
| #define ITT_ANDROID_LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR,ITT_ANDROID_LOG_TAG, __VA_ARGS__)) |
| #define ITT_ANDROID_LOGD(...) ((void)__android_log_print(ANDROID_LOG_DEBUG,ITT_ANDROID_LOG_TAG, __VA_ARGS__)) |
| #else |
| #define ITT_ANDROID_LOGI(...) |
| #define ITT_ANDROID_LOGW(...) |
| #define ITT_ANDROID_LOGE(...) |
| #define ITT_ANDROID_LOGD(...) |
| #endif |
| |
| /* default location of userapi collector on Android */ |
| #define ANDROID_ITTNOTIFY_DEFAULT_PATH "/data/data/com.intel.vtune/intel/libittnotify.so" |
| #endif |
| |
| |
| #ifndef LIB_VAR_NAME |
| #if ITT_ARCH==ITT_ARCH_IA32 || ITT_ARCH==ITT_ARCH_ARM |
| #define LIB_VAR_NAME INTEL_LIBITTNOTIFY32 |
| #else |
| #define LIB_VAR_NAME INTEL_LIBITTNOTIFY64 |
| #endif |
| #endif /* LIB_VAR_NAME */ |
| |
| #define ITT_MUTEX_INIT_AND_LOCK(p) { \ |
| if (!p.mutex_initialized) \ |
| { \ |
| if (__itt_interlocked_increment(&p.atomic_counter) == 1) \ |
| { \ |
| __itt_mutex_init(&p.mutex); \ |
| p.mutex_initialized = 1; \ |
| } \ |
| else \ |
| while (!p.mutex_initialized) \ |
| __itt_thread_yield(); \ |
| } \ |
| __itt_mutex_lock(&p.mutex); \ |
| } |
| |
| const int _N_(err) = 0; |
| |
| typedef int (__itt_init_ittlib_t)(const char*, __itt_group_id); |
| |
| /* this define used to control initialization function name. */ |
| #ifndef __itt_init_ittlib_name |
| ITT_EXTERN_C int _N_(init_ittlib)(const char*, __itt_group_id); |
| static __itt_init_ittlib_t* __itt_init_ittlib_ptr = _N_(init_ittlib); |
| #define __itt_init_ittlib_name __itt_init_ittlib_ptr |
| #endif /* __itt_init_ittlib_name */ |
| |
| typedef void (__itt_fini_ittlib_t)(void); |
| |
| /* this define used to control finalization function name. */ |
| #ifndef __itt_fini_ittlib_name |
| ITT_EXTERN_C void _N_(fini_ittlib)(void); |
| static __itt_fini_ittlib_t* __itt_fini_ittlib_ptr = _N_(fini_ittlib); |
| #define __itt_fini_ittlib_name __itt_fini_ittlib_ptr |
| #endif /* __itt_fini_ittlib_name */ |
| |
| /* building pointers to imported funcs */ |
| #undef ITT_STUBV |
| #undef ITT_STUB |
| #define ITT_STUB(api,type,name,args,params,ptr,group,format) \ |
| static type api ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init)) args;\ |
| typedef type api ITT_JOIN(_N_(name),_t) args; \ |
| ITT_EXTERN_C ITT_JOIN(_N_(name),_t)* ITTNOTIFY_NAME(name) = ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init)); \ |
| static type api ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init)) args \ |
| { \ |
| __itt_init_ittlib_name(NULL, __itt_group_all); \ |
| if (ITTNOTIFY_NAME(name) && ITTNOTIFY_NAME(name) != ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init))) \ |
| return ITTNOTIFY_NAME(name) params; \ |
| else \ |
| return (type)0; \ |
| } |
| |
| #define ITT_STUBV(api,type,name,args,params,ptr,group,format) \ |
| static type api ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init)) args;\ |
| typedef type api ITT_JOIN(_N_(name),_t) args; \ |
| ITT_EXTERN_C ITT_JOIN(_N_(name),_t)* ITTNOTIFY_NAME(name) = ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init)); \ |
| static type api ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init)) args \ |
| { \ |
| __itt_init_ittlib_name(NULL, __itt_group_all); \ |
| if (ITTNOTIFY_NAME(name) && ITTNOTIFY_NAME(name) != ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init))) \ |
| ITTNOTIFY_NAME(name) params; \ |
| else \ |
| return; \ |
| } |
| |
| #undef __ITT_INTERNAL_INIT |
| #include "ittnotify_static.h" |
| |
| #undef ITT_STUB |
| #undef ITT_STUBV |
| #define ITT_STUB(api,type,name,args,params,ptr,group,format) \ |
| static type api ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init)) args;\ |
| typedef type api ITT_JOIN(_N_(name),_t) args; \ |
| ITT_EXTERN_C ITT_JOIN(_N_(name),_t)* ITTNOTIFY_NAME(name) = ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init)); |
| |
| #define ITT_STUBV(api,type,name,args,params,ptr,group,format) \ |
| static type api ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init)) args;\ |
| typedef type api ITT_JOIN(_N_(name),_t) args; \ |
| ITT_EXTERN_C ITT_JOIN(_N_(name),_t)* ITTNOTIFY_NAME(name) = ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init)); |
| |
| #define __ITT_INTERNAL_INIT |
| #include "ittnotify_static.h" |
| #undef __ITT_INTERNAL_INIT |
| |
| ITT_GROUP_LIST(group_list); |
| |
| #pragma pack(push, 8) |
| |
| typedef struct ___itt_group_alias |
| { |
| const char* env_var; |
| __itt_group_id groups; |
| } __itt_group_alias; |
| |
| static __itt_group_alias group_alias[] = { |
| { "KMP_FOR_TPROFILE", (__itt_group_id)(__itt_group_control | __itt_group_thread | __itt_group_sync | __itt_group_mark) }, |
| { "KMP_FOR_TCHECK", (__itt_group_id)(__itt_group_control | __itt_group_thread | __itt_group_sync | __itt_group_fsync | __itt_group_mark | __itt_group_suppress) }, |
| { NULL, (__itt_group_none) }, |
| { api_version, (__itt_group_none) } /* !!! Just to avoid unused code elimination !!! */ |
| }; |
| |
| #pragma pack(pop) |
| |
| #if ITT_PLATFORM==ITT_PLATFORM_WIN |
| #pragma warning(push) |
| #pragma warning(disable: 4054) /* warning C4054: 'type cast' : from function pointer 'XXX' to data pointer 'void *' */ |
| #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ |
| |
| static __itt_api_info api_list[] = { |
| /* Define functions with static implementation */ |
| #undef ITT_STUB |
| #undef ITT_STUBV |
| #define ITT_STUB(api,type,name,args,params,nameindll,group,format) { ITT_TO_STR(ITT_JOIN(__itt_,nameindll)), (void**)(void*)&ITTNOTIFY_NAME(name), (void*)(size_t)&ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init)), (void*)(size_t)&ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init)), (__itt_group_id)(group)}, |
| #define ITT_STUBV ITT_STUB |
| #define __ITT_INTERNAL_INIT |
| #include "ittnotify_static.h" |
| #undef __ITT_INTERNAL_INIT |
| /* Define functions without static implementation */ |
| #undef ITT_STUB |
| #undef ITT_STUBV |
| #define ITT_STUB(api,type,name,args,params,nameindll,group,format) {ITT_TO_STR(ITT_JOIN(__itt_,nameindll)), (void**)(void*)&ITTNOTIFY_NAME(name), (void*)(size_t)&ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init)), NULL, (__itt_group_id)(group)}, |
| #define ITT_STUBV ITT_STUB |
| #include "ittnotify_static.h" |
| {NULL, NULL, NULL, NULL, __itt_group_none} |
| }; |
| |
| #if ITT_PLATFORM==ITT_PLATFORM_WIN |
| #pragma warning(pop) |
| #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ |
| |
| /* private, init thread info item. used for internal purposes */ |
| static __itt_thread_info init_thread_info = { |
| (const char*)NULL, /* nameA */ |
| #if defined(UNICODE) || defined(_UNICODE) |
| (const wchar_t*)NULL, /* nameW */ |
| #else |
| (void*)NULL, /* nameW */ |
| #endif |
| 0, /* tid */ |
| __itt_thread_normal, /* state */ |
| 0, /* extra1 */ |
| (void*)NULL, /* extra2 */ |
| (__itt_thread_info*)NULL /* next */ |
| }; |
| |
| /* private, NULL domain item. used for internal purposes */ |
| static __itt_domain null_domain = { |
| 0, /* flags: disabled by default */ |
| (const char*)NULL, /* nameA */ |
| #if defined(UNICODE) || defined(_UNICODE) |
| (const wchar_t*)NULL, /* nameW */ |
| #else |
| (void*)NULL, /* nameW */ |
| #endif |
| 0, /* extra1 */ |
| (void*)NULL, /* extra2 */ |
| (__itt_domain*)NULL /* next */ |
| }; |
| |
| /* private, NULL string handle item. used for internal purposes */ |
| static __itt_string_handle null_string_handle = { |
| (const char*)NULL, /* strA */ |
| #if defined(UNICODE) || defined(_UNICODE) |
| (const wchar_t*)NULL, /* strW */ |
| #else |
| (void*)NULL, /* strW */ |
| #endif |
| 0, /* extra1 */ |
| (void*)NULL, /* extra2 */ |
| (__itt_string_handle*)NULL /* next */ |
| }; |
| |
| static const char dll_path[PATH_MAX] = { 0 }; |
| |
| /* static part descriptor which handles. all notification api attributes. */ |
| __itt_global _N_(_ittapi_global) = { |
| ITT_MAGIC, /* identification info */ |
| ITT_MAJOR, ITT_MINOR, API_VERSION_BUILD, /* version info */ |
| 0, /* api_initialized */ |
| 0, /* mutex_initialized */ |
| 0, /* atomic_counter */ |
| MUTEX_INITIALIZER, /* mutex */ |
| NULL, /* dynamic library handle */ |
| NULL, /* error_handler */ |
| (const char**)&dll_path, /* dll_path_ptr */ |
| (__itt_api_info*)&api_list, /* api_list_ptr */ |
| NULL, /* next __itt_global */ |
| (__itt_thread_info*)&init_thread_info, /* thread_list */ |
| (__itt_domain*)&null_domain, /* domain_list */ |
| (__itt_string_handle*)&null_string_handle, /* string_list */ |
| __itt_collection_normal /* collection state */ |
| }; |
| |
| typedef void (__itt_api_init_t)(__itt_global*, __itt_group_id); |
| typedef void (__itt_api_fini_t)(__itt_global*); |
| |
| /* ========================================================================= */ |
| |
| #ifdef ITT_NOTIFY_EXT_REPORT |
| ITT_EXTERN_C void _N_(error_handler)(__itt_error_code, va_list args); |
| #endif /* ITT_NOTIFY_EXT_REPORT */ |
| |
| #if ITT_PLATFORM==ITT_PLATFORM_WIN |
| #pragma warning(push) |
| #pragma warning(disable: 4055) /* warning C4055: 'type cast' : from data pointer 'void *' to function pointer 'XXX' */ |
| #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ |
| |
| static void __itt_report_error(__itt_error_code code, ...) |
| { |
| va_list args; |
| va_start(args, code); |
| if (_N_(_ittapi_global).error_handler != NULL) |
| { |
| __itt_error_handler_t* handler = (__itt_error_handler_t*)(size_t)_N_(_ittapi_global).error_handler; |
| handler(code, args); |
| } |
| #ifdef ITT_NOTIFY_EXT_REPORT |
| _N_(error_handler)(code, args); |
| #endif /* ITT_NOTIFY_EXT_REPORT */ |
| va_end(args); |
| } |
| |
| #if ITT_PLATFORM==ITT_PLATFORM_WIN |
| #pragma warning(pop) |
| #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ |
| |
| #if ITT_PLATFORM==ITT_PLATFORM_WIN |
| static __itt_domain* ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(domain_createW),_init))(const wchar_t* name) |
| { |
| __itt_domain *h_tail, *h; |
| |
| if (!_N_(_ittapi_global).api_initialized && _N_(_ittapi_global).thread_list->tid == 0) |
| { |
| __itt_init_ittlib_name(NULL, __itt_group_all); |
| if (ITTNOTIFY_NAME(domain_createW) && ITTNOTIFY_NAME(domain_createW) != ITT_VERSIONIZE(ITT_JOIN(_N_(domain_createW),_init))) |
| return ITTNOTIFY_NAME(domain_createW)(name); |
| } |
| |
| if (name == NULL) |
| return _N_(_ittapi_global).domain_list; |
| |
| ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global)); |
| for (h_tail = NULL, h = _N_(_ittapi_global).domain_list; h != NULL; h_tail = h, h = h->next) |
| if (h->nameW != NULL && !wcscmp(h->nameW, name)) |
| break; |
| if (h == NULL) { |
| NEW_DOMAIN_W(&_N_(_ittapi_global),h,h_tail,name); |
| } |
| __itt_mutex_unlock(&_N_(_ittapi_global).mutex); |
| return h; |
| } |
| |
| static __itt_domain* ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(domain_createA),_init))(const char* name) |
| #else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */ |
| static __itt_domain* ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(domain_create),_init))(const char* name) |
| #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ |
| { |
| __itt_domain *h_tail, *h; |
| |
| if (!_N_(_ittapi_global).api_initialized && _N_(_ittapi_global).thread_list->tid == 0) |
| { |
| __itt_init_ittlib_name(NULL, __itt_group_all); |
| #if ITT_PLATFORM==ITT_PLATFORM_WIN |
| if (ITTNOTIFY_NAME(domain_createA) && ITTNOTIFY_NAME(domain_createA) != ITT_VERSIONIZE(ITT_JOIN(_N_(domain_createA),_init))) |
| return ITTNOTIFY_NAME(domain_createA)(name); |
| #else |
| if (ITTNOTIFY_NAME(domain_create) && ITTNOTIFY_NAME(domain_create) != ITT_VERSIONIZE(ITT_JOIN(_N_(domain_create),_init))) |
| return ITTNOTIFY_NAME(domain_create)(name); |
| #endif |
| } |
| |
| if (name == NULL) |
| return _N_(_ittapi_global).domain_list; |
| |
| ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global)); |
| for (h_tail = NULL, h = _N_(_ittapi_global).domain_list; h != NULL; h_tail = h, h = h->next) |
| if (h->nameA != NULL && !__itt_fstrcmp(h->nameA, name)) |
| break; |
| if (h == NULL) { |
| NEW_DOMAIN_A(&_N_(_ittapi_global),h,h_tail,name); |
| } |
| __itt_mutex_unlock(&_N_(_ittapi_global).mutex); |
| return h; |
| } |
| |
| #if ITT_PLATFORM==ITT_PLATFORM_WIN |
| static __itt_string_handle* ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(string_handle_createW),_init))(const wchar_t* name) |
| { |
| __itt_string_handle *h_tail, *h; |
| |
| if (!_N_(_ittapi_global).api_initialized && _N_(_ittapi_global).thread_list->tid == 0) |
| { |
| __itt_init_ittlib_name(NULL, __itt_group_all); |
| if (ITTNOTIFY_NAME(string_handle_createW) && ITTNOTIFY_NAME(string_handle_createW) != ITT_VERSIONIZE(ITT_JOIN(_N_(string_handle_createW),_init))) |
| return ITTNOTIFY_NAME(string_handle_createW)(name); |
| } |
| |
| if (name == NULL) |
| return _N_(_ittapi_global).string_list; |
| |
| ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global)); |
| for (h_tail = NULL, h = _N_(_ittapi_global).string_list; h != NULL; h_tail = h, h = h->next) |
| if (h->strW != NULL && !wcscmp(h->strW, name)) |
| break; |
| if (h == NULL) { |
| NEW_STRING_HANDLE_W(&_N_(_ittapi_global),h,h_tail,name); |
| } |
| __itt_mutex_unlock(&_N_(_ittapi_global).mutex); |
| return h; |
| } |
| |
| static __itt_string_handle* ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(string_handle_createA),_init))(const char* name) |
| #else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */ |
| static __itt_string_handle* ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(string_handle_create),_init))(const char* name) |
| #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ |
| { |
| __itt_string_handle *h_tail, *h; |
| |
| if (!_N_(_ittapi_global).api_initialized && _N_(_ittapi_global).thread_list->tid == 0) |
| { |
| __itt_init_ittlib_name(NULL, __itt_group_all); |
| #if ITT_PLATFORM==ITT_PLATFORM_WIN |
| if (ITTNOTIFY_NAME(string_handle_createA) && ITTNOTIFY_NAME(string_handle_createA) != ITT_VERSIONIZE(ITT_JOIN(_N_(string_handle_createA),_init))) |
| return ITTNOTIFY_NAME(string_handle_createA)(name); |
| #else |
| if (ITTNOTIFY_NAME(string_handle_create) && ITTNOTIFY_NAME(string_handle_create) != ITT_VERSIONIZE(ITT_JOIN(_N_(string_handle_create),_init))) |
| return ITTNOTIFY_NAME(string_handle_create)(name); |
| #endif |
| } |
| |
| if (name == NULL) |
| return _N_(_ittapi_global).string_list; |
| |
| ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global)); |
| for (h_tail = NULL, h = _N_(_ittapi_global).string_list; h != NULL; h_tail = h, h = h->next) |
| if (h->strA != NULL && !__itt_fstrcmp(h->strA, name)) |
| break; |
| if (h == NULL) { |
| NEW_STRING_HANDLE_A(&_N_(_ittapi_global),h,h_tail,name); |
| } |
| __itt_mutex_unlock(&_N_(_ittapi_global).mutex); |
| return h; |
| } |
| |
| /* -------------------------------------------------------------------------- */ |
| |
| static void ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(pause),_init))(void) |
| { |
| if (!_N_(_ittapi_global).api_initialized && _N_(_ittapi_global).thread_list->tid == 0) |
| { |
| __itt_init_ittlib_name(NULL, __itt_group_all); |
| if (ITTNOTIFY_NAME(pause) && ITTNOTIFY_NAME(pause) != ITT_VERSIONIZE(ITT_JOIN(_N_(pause),_init))) |
| { |
| ITTNOTIFY_NAME(pause)(); |
| return; |
| } |
| } |
| _N_(_ittapi_global).state = __itt_collection_paused; |
| } |
| |
| static void ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(resume),_init))(void) |
| { |
| if (!_N_(_ittapi_global).api_initialized && _N_(_ittapi_global).thread_list->tid == 0) |
| { |
| __itt_init_ittlib_name(NULL, __itt_group_all); |
| if (ITTNOTIFY_NAME(resume) && ITTNOTIFY_NAME(resume) != ITT_VERSIONIZE(ITT_JOIN(_N_(resume),_init))) |
| { |
| ITTNOTIFY_NAME(resume)(); |
| return; |
| } |
| } |
| _N_(_ittapi_global).state = __itt_collection_normal; |
| } |
| |
| #if ITT_PLATFORM==ITT_PLATFORM_WIN |
| static void ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_nameW),_init))(const wchar_t* name) |
| { |
| TIDT tid = __itt_thread_id(); |
| __itt_thread_info *h_tail, *h; |
| |
| if (!_N_(_ittapi_global).api_initialized && _N_(_ittapi_global).thread_list->tid == 0) |
| { |
| __itt_init_ittlib_name(NULL, __itt_group_all); |
| if (ITTNOTIFY_NAME(thread_set_nameW) && ITTNOTIFY_NAME(thread_set_nameW) != ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_nameW),_init))) |
| { |
| ITTNOTIFY_NAME(thread_set_nameW)(name); |
| return; |
| } |
| } |
| |
| __itt_mutex_lock(&_N_(_ittapi_global).mutex); |
| for (h_tail = NULL, h = _N_(_ittapi_global).thread_list; h != NULL; h_tail = h, h = h->next) |
| if (h->tid == tid) |
| break; |
| if (h == NULL) { |
| NEW_THREAD_INFO_W(&_N_(_ittapi_global), h, h_tail, tid, __itt_thread_normal, name); |
| } |
| else |
| { |
| h->nameW = name ? _wcsdup(name) : NULL; |
| } |
| __itt_mutex_unlock(&_N_(_ittapi_global).mutex); |
| } |
| |
| static int ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(thr_name_setW),_init))(const wchar_t* name, int namelen) |
| { |
| namelen = namelen; |
| ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_nameW),_init))(name); |
| return 0; |
| } |
| |
| static void ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_nameA),_init))(const char* name) |
| #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ |
| static void ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_name),_init))(const char* name) |
| #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ |
| { |
| TIDT tid = __itt_thread_id(); |
| __itt_thread_info *h_tail, *h; |
| |
| if (!_N_(_ittapi_global).api_initialized && _N_(_ittapi_global).thread_list->tid == 0) |
| { |
| __itt_init_ittlib_name(NULL, __itt_group_all); |
| #if ITT_PLATFORM==ITT_PLATFORM_WIN |
| if (ITTNOTIFY_NAME(thread_set_nameA) && ITTNOTIFY_NAME(thread_set_nameA) != ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_nameA),_init))) |
| { |
| ITTNOTIFY_NAME(thread_set_nameA)(name); |
| return; |
| } |
| #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ |
| if (ITTNOTIFY_NAME(thread_set_name) && ITTNOTIFY_NAME(thread_set_name) != ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_name),_init))) |
| { |
| ITTNOTIFY_NAME(thread_set_name)(name); |
| return; |
| } |
| #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ |
| } |
| |
| __itt_mutex_lock(&_N_(_ittapi_global).mutex); |
| for (h_tail = NULL, h = _N_(_ittapi_global).thread_list; h != NULL; h_tail = h, h = h->next) |
| if (h->tid == tid) |
| break; |
| if (h == NULL) { |
| NEW_THREAD_INFO_A(&_N_(_ittapi_global), h, h_tail, tid, __itt_thread_normal, name); |
| } |
| else |
| { |
| h->nameA = name ? __itt_fstrdup(name) : NULL; |
| } |
| __itt_mutex_unlock(&_N_(_ittapi_global).mutex); |
| } |
| |
| #if ITT_PLATFORM==ITT_PLATFORM_WIN |
| static int ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(thr_name_setA),_init))(const char* name, int namelen) |
| { |
| namelen = namelen; |
| ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_nameA),_init))(name); |
| return 0; |
| } |
| #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ |
| static int ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(thr_name_set),_init))(const char* name, int namelen) |
| { |
| namelen = namelen; |
| ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_name),_init))(name); |
| return 0; |
| } |
| #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ |
| |
| static void ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(thread_ignore),_init))(void) |
| { |
| TIDT tid = __itt_thread_id(); |
| __itt_thread_info *h_tail, *h; |
| |
| if (!_N_(_ittapi_global).api_initialized && _N_(_ittapi_global).thread_list->tid == 0) |
| { |
| __itt_init_ittlib_name(NULL, __itt_group_all); |
| if (ITTNOTIFY_NAME(thread_ignore) && ITTNOTIFY_NAME(thread_ignore) != ITT_VERSIONIZE(ITT_JOIN(_N_(thread_ignore),_init))) |
| { |
| ITTNOTIFY_NAME(thread_ignore)(); |
| return; |
| } |
| } |
| |
| __itt_mutex_lock(&_N_(_ittapi_global).mutex); |
| for (h_tail = NULL, h = _N_(_ittapi_global).thread_list; h != NULL; h_tail = h, h = h->next) |
| if (h->tid == tid) |
| break; |
| if (h == NULL) { |
| static const char* name = "unknown"; |
| NEW_THREAD_INFO_A(&_N_(_ittapi_global), h, h_tail, tid, __itt_thread_ignored, name); |
| } |
| else |
| { |
| h->state = __itt_thread_ignored; |
| } |
| __itt_mutex_unlock(&_N_(_ittapi_global).mutex); |
| } |
| |
| static void ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(thr_ignore),_init))(void) |
| { |
| ITT_VERSIONIZE(ITT_JOIN(_N_(thread_ignore),_init))(); |
| } |
| |
| static void ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(enable_attach),_init))(void) |
| { |
| #ifdef __ANDROID__ |
| /* |
| * if LIB_VAR_NAME env variable were set before then stay previous value |
| * else set default path |
| */ |
| setenv(ITT_TO_STR(LIB_VAR_NAME), ANDROID_ITTNOTIFY_DEFAULT_PATH, 0); |
| #endif |
| } |
| |
| /* -------------------------------------------------------------------------- */ |
| |
| static const char* __itt_fsplit(const char* s, const char* sep, const char** out, int* len) |
| { |
| int i; |
| int j; |
| |
| if (!s || !sep || !out || !len) |
| return NULL; |
| |
| for (i = 0; s[i]; i++) |
| { |
| int b = 0; |
| for (j = 0; sep[j]; j++) |
| if (s[i] == sep[j]) |
| { |
| b = 1; |
| break; |
| } |
| if (!b) |
| break; |
| } |
| |
| if (!s[i]) |
| return NULL; |
| |
| *len = 0; |
| *out = &s[i]; |
| |
| for (; s[i]; i++, (*len)++) |
| { |
| int b = 0; |
| for (j = 0; sep[j]; j++) |
| if (s[i] == sep[j]) |
| { |
| b = 1; |
| break; |
| } |
| if (b) |
| break; |
| } |
| |
| for (; s[i]; i++) |
| { |
| int b = 0; |
| for (j = 0; sep[j]; j++) |
| if (s[i] == sep[j]) |
| { |
| b = 1; |
| break; |
| } |
| if (!b) |
| break; |
| } |
| |
| return &s[i]; |
| } |
| |
| /* This function return value of env variable that placed into static buffer. |
| * !!! The same static buffer is used for subsequent calls. !!! |
| * This was done to aviod dynamic allocation for few calls. |
| * Actually we need this function only four times. |
| */ |
| static const char* __itt_get_env_var(const char* name) |
| { |
| #define MAX_ENV_VALUE_SIZE 4086 |
| static char env_buff[MAX_ENV_VALUE_SIZE]; |
| static char* env_value = (char*)env_buff; |
| |
| if (name != NULL) |
| { |
| #if ITT_PLATFORM==ITT_PLATFORM_WIN |
| size_t max_len = MAX_ENV_VALUE_SIZE - (size_t)(env_value - env_buff); |
| DWORD rc = GetEnvironmentVariableA(name, env_value, (DWORD)max_len); |
| if (rc >= max_len) |
| __itt_report_error(__itt_error_env_too_long, name, (size_t)rc - 1, (size_t)(max_len - 1)); |
| else if (rc > 0) |
| { |
| const char* ret = (const char*)env_value; |
| env_value += rc + 1; |
| return ret; |
| } |
| else |
| { |
| /* If environment variable is empty, GetEnvirornmentVariables() |
| * returns zero (number of characters (not including terminating null), |
| * and GetLastError() returns ERROR_SUCCESS. */ |
| DWORD err = GetLastError(); |
| if (err == ERROR_SUCCESS) |
| return env_value; |
| |
| if (err != ERROR_ENVVAR_NOT_FOUND) |
| __itt_report_error(__itt_error_cant_read_env, name, (int)err); |
| } |
| #else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */ |
| char* env = getenv(name); |
| if (env != NULL) |
| { |
| size_t len = strlen(env); |
| size_t max_len = MAX_ENV_VALUE_SIZE - (size_t)(env_value - env_buff); |
| if (len < max_len) |
| { |
| const char* ret = (const char*)env_value; |
| strncpy(env_value, env, len + 1); |
| env_value += len + 1; |
| return ret; |
| } else |
| __itt_report_error(__itt_error_env_too_long, name, (size_t)len, (size_t)(max_len - 1)); |
| } |
| #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ |
| } |
| return NULL; |
| } |
| |
| static const char* __itt_get_lib_name(void) |
| { |
| const char* lib_name = __itt_get_env_var(ITT_TO_STR(LIB_VAR_NAME)); |
| |
| #ifdef __ANDROID__ |
| if (lib_name == NULL) |
| { |
| const char* const system_wide_marker_filename = "/data/local/tmp/com.intel.itt.collector_lib"; |
| int itt_marker_file_fd = open(system_wide_marker_filename, O_RDONLY); |
| ssize_t res = 0; |
| |
| if (itt_marker_file_fd == -1) |
| { |
| const pid_t my_pid = getpid(); |
| char cmdline_path[PATH_MAX] = {0}; |
| char package_name[PATH_MAX] = {0}; |
| char app_sandbox_file[PATH_MAX] = {0}; |
| int cmdline_fd = 0; |
| |
| ITT_ANDROID_LOGI("Unable to open system-wide marker file."); |
| snprintf(cmdline_path, PATH_MAX - 1, "/proc/%d/cmdline", my_pid); |
| ITT_ANDROID_LOGI("CMD file: %s\n", cmdline_path); |
| cmdline_fd = open(cmdline_path, O_RDONLY); |
| if (cmdline_fd == -1) |
| { |
| ITT_ANDROID_LOGE("Unable to open %s file!", cmdline_path); |
| return lib_name; |
| } |
| res = read(cmdline_fd, package_name, PATH_MAX - 1); |
| if (res == -1) |
| { |
| ITT_ANDROID_LOGE("Unable to read %s file!", cmdline_path); |
| res = close(cmdline_fd); |
| if (res == -1) |
| { |
| ITT_ANDROID_LOGE("Unable to close %s file!", cmdline_path); |
| } |
| return lib_name; |
| } |
| res = close(cmdline_fd); |
| if (res == -1) |
| { |
| ITT_ANDROID_LOGE("Unable to close %s file!", cmdline_path); |
| return lib_name; |
| } |
| ITT_ANDROID_LOGI("Package name: %s\n", package_name); |
| snprintf(app_sandbox_file, PATH_MAX - 1, "/data/data/%s/com.intel.itt.collector_lib", package_name); |
| ITT_ANDROID_LOGI("Lib marker file name: %s\n", app_sandbox_file); |
| itt_marker_file_fd = open(app_sandbox_file, O_RDONLY); |
| if (itt_marker_file_fd == -1) |
| { |
| ITT_ANDROID_LOGE("Unable to open app marker file!"); |
| return lib_name; |
| } |
| } |
| |
| { |
| char itt_lib_name[PATH_MAX] = {0}; |
| |
| res = read(itt_marker_file_fd, itt_lib_name, PATH_MAX - 1); |
| if (res == -1) |
| { |
| ITT_ANDROID_LOGE("Unable to read %s file!", itt_marker_file_fd); |
| res = close(itt_marker_file_fd); |
| if (res == -1) |
| { |
| ITT_ANDROID_LOGE("Unable to close %s file!", itt_marker_file_fd); |
| } |
| return lib_name; |
| } |
| ITT_ANDROID_LOGI("ITT Lib path: %s", itt_lib_name); |
| res = close(itt_marker_file_fd); |
| if (res == -1) |
| { |
| ITT_ANDROID_LOGE("Unable to close %s file!", itt_marker_file_fd); |
| return lib_name; |
| } |
| ITT_ANDROID_LOGI("Set env"); |
| res = setenv(ITT_TO_STR(LIB_VAR_NAME), itt_lib_name, 0); |
| if (res == -1) |
| { |
| ITT_ANDROID_LOGE("Unable to set env var!"); |
| return lib_name; |
| } |
| lib_name = __itt_get_env_var(ITT_TO_STR(LIB_VAR_NAME)); |
| ITT_ANDROID_LOGI("ITT Lib path from env: %s", itt_lib_name); |
| } |
| } |
| #endif |
| |
| return lib_name; |
| } |
| |
| #ifndef min |
| #define min(a,b) (a) < (b) ? (a) : (b) |
| #endif /* min */ |
| |
| static __itt_group_id __itt_get_groups(void) |
| { |
| register int i; |
| __itt_group_id res = __itt_group_none; |
| const char* var_name = "INTEL_ITTNOTIFY_GROUPS"; |
| const char* group_str = __itt_get_env_var(var_name); |
| |
| if (group_str != NULL) |
| { |
| int len; |
| char gr[255]; |
| const char* chunk; |
| while ((group_str = __itt_fsplit(group_str, ",; ", &chunk, &len)) != NULL) |
| { |
| __itt_fstrcpyn(gr, chunk, sizeof(gr) - 1); |
| gr[min(len, (int)(sizeof(gr) - 1))] = 0; |
| |
| for (i = 0; group_list[i].name != NULL; i++) |
| { |
| if (!__itt_fstrcmp(gr, group_list[i].name)) |
| { |
| res = (__itt_group_id)(res | group_list[i].id); |
| break; |
| } |
| } |
| } |
| /* TODO: !!! Workaround for bug with warning for unknown group !!! |
| * Should be fixed in new initialization scheme. |
| * Now the following groups should be set always. */ |
| for (i = 0; group_list[i].id != __itt_group_none; i++) |
| if (group_list[i].id != __itt_group_all && |
| group_list[i].id > __itt_group_splitter_min && |
| group_list[i].id < __itt_group_splitter_max) |
| res = (__itt_group_id)(res | group_list[i].id); |
| return res; |
| } |
| else |
| { |
| for (i = 0; group_alias[i].env_var != NULL; i++) |
| if (__itt_get_env_var(group_alias[i].env_var) != NULL) |
| return group_alias[i].groups; |
| } |
| |
| return res; |
| } |
| |
| 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; |
| } |
| |
| /* It's not used right now! Comment it out to avoid warnings. |
| static void __itt_reinit_all_pointers(void) |
| { |
| register int i; |
| // Fill all pointers with initial stubs |
| for (i = 0; _N_(_ittapi_global).api_list_ptr[i].name != NULL; i++) |
| *_N_(_ittapi_global).api_list_ptr[i].func_ptr = _N_(_ittapi_global).api_list_ptr[i].init_func; |
| } |
| */ |
| |
| static void __itt_nullify_all_pointers(void) |
| { |
| register int i; |
| /* Nulify all pointers except domain_create and string_handle_create */ |
| for (i = 0; _N_(_ittapi_global).api_list_ptr[i].name != NULL; i++) |
| *_N_(_ittapi_global).api_list_ptr[i].func_ptr = _N_(_ittapi_global).api_list_ptr[i].null_func; |
| } |
| |
| #if ITT_PLATFORM==ITT_PLATFORM_WIN |
| #pragma warning(push) |
| #pragma warning(disable: 4054) /* warning C4054: 'type cast' : from function pointer 'XXX' to data pointer 'void *' */ |
| #pragma warning(disable: 4055) /* warning C4055: 'type cast' : from data pointer 'void *' to function pointer 'XXX' */ |
| #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ |
| |
| ITT_EXTERN_C void _N_(fini_ittlib)(void) |
| { |
| __itt_api_fini_t* __itt_api_fini_ptr; |
| static volatile TIDT current_thread = 0; |
| |
| if (_N_(_ittapi_global).api_initialized) |
| { |
| __itt_mutex_lock(&_N_(_ittapi_global).mutex); |
| if (_N_(_ittapi_global).api_initialized) |
| { |
| if (current_thread == 0) |
| { |
| current_thread = __itt_thread_id(); |
| __itt_api_fini_ptr = (__itt_api_fini_t*)(size_t)__itt_get_proc(_N_(_ittapi_global).lib, "__itt_api_fini"); |
| if (__itt_api_fini_ptr) |
| __itt_api_fini_ptr(&_N_(_ittapi_global)); |
| |
| __itt_nullify_all_pointers(); |
| |
| /* TODO: !!! not safe !!! don't support unload so far. |
| * if (_N_(_ittapi_global).lib != NULL) |
| * __itt_unload_lib(_N_(_ittapi_global).lib); |
| * _N_(_ittapi_global).lib = NULL; |
| */ |
| _N_(_ittapi_global).api_initialized = 0; |
| current_thread = 0; |
| } |
| } |
| __itt_mutex_unlock(&_N_(_ittapi_global).mutex); |
| } |
| } |
| |
| 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 (!_N_(_ittapi_global).api_initialized) |
| { |
| #ifndef ITT_SIMPLE_INIT |
| ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global)); |
| #endif /* ITT_SIMPLE_INIT */ |
| |
| if (!_N_(_ittapi_global).api_initialized) |
| { |
| if (current_thread == 0) |
| { |
| current_thread = __itt_thread_id(); |
| _N_(_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) |
| { |
| _N_(_ittapi_global).lib = __itt_load_lib((lib_name == NULL) ? ittnotify_lib_name : lib_name); |
| |
| if (_N_(_ittapi_global).lib != NULL) |
| { |
| __itt_api_init_t* __itt_api_init_ptr; |
| int lib_version = __itt_lib_version(_N_(_ittapi_global).lib); |
| |
| switch (lib_version) { |
| case 0: |
| groups = __itt_group_legacy; |
| case 1: |
| /* Fill all pointers from dynamic library */ |
| for (i = 0; _N_(_ittapi_global).api_list_ptr[i].name != NULL; i++) |
| { |
| if (_N_(_ittapi_global).api_list_ptr[i].group & groups & init_groups) |
| { |
| *_N_(_ittapi_global).api_list_ptr[i].func_ptr = (void*)__itt_get_proc(_N_(_ittapi_global).lib, _N_(_ittapi_global).api_list_ptr[i].name); |
| if (*_N_(_ittapi_global).api_list_ptr[i].func_ptr == NULL) |
| { |
| /* Restore pointers for function with static implementation */ |
| *_N_(_ittapi_global).api_list_ptr[i].func_ptr = _N_(_ittapi_global).api_list_ptr[i].null_func; |
| __itt_report_error(__itt_error_no_symbol, lib_name, _N_(_ittapi_global).api_list_ptr[i].name); |
| #ifdef ITT_COMPLETE_GROUP |
| zero_group = (__itt_group_id)(zero_group | _N_(_ittapi_global).api_list_ptr[i].group); |
| #endif /* ITT_COMPLETE_GROUP */ |
| } |
| } |
| else |
| *_N_(_ittapi_global).api_list_ptr[i].func_ptr = _N_(_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; _N_(_ittapi_global).api_list_ptr[i].name != NULL; i++) |
| if (_N_(_ittapi_global).api_list_ptr[i].group & zero_group) |
| *_N_(_ittapi_global).api_list_ptr[i].func_ptr = _N_(_ittapi_global).api_list_ptr[i].null_func; |
| #endif /* ITT_COMPLETE_GROUP */ |
| break; |
| case 2: |
| __itt_api_init_ptr = (__itt_api_init_t*)(size_t)__itt_get_proc(_N_(_ittapi_global).lib, "__itt_api_init"); |
| if (__itt_api_init_ptr) |
| __itt_api_init_ptr(&_N_(_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(); |
| } |
| _N_(_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(&_N_(_ittapi_global).mutex); |
| #endif /* ITT_SIMPLE_INIT */ |
| } |
| |
| /* Evaluating if any function ptr is non empty and it's in init_groups */ |
| for (i = 0; _N_(_ittapi_global).api_list_ptr[i].name != NULL; i++) |
| if (*_N_(_ittapi_global).api_list_ptr[i].func_ptr != _N_(_ittapi_global).api_list_ptr[i].null_func && |
| _N_(_ittapi_global).api_list_ptr[i].group & init_groups) |
| return 1; |
| return 0; |
| } |
| |
| ITT_EXTERN_C __itt_error_handler_t* _N_(set_error_handler)(__itt_error_handler_t* handler) |
| { |
| __itt_error_handler_t* prev = (__itt_error_handler_t*)(size_t)_N_(_ittapi_global).error_handler; |
| _N_(_ittapi_global).error_handler = (void*)(size_t)handler; |
| return prev; |
| } |
| |
| #if ITT_PLATFORM==ITT_PLATFORM_WIN |
| #pragma warning(pop) |
| #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ |
| |