1 2 //===----------------------------------------------------------------------===// 3 // 4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5 // See https://llvm.org/LICENSE.txt for license information. 6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "kmp_config.h" 11 #include "ittnotify_config.h" 12 13 #if ITT_PLATFORM==ITT_PLATFORM_WIN 14 #if defined(__MINGW32__) 15 #include <limits.h> 16 #else 17 #define PATH_MAX 512 18 #endif 19 #else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */ 20 #include <limits.h> 21 #include <dlfcn.h> 22 #include <errno.h> 23 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ 24 #include <stdio.h> 25 #include <stdlib.h> 26 #include <stdarg.h> 27 #include <string.h> 28 29 #define INTEL_NO_MACRO_BODY 30 #define INTEL_ITTNOTIFY_API_PRIVATE 31 #include "ittnotify.h" 32 #include "legacy/ittnotify.h" 33 34 #if KMP_MSVC_COMPAT 35 #include "disable_warnings.h" 36 #endif 37 38 static const char api_version[] = API_VERSION "\0\n@(#) $Revision: 481659 $\n"; 39 40 #define _N_(n) ITT_JOIN(INTEL_ITTNOTIFY_PREFIX,n) 41 42 #if ITT_OS==ITT_OS_WIN 43 static const char* ittnotify_lib_name = "libittnotify.dll"; 44 #elif ITT_OS==ITT_OS_LINUX || ITT_OS==ITT_OS_FREEBSD 45 static const char* ittnotify_lib_name = "libittnotify.so"; 46 #elif ITT_OS==ITT_OS_MAC 47 static const char* ittnotify_lib_name = "libittnotify.dylib"; 48 #else 49 #error Unsupported or unknown OS. 50 #endif 51 52 #ifdef __ANDROID__ 53 #include <android/log.h> 54 #include <stdio.h> 55 #include <unistd.h> 56 #include <sys/types.h> 57 #include <sys/stat.h> 58 #include <fcntl.h> 59 #include <linux/limits.h> 60 61 #ifdef ITT_ANDROID_LOG 62 #define ITT_ANDROID_LOG_TAG "INTEL_VTUNE_USERAPI" 63 #define ITT_ANDROID_LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, ITT_ANDROID_LOG_TAG, __VA_ARGS__)) 64 #define ITT_ANDROID_LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, ITT_ANDROID_LOG_TAG, __VA_ARGS__)) 65 #define ITT_ANDROID_LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR,ITT_ANDROID_LOG_TAG, __VA_ARGS__)) 66 #define ITT_ANDROID_LOGD(...) ((void)__android_log_print(ANDROID_LOG_DEBUG,ITT_ANDROID_LOG_TAG, __VA_ARGS__)) 67 #else 68 #define ITT_ANDROID_LOGI(...) 69 #define ITT_ANDROID_LOGW(...) 70 #define ITT_ANDROID_LOGE(...) 71 #define ITT_ANDROID_LOGD(...) 72 #endif 73 74 /* default location of userapi collector on Android */ 75 #define ANDROID_ITTNOTIFY_DEFAULT_PATH_MASK(x) "/data/data/com.intel.vtune/perfrun/lib" \ 76 #x "/runtime/libittnotify.so" 77 78 #if ITT_ARCH==ITT_ARCH_IA32 || ITT_ARCH==ITT_ARCH_ARM 79 #define ANDROID_ITTNOTIFY_DEFAULT_PATH ANDROID_ITTNOTIFY_DEFAULT_PATH_MASK(32) 80 #else 81 #define ANDROID_ITTNOTIFY_DEFAULT_PATH ANDROID_ITTNOTIFY_DEFAULT_PATH_MASK(64) 82 #endif 83 84 #endif 85 86 #ifndef PATH_MAX 87 #define PATH_MAX 4096 88 #endif 89 90 91 #ifndef LIB_VAR_NAME 92 #if ITT_ARCH==ITT_ARCH_IA32 || ITT_ARCH==ITT_ARCH_ARM || ITT_ARCH==ITT_ARCH_MIPS 93 #define LIB_VAR_NAME INTEL_LIBITTNOTIFY32 94 #else 95 #define LIB_VAR_NAME INTEL_LIBITTNOTIFY64 96 #endif 97 #endif /* LIB_VAR_NAME */ 98 99 #define ITT_MUTEX_INIT_AND_LOCK(p) { \ 100 if (PTHREAD_SYMBOLS) \ 101 { \ 102 if (!p.mutex_initialized) \ 103 { \ 104 if (__itt_interlocked_increment(&p.atomic_counter) == 1) \ 105 { \ 106 __itt_mutex_init(&p.mutex); \ 107 p.mutex_initialized = 1; \ 108 } \ 109 else \ 110 while (!p.mutex_initialized) \ 111 __itt_thread_yield(); \ 112 } \ 113 __itt_mutex_lock(&p.mutex); \ 114 } \ 115 } 116 117 typedef int (__itt_init_ittlib_t)(const char*, __itt_group_id); 118 119 /* this define used to control initialization function name. */ 120 #ifndef __itt_init_ittlib_name 121 ITT_EXTERN_C int _N_(init_ittlib)(const char*, __itt_group_id); 122 static __itt_init_ittlib_t* __itt_init_ittlib_ptr = _N_(init_ittlib); 123 #define __itt_init_ittlib_name __itt_init_ittlib_ptr 124 #endif /* __itt_init_ittlib_name */ 125 126 typedef void (__itt_fini_ittlib_t)(void); 127 128 /* this define used to control finalization function name. */ 129 #ifndef __itt_fini_ittlib_name 130 ITT_EXTERN_C void _N_(fini_ittlib)(void); 131 static __itt_fini_ittlib_t* __itt_fini_ittlib_ptr = _N_(fini_ittlib); 132 #define __itt_fini_ittlib_name __itt_fini_ittlib_ptr 133 #endif /* __itt_fini_ittlib_name */ 134 135 /* building pointers to imported funcs */ 136 #undef ITT_STUBV 137 #undef ITT_STUB 138 #define ITT_STUB(api,type,name,args,params,ptr,group,format) \ 139 static type api ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init)) args;\ 140 typedef type api ITT_JOIN(_N_(name),_t) args; \ 141 ITT_EXTERN_C_BEGIN ITT_JOIN(_N_(name),_t)* ITTNOTIFY_NAME(name) = ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init)); ITT_EXTERN_C_END \ 142 static type api ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init)) args \ 143 { \ 144 __itt_init_ittlib_name(NULL, __itt_group_all); \ 145 if (ITTNOTIFY_NAME(name) && ITTNOTIFY_NAME(name) != ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init))) \ 146 return ITTNOTIFY_NAME(name) params; \ 147 else \ 148 return (type)0; \ 149 } 150 151 #define ITT_STUBV(api,type,name,args,params,ptr,group,format) \ 152 static type api ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init)) args;\ 153 typedef type api ITT_JOIN(_N_(name),_t) args; \ 154 ITT_EXTERN_C_BEGIN ITT_JOIN(_N_(name),_t)* ITTNOTIFY_NAME(name) = ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init)); ITT_EXTERN_C_END \ 155 static type api ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init)) args \ 156 { \ 157 __itt_init_ittlib_name(NULL, __itt_group_all); \ 158 if (ITTNOTIFY_NAME(name) && ITTNOTIFY_NAME(name) != ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init))) \ 159 ITTNOTIFY_NAME(name) params; \ 160 else \ 161 return; \ 162 } 163 164 #undef __ITT_INTERNAL_INIT 165 #include "ittnotify_static.h" 166 167 #undef ITT_STUB 168 #undef ITT_STUBV 169 #define ITT_STUB(api,type,name,args,params,ptr,group,format) \ 170 static type api ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init)) args;\ 171 typedef type api ITT_JOIN(_N_(name),_t) args; \ 172 ITT_EXTERN_C_BEGIN ITT_JOIN(_N_(name),_t)* ITTNOTIFY_NAME(name) = ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init)); ITT_EXTERN_C_END 173 174 #define ITT_STUBV(api,type,name,args,params,ptr,group,format) \ 175 static type api ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init)) args;\ 176 typedef type api ITT_JOIN(_N_(name),_t) args; \ 177 ITT_EXTERN_C_BEGIN ITT_JOIN(_N_(name),_t)* ITTNOTIFY_NAME(name) = ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init)); ITT_EXTERN_C_END 178 179 #define __ITT_INTERNAL_INIT 180 #include "ittnotify_static.h" 181 #undef __ITT_INTERNAL_INIT 182 183 ITT_GROUP_LIST(group_list); 184 185 #pragma pack(push, 8) 186 187 typedef struct ___itt_group_alias 188 { 189 const char* env_var; 190 __itt_group_id groups; 191 } __itt_group_alias; 192 193 static __itt_group_alias group_alias[] = { 194 { "KMP_FOR_TPROFILE", (__itt_group_id)(__itt_group_control | __itt_group_thread | __itt_group_sync | __itt_group_mark) }, 195 { "KMP_FOR_TCHECK", (__itt_group_id)(__itt_group_control | __itt_group_thread | __itt_group_sync | __itt_group_fsync | __itt_group_mark | __itt_group_suppress) }, 196 { NULL, (__itt_group_none) }, 197 { api_version, (__itt_group_none) } /* !!! Just to avoid unused code elimination !!! */ 198 }; 199 200 #pragma pack(pop) 201 202 #if ITT_PLATFORM==ITT_PLATFORM_WIN && KMP_MSVC_COMPAT 203 #pragma warning(push) 204 #pragma warning(disable: 4054) /* warning C4054: 'type cast' : from function pointer 'XXX' to data pointer 'void *' */ 205 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ 206 207 static __itt_api_info api_list[] = { 208 /* Define functions with static implementation */ 209 #undef ITT_STUB 210 #undef ITT_STUBV 211 #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)}, 212 #define ITT_STUBV ITT_STUB 213 #define __ITT_INTERNAL_INIT 214 #include "ittnotify_static.h" 215 #undef __ITT_INTERNAL_INIT 216 /* Define functions without static implementation */ 217 #undef ITT_STUB 218 #undef ITT_STUBV 219 #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)}, 220 #define ITT_STUBV ITT_STUB 221 #include "ittnotify_static.h" 222 {NULL, NULL, NULL, NULL, __itt_group_none} 223 }; 224 225 #if ITT_PLATFORM==ITT_PLATFORM_WIN && KMP_MSVC_COMPAT 226 #pragma warning(pop) 227 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ 228 229 /* static part descriptor which handles. all notification api attributes. */ 230 __itt_global _N_(_ittapi_global) = { 231 ITT_MAGIC, /* identification info */ 232 ITT_MAJOR, ITT_MINOR, API_VERSION_BUILD, /* version info */ 233 0, /* api_initialized */ 234 0, /* mutex_initialized */ 235 0, /* atomic_counter */ 236 MUTEX_INITIALIZER, /* mutex */ 237 NULL, /* dynamic library handle */ 238 NULL, /* error_handler */ 239 NULL, /* dll_path_ptr */ 240 (__itt_api_info*)&api_list, /* api_list_ptr */ 241 NULL, /* next __itt_global */ 242 NULL, /* thread_list */ 243 NULL, /* domain_list */ 244 NULL, /* string_list */ 245 __itt_collection_normal, /* collection state */ 246 NULL /* counter_list */ 247 }; 248 249 typedef void (__itt_api_init_t)(__itt_global*, __itt_group_id); 250 typedef void (__itt_api_fini_t)(__itt_global*); 251 252 /* ========================================================================= */ 253 254 #ifdef ITT_NOTIFY_EXT_REPORT 255 ITT_EXTERN_C void _N_(error_handler)(__itt_error_code, va_list args); 256 #endif /* ITT_NOTIFY_EXT_REPORT */ 257 258 #if ITT_PLATFORM==ITT_PLATFORM_WIN && KMP_MSVC_COMPAT 259 #pragma warning(push) 260 #pragma warning(disable: 4055) /* warning C4055: 'type cast' : from data pointer 'void *' to function pointer 'XXX' */ 261 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ 262 263 static void __itt_report_error(unsigned code_arg, ...) 264 { 265 va_list args; 266 va_start(args, code_arg); 267 268 // We use unsigned for the code argument and explicitly cast it here to the 269 // right enumerator because variadic functions are not compatible with 270 // default promotions. 271 __itt_error_code code = (__itt_error_code)code_arg; 272 273 if (_N_(_ittapi_global).error_handler != NULL) 274 { 275 __itt_error_handler_t* handler = (__itt_error_handler_t*)(size_t)_N_(_ittapi_global).error_handler; 276 handler(code, args); 277 } 278 #ifdef ITT_NOTIFY_EXT_REPORT 279 _N_(error_handler)(code, args); 280 #endif /* ITT_NOTIFY_EXT_REPORT */ 281 va_end(args); 282 } 283 284 #if ITT_PLATFORM==ITT_PLATFORM_WIN && KMP_MSVC_COMPAT 285 #pragma warning(pop) 286 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ 287 288 #if ITT_PLATFORM==ITT_PLATFORM_WIN 289 static __itt_domain* ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(domain_createW),_init))(const wchar_t* name) 290 { 291 __itt_domain *h_tail = NULL, *h = NULL; 292 293 if (name == NULL) 294 { 295 return NULL; 296 } 297 298 ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global)); 299 if (_N_(_ittapi_global).api_initialized) 300 { 301 if (ITTNOTIFY_NAME(domain_createW) && ITTNOTIFY_NAME(domain_createW) != ITT_VERSIONIZE(ITT_JOIN(_N_(domain_createW),_init))) 302 { 303 __itt_mutex_unlock(&_N_(_ittapi_global).mutex); 304 return ITTNOTIFY_NAME(domain_createW)(name); 305 } 306 } 307 for (h_tail = NULL, h = _N_(_ittapi_global).domain_list; h != NULL; h_tail = h, h = h->next) 308 { 309 if (h->nameW != NULL && !wcscmp(h->nameW, name)) break; 310 } 311 if (h == NULL) 312 { 313 NEW_DOMAIN_W(&_N_(_ittapi_global),h,h_tail,name); 314 } 315 if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex); 316 return h; 317 } 318 319 static __itt_domain* ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(domain_createA),_init))(const char* name) 320 #else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */ 321 static __itt_domain* ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(domain_create),_init))(const char* name) 322 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ 323 { 324 __itt_domain *h_tail = NULL, *h = NULL; 325 326 if (name == NULL) 327 { 328 return NULL; 329 } 330 331 ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global)); 332 if (_N_(_ittapi_global).api_initialized) 333 { 334 #if ITT_PLATFORM==ITT_PLATFORM_WIN 335 if (ITTNOTIFY_NAME(domain_createA) && ITTNOTIFY_NAME(domain_createA) != ITT_VERSIONIZE(ITT_JOIN(_N_(domain_createA),_init))) 336 { 337 __itt_mutex_unlock(&_N_(_ittapi_global).mutex); 338 return ITTNOTIFY_NAME(domain_createA)(name); 339 } 340 #else 341 if (ITTNOTIFY_NAME(domain_create) && ITTNOTIFY_NAME(domain_create) != ITT_VERSIONIZE(ITT_JOIN(_N_(domain_create),_init))) 342 { 343 if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex); 344 return ITTNOTIFY_NAME(domain_create)(name); 345 } 346 #endif 347 } 348 for (h_tail = NULL, h = _N_(_ittapi_global).domain_list; h != NULL; h_tail = h, h = h->next) 349 { 350 if (h->nameA != NULL && !__itt_fstrcmp(h->nameA, name)) break; 351 } 352 if (h == NULL) 353 { 354 NEW_DOMAIN_A(&_N_(_ittapi_global),h,h_tail,name); 355 } 356 if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex); 357 return h; 358 } 359 360 #if ITT_PLATFORM==ITT_PLATFORM_WIN 361 static __itt_string_handle* ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(string_handle_createW),_init))(const wchar_t* name) 362 { 363 __itt_string_handle *h_tail = NULL, *h = NULL; 364 365 if (name == NULL) 366 { 367 return NULL; 368 } 369 370 ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global)); 371 if (_N_(_ittapi_global).api_initialized) 372 { 373 if (ITTNOTIFY_NAME(string_handle_createW) && ITTNOTIFY_NAME(string_handle_createW) != ITT_VERSIONIZE(ITT_JOIN(_N_(string_handle_createW),_init))) 374 { 375 __itt_mutex_unlock(&_N_(_ittapi_global).mutex); 376 return ITTNOTIFY_NAME(string_handle_createW)(name); 377 } 378 } 379 for (h_tail = NULL, h = _N_(_ittapi_global).string_list; h != NULL; h_tail = h, h = h->next) 380 { 381 if (h->strW != NULL && !wcscmp(h->strW, name)) break; 382 } 383 if (h == NULL) 384 { 385 NEW_STRING_HANDLE_W(&_N_(_ittapi_global),h,h_tail,name); 386 } 387 __itt_mutex_unlock(&_N_(_ittapi_global).mutex); 388 return h; 389 } 390 391 static __itt_string_handle* ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(string_handle_createA),_init))(const char* name) 392 #else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */ 393 static __itt_string_handle* ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(string_handle_create),_init))(const char* name) 394 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ 395 { 396 __itt_string_handle *h_tail = NULL, *h = NULL; 397 398 if (name == NULL) 399 { 400 return NULL; 401 } 402 403 ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global)); 404 if (_N_(_ittapi_global).api_initialized) 405 { 406 #if ITT_PLATFORM==ITT_PLATFORM_WIN 407 if (ITTNOTIFY_NAME(string_handle_createA) && ITTNOTIFY_NAME(string_handle_createA) != ITT_VERSIONIZE(ITT_JOIN(_N_(string_handle_createA),_init))) 408 { 409 __itt_mutex_unlock(&_N_(_ittapi_global).mutex); 410 return ITTNOTIFY_NAME(string_handle_createA)(name); 411 } 412 #else 413 if (ITTNOTIFY_NAME(string_handle_create) && ITTNOTIFY_NAME(string_handle_create) != ITT_VERSIONIZE(ITT_JOIN(_N_(string_handle_create),_init))) 414 { 415 if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex); 416 return ITTNOTIFY_NAME(string_handle_create)(name); 417 } 418 #endif 419 } 420 for (h_tail = NULL, h = _N_(_ittapi_global).string_list; h != NULL; h_tail = h, h = h->next) 421 { 422 if (h->strA != NULL && !__itt_fstrcmp(h->strA, name)) break; 423 } 424 if (h == NULL) 425 { 426 NEW_STRING_HANDLE_A(&_N_(_ittapi_global),h,h_tail,name); 427 } 428 if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex); 429 return h; 430 } 431 432 #if ITT_PLATFORM==ITT_PLATFORM_WIN 433 static __itt_counter ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(counter_createW),_init))(const wchar_t *name, const wchar_t *domain) 434 { 435 __itt_counter_info_t *h_tail = NULL, *h = NULL; 436 __itt_metadata_type type = __itt_metadata_u64; 437 438 if (name == NULL) 439 { 440 return NULL; 441 } 442 443 ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global)); 444 if (_N_(_ittapi_global).api_initialized) 445 { 446 if (ITTNOTIFY_NAME(counter_createW) && ITTNOTIFY_NAME(counter_createW) != ITT_VERSIONIZE(ITT_JOIN(_N_(counter_createW),_init))) 447 { 448 __itt_mutex_unlock(&_N_(_ittapi_global).mutex); 449 return ITTNOTIFY_NAME(counter_createW)(name, domain); 450 } 451 } 452 for (h_tail = NULL, h = _N_(_ittapi_global).counter_list; h != NULL; h_tail = h, h = h->next) 453 { 454 if (h->nameW != NULL && h->type == type && !wcscmp(h->nameW, name) && ((h->domainW == NULL && domain == NULL) || 455 (h->domainW != NULL && domain != NULL && !wcscmp(h->domainW, domain)))) break; 456 457 } 458 if (h == NULL) 459 { 460 NEW_COUNTER_W(&_N_(_ittapi_global),h,h_tail,name,domain,type); 461 } 462 __itt_mutex_unlock(&_N_(_ittapi_global).mutex); 463 return (__itt_counter)h; 464 } 465 466 static __itt_counter ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(counter_createA),_init))(const char *name, const char *domain) 467 #else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */ 468 static __itt_counter ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(counter_create),_init))(const char *name, const char *domain) 469 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ 470 { 471 __itt_counter_info_t *h_tail = NULL, *h = NULL; 472 __itt_metadata_type type = __itt_metadata_u64; 473 474 if (name == NULL) 475 { 476 return NULL; 477 } 478 479 ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global)); 480 if (_N_(_ittapi_global).api_initialized) 481 { 482 #if ITT_PLATFORM==ITT_PLATFORM_WIN 483 if (ITTNOTIFY_NAME(counter_createA) && ITTNOTIFY_NAME(counter_createA) != ITT_VERSIONIZE(ITT_JOIN(_N_(counter_createA),_init))) 484 { 485 __itt_mutex_unlock(&_N_(_ittapi_global).mutex); 486 return ITTNOTIFY_NAME(counter_createA)(name, domain); 487 } 488 #else 489 if (ITTNOTIFY_NAME(counter_create) && ITTNOTIFY_NAME(counter_create) != ITT_VERSIONIZE(ITT_JOIN(_N_(counter_create),_init))) 490 { 491 if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex); 492 return ITTNOTIFY_NAME(counter_create)(name, domain); 493 } 494 #endif 495 } 496 for (h_tail = NULL, h = _N_(_ittapi_global).counter_list; h != NULL; h_tail = h, h = h->next) 497 { 498 if (h->nameA != NULL && h->type == type && !__itt_fstrcmp(h->nameA, name) && ((h->domainA == NULL && domain == NULL) || 499 (h->domainA != NULL && domain != NULL && !__itt_fstrcmp(h->domainA, domain)))) break; 500 } 501 if (h == NULL) 502 { 503 NEW_COUNTER_A(&_N_(_ittapi_global),h,h_tail,name,domain,type); 504 } 505 if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex); 506 return (__itt_counter)h; 507 } 508 509 #if ITT_PLATFORM==ITT_PLATFORM_WIN 510 static __itt_counter ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(counter_create_typedW),_init))(const wchar_t *name, const wchar_t *domain, __itt_metadata_type type) 511 { 512 __itt_counter_info_t *h_tail = NULL, *h = NULL; 513 514 if (name == NULL) 515 { 516 return NULL; 517 } 518 519 ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global)); 520 if (_N_(_ittapi_global).api_initialized) 521 { 522 if (ITTNOTIFY_NAME(counter_create_typedW) && ITTNOTIFY_NAME(counter_create_typedW) != ITT_VERSIONIZE(ITT_JOIN(_N_(counter_create_typedW),_init))) 523 { 524 __itt_mutex_unlock(&_N_(_ittapi_global).mutex); 525 return ITTNOTIFY_NAME(counter_create_typedW)(name, domain, type); 526 } 527 } 528 for (h_tail = NULL, h = _N_(_ittapi_global).counter_list; h != NULL; h_tail = h, h = h->next) 529 { 530 if (h->nameW != NULL && h->type == type && !wcscmp(h->nameW, name) && ((h->domainW == NULL && domain == NULL) || 531 (h->domainW != NULL && domain != NULL && !wcscmp(h->domainW, domain)))) break; 532 533 } 534 if (h == NULL) 535 { 536 NEW_COUNTER_W(&_N_(_ittapi_global),h,h_tail,name,domain,type); 537 } 538 __itt_mutex_unlock(&_N_(_ittapi_global).mutex); 539 return (__itt_counter)h; 540 } 541 542 static __itt_counter ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(counter_create_typedA),_init))(const char *name, const char *domain, __itt_metadata_type type) 543 #else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */ 544 static __itt_counter ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(counter_create_typed),_init))(const char *name, const char *domain, __itt_metadata_type type) 545 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ 546 { 547 __itt_counter_info_t *h_tail = NULL, *h = NULL; 548 549 if (name == NULL) 550 { 551 return NULL; 552 } 553 554 ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global)); 555 if (_N_(_ittapi_global).api_initialized) 556 { 557 #if ITT_PLATFORM==ITT_PLATFORM_WIN 558 if (ITTNOTIFY_NAME(counter_create_typedA) && ITTNOTIFY_NAME(counter_create_typedA) != ITT_VERSIONIZE(ITT_JOIN(_N_(counter_create_typedA),_init))) 559 { 560 __itt_mutex_unlock(&_N_(_ittapi_global).mutex); 561 return ITTNOTIFY_NAME(counter_create_typedA)(name, domain, type); 562 } 563 #else 564 if (ITTNOTIFY_NAME(counter_create_typed) && ITTNOTIFY_NAME(counter_create_typed) != ITT_VERSIONIZE(ITT_JOIN(_N_(counter_create_typed),_init))) 565 { 566 if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex); 567 return ITTNOTIFY_NAME(counter_create_typed)(name, domain, type); 568 } 569 #endif 570 } 571 for (h_tail = NULL, h = _N_(_ittapi_global).counter_list; h != NULL; h_tail = h, h = h->next) 572 { 573 if (h->nameA != NULL && h->type == type && !__itt_fstrcmp(h->nameA, name) && ((h->domainA == NULL && domain == NULL) || 574 (h->domainA != NULL && domain != NULL && !__itt_fstrcmp(h->domainA, domain)))) break; 575 } 576 if (h == NULL) 577 { 578 NEW_COUNTER_A(&_N_(_ittapi_global),h,h_tail,name,domain,type); 579 } 580 if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex); 581 return (__itt_counter)h; 582 } 583 584 /* -------------------------------------------------------------------------- */ 585 586 static void ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(pause),_init))(void) 587 { 588 if (!_N_(_ittapi_global).api_initialized && _N_(_ittapi_global).thread_list == NULL) 589 { 590 __itt_init_ittlib_name(NULL, __itt_group_all); 591 } 592 if (ITTNOTIFY_NAME(pause) && ITTNOTIFY_NAME(pause) != ITT_VERSIONIZE(ITT_JOIN(_N_(pause),_init))) 593 { 594 ITTNOTIFY_NAME(pause)(); 595 } 596 else 597 { 598 _N_(_ittapi_global).state = __itt_collection_paused; 599 } 600 } 601 602 static void ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(resume),_init))(void) 603 { 604 if (!_N_(_ittapi_global).api_initialized && _N_(_ittapi_global).thread_list == NULL) 605 { 606 __itt_init_ittlib_name(NULL, __itt_group_all); 607 } 608 if (ITTNOTIFY_NAME(resume) && ITTNOTIFY_NAME(resume) != ITT_VERSIONIZE(ITT_JOIN(_N_(resume),_init))) 609 { 610 ITTNOTIFY_NAME(resume)(); 611 } 612 else 613 { 614 _N_(_ittapi_global).state = __itt_collection_normal; 615 } 616 } 617 618 #if ITT_PLATFORM==ITT_PLATFORM_WIN 619 static void ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_nameW),_init))(const wchar_t* name) 620 { 621 if (!_N_(_ittapi_global).api_initialized && _N_(_ittapi_global).thread_list == NULL) 622 { 623 __itt_init_ittlib_name(NULL, __itt_group_all); 624 } 625 if (ITTNOTIFY_NAME(thread_set_nameW) && ITTNOTIFY_NAME(thread_set_nameW) != ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_nameW),_init))) 626 { 627 ITTNOTIFY_NAME(thread_set_nameW)(name); 628 } 629 } 630 631 static int ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(thr_name_setW),_init))(const wchar_t* name, int namelen) 632 { 633 (void)namelen; 634 ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_nameW),_init))(name); 635 return 0; 636 } 637 638 static void ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_nameA),_init))(const char* name) 639 #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ 640 static void ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_name),_init))(const char* name) 641 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ 642 { 643 if (!_N_(_ittapi_global).api_initialized && _N_(_ittapi_global).thread_list == NULL) 644 { 645 __itt_init_ittlib_name(NULL, __itt_group_all); 646 } 647 #if ITT_PLATFORM==ITT_PLATFORM_WIN 648 if (ITTNOTIFY_NAME(thread_set_nameA) && ITTNOTIFY_NAME(thread_set_nameA) != ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_nameA),_init))) 649 { 650 ITTNOTIFY_NAME(thread_set_nameA)(name); 651 } 652 #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ 653 if (ITTNOTIFY_NAME(thread_set_name) && ITTNOTIFY_NAME(thread_set_name) != ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_name),_init))) 654 { 655 ITTNOTIFY_NAME(thread_set_name)(name); 656 } 657 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ 658 } 659 660 #if ITT_PLATFORM==ITT_PLATFORM_WIN 661 static int ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(thr_name_setA),_init))(const char* name, int namelen) 662 { 663 (void)namelen; 664 ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_nameA),_init))(name); 665 return 0; 666 } 667 #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ 668 static int ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(thr_name_set),_init))(const char* name, int namelen) 669 { 670 (void)namelen; 671 ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_name),_init))(name); 672 return 0; 673 } 674 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ 675 676 static void ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(thread_ignore),_init))(void) 677 { 678 if (!_N_(_ittapi_global).api_initialized && _N_(_ittapi_global).thread_list == NULL) 679 { 680 __itt_init_ittlib_name(NULL, __itt_group_all); 681 } 682 if (ITTNOTIFY_NAME(thread_ignore) && ITTNOTIFY_NAME(thread_ignore) != ITT_VERSIONIZE(ITT_JOIN(_N_(thread_ignore),_init))) 683 { 684 ITTNOTIFY_NAME(thread_ignore)(); 685 } 686 } 687 688 static void ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(thr_ignore),_init))(void) 689 { 690 ITT_VERSIONIZE(ITT_JOIN(_N_(thread_ignore),_init))(); 691 } 692 693 static void ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(enable_attach),_init))(void) 694 { 695 #ifdef __ANDROID__ 696 /* 697 * if LIB_VAR_NAME env variable were set before then stay previous value 698 * else set default path 699 */ 700 setenv(ITT_TO_STR(LIB_VAR_NAME), ANDROID_ITTNOTIFY_DEFAULT_PATH, 0); 701 #endif 702 } 703 704 /* -------------------------------------------------------------------------- */ 705 706 static const char* __itt_fsplit(const char* s, const char* sep, const char** out, int* len) 707 { 708 int i; 709 int j; 710 711 if (!s || !sep || !out || !len) 712 return NULL; 713 714 for (i = 0; s[i]; i++) 715 { 716 int b = 0; 717 for (j = 0; sep[j]; j++) 718 if (s[i] == sep[j]) 719 { 720 b = 1; 721 break; 722 } 723 if (!b) 724 break; 725 } 726 727 if (!s[i]) 728 return NULL; 729 730 *len = 0; 731 *out = &s[i]; 732 733 for (; s[i]; i++, (*len)++) 734 { 735 int b = 0; 736 for (j = 0; sep[j]; j++) 737 if (s[i] == sep[j]) 738 { 739 b = 1; 740 break; 741 } 742 if (b) 743 break; 744 } 745 746 for (; s[i]; i++) 747 { 748 int b = 0; 749 for (j = 0; sep[j]; j++) 750 if (s[i] == sep[j]) 751 { 752 b = 1; 753 break; 754 } 755 if (!b) 756 break; 757 } 758 759 return &s[i]; 760 } 761 762 /* This function return value of env variable that placed into static buffer. 763 * !!! The same static buffer is used for subsequent calls. !!! 764 * This was done to aviod dynamic allocation for few calls. 765 * Actually we need this function only four times. 766 */ 767 static const char* __itt_get_env_var(const char* name) 768 { 769 #define MAX_ENV_VALUE_SIZE 4086 770 static char env_buff[MAX_ENV_VALUE_SIZE]; 771 static char* env_value = (char*)env_buff; 772 773 if (name != NULL) 774 { 775 #if ITT_PLATFORM==ITT_PLATFORM_WIN 776 size_t max_len = MAX_ENV_VALUE_SIZE - (size_t)(env_value - env_buff); 777 DWORD rc = GetEnvironmentVariableA(name, env_value, (DWORD)max_len); 778 if (rc >= max_len) 779 __itt_report_error(__itt_error_env_too_long, name, (size_t)rc - 1, (size_t)(max_len - 1)); 780 else if (rc > 0) 781 { 782 const char* ret = (const char*)env_value; 783 env_value += rc + 1; 784 return ret; 785 } 786 else 787 { 788 /* If environment variable is empty, GetEnvirornmentVariables() 789 * returns zero (number of characters (not including terminating null), 790 * and GetLastError() returns ERROR_SUCCESS. */ 791 DWORD err = GetLastError(); 792 if (err == ERROR_SUCCESS) 793 return env_value; 794 795 if (err != ERROR_ENVVAR_NOT_FOUND) 796 __itt_report_error(__itt_error_cant_read_env, name, (int)err); 797 } 798 #else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */ 799 char* env = getenv(name); 800 if (env != NULL) 801 { 802 size_t len = __itt_fstrnlen(env, MAX_ENV_VALUE_SIZE); 803 size_t max_len = MAX_ENV_VALUE_SIZE - (size_t)(env_value - env_buff); 804 if (len < max_len) 805 { 806 const char* ret = (const char*)env_value; 807 __itt_fstrcpyn(env_value, max_len, env, len + 1); 808 env_value += len + 1; 809 return ret; 810 } else 811 __itt_report_error(__itt_error_env_too_long, name, (size_t)len, (size_t)(max_len - 1)); 812 } 813 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ 814 } 815 return NULL; 816 } 817 818 static const char* __itt_get_lib_name(void) 819 { 820 const char* lib_name = __itt_get_env_var(ITT_TO_STR(LIB_VAR_NAME)); 821 822 #ifdef __ANDROID__ 823 if (lib_name == NULL) 824 { 825 826 #if ITT_ARCH==ITT_ARCH_IA32 || ITT_ARCH==ITT_ARCH_ARM 827 const char* const marker_filename = "com.intel.itt.collector_lib_32"; 828 #else 829 const char* const marker_filename = "com.intel.itt.collector_lib_64"; 830 #endif 831 832 char system_wide_marker_filename[PATH_MAX] = {0}; 833 int itt_marker_file_fd = -1; 834 ssize_t res = 0; 835 836 res = snprintf(system_wide_marker_filename, PATH_MAX - 1, "%s%s", "/data/local/tmp/", marker_filename); 837 if (res < 0) 838 { 839 ITT_ANDROID_LOGE("Unable to concatenate marker file string."); 840 return lib_name; 841 } 842 itt_marker_file_fd = open(system_wide_marker_filename, O_RDONLY); 843 844 if (itt_marker_file_fd == -1) 845 { 846 const pid_t my_pid = getpid(); 847 char cmdline_path[PATH_MAX] = {0}; 848 char package_name[PATH_MAX] = {0}; 849 char app_sandbox_file[PATH_MAX] = {0}; 850 int cmdline_fd = 0; 851 852 ITT_ANDROID_LOGI("Unable to open system-wide marker file."); 853 res = snprintf(cmdline_path, PATH_MAX - 1, "/proc/%d/cmdline", my_pid); 854 if (res < 0) 855 { 856 ITT_ANDROID_LOGE("Unable to get cmdline path string."); 857 return lib_name; 858 } 859 860 ITT_ANDROID_LOGI("CMD file: %s\n", cmdline_path); 861 cmdline_fd = open(cmdline_path, O_RDONLY); 862 if (cmdline_fd == -1) 863 { 864 ITT_ANDROID_LOGE("Unable to open %s file!", cmdline_path); 865 return lib_name; 866 } 867 res = read(cmdline_fd, package_name, PATH_MAX - 1); 868 if (res == -1) 869 { 870 ITT_ANDROID_LOGE("Unable to read %s file!", cmdline_path); 871 res = close(cmdline_fd); 872 if (res == -1) 873 { 874 ITT_ANDROID_LOGE("Unable to close %s file!", cmdline_path); 875 } 876 return lib_name; 877 } 878 res = close(cmdline_fd); 879 if (res == -1) 880 { 881 ITT_ANDROID_LOGE("Unable to close %s file!", cmdline_path); 882 return lib_name; 883 } 884 ITT_ANDROID_LOGI("Package name: %s\n", package_name); 885 res = snprintf(app_sandbox_file, PATH_MAX - 1, "/data/data/%s/%s", package_name, marker_filename); 886 if (res < 0) 887 { 888 ITT_ANDROID_LOGE("Unable to concatenate marker file string."); 889 return lib_name; 890 } 891 892 ITT_ANDROID_LOGI("Lib marker file name: %s\n", app_sandbox_file); 893 itt_marker_file_fd = open(app_sandbox_file, O_RDONLY); 894 if (itt_marker_file_fd == -1) 895 { 896 ITT_ANDROID_LOGE("Unable to open app marker file!"); 897 return lib_name; 898 } 899 } 900 901 { 902 char itt_lib_name[PATH_MAX] = {0}; 903 904 res = read(itt_marker_file_fd, itt_lib_name, PATH_MAX - 1); 905 if (res == -1) 906 { 907 ITT_ANDROID_LOGE("Unable to read %s file!", itt_marker_file_fd); 908 res = close(itt_marker_file_fd); 909 if (res == -1) 910 { 911 ITT_ANDROID_LOGE("Unable to close %s file!", itt_marker_file_fd); 912 } 913 return lib_name; 914 } 915 ITT_ANDROID_LOGI("ITT Lib path: %s", itt_lib_name); 916 res = close(itt_marker_file_fd); 917 if (res == -1) 918 { 919 ITT_ANDROID_LOGE("Unable to close %s file!", itt_marker_file_fd); 920 return lib_name; 921 } 922 ITT_ANDROID_LOGI("Set env %s to %s", ITT_TO_STR(LIB_VAR_NAME), itt_lib_name); 923 res = setenv(ITT_TO_STR(LIB_VAR_NAME), itt_lib_name, 0); 924 if (res == -1) 925 { 926 ITT_ANDROID_LOGE("Unable to set env var!"); 927 return lib_name; 928 } 929 lib_name = __itt_get_env_var(ITT_TO_STR(LIB_VAR_NAME)); 930 ITT_ANDROID_LOGI("ITT Lib path from env: %s", lib_name); 931 } 932 } 933 #endif 934 935 return lib_name; 936 } 937 938 /* Avoid clashes with std::min, reported by tbb team */ 939 #define __itt_min(a,b) (a) < (b) ? (a) : (b) 940 941 static __itt_group_id __itt_get_groups(void) 942 { 943 int i; 944 __itt_group_id res = __itt_group_none; 945 const char* var_name = "INTEL_ITTNOTIFY_GROUPS"; 946 const char* group_str = __itt_get_env_var(var_name); 947 948 if (group_str != NULL) 949 { 950 int len; 951 char gr[255]; 952 const char* chunk; 953 while ((group_str = __itt_fsplit(group_str, ",; ", &chunk, &len)) != NULL) 954 { 955 int min_len = __itt_min(len, (int)(sizeof(gr) - 1)); 956 __itt_fstrcpyn(gr, sizeof(gr) - 1, chunk, min_len); 957 gr[min_len] = 0; 958 959 for (i = 0; group_list[i].name != NULL; i++) 960 { 961 if (!__itt_fstrcmp(gr, group_list[i].name)) 962 { 963 res = (__itt_group_id)(res | group_list[i].id); 964 break; 965 } 966 } 967 } 968 /* TODO: !!! Workaround for bug with warning for unknown group !!! 969 * Should be fixed in new initialization scheme. 970 * Now the following groups should be set always. */ 971 for (i = 0; group_list[i].id != __itt_group_none; i++) 972 if (group_list[i].id != __itt_group_all && 973 group_list[i].id > __itt_group_splitter_min && 974 group_list[i].id < __itt_group_splitter_max) 975 res = (__itt_group_id)(res | group_list[i].id); 976 return res; 977 } 978 else 979 { 980 for (i = 0; group_alias[i].env_var != NULL; i++) 981 if (__itt_get_env_var(group_alias[i].env_var) != NULL) 982 return group_alias[i].groups; 983 } 984 985 return res; 986 } 987 988 #undef __itt_min 989 990 static int __itt_lib_version(lib_t lib) 991 { 992 if (lib == NULL) 993 return 0; 994 if (__itt_get_proc(lib, "__itt_api_init")) 995 return 2; 996 if (__itt_get_proc(lib, "__itt_api_version")) 997 return 1; 998 return 0; 999 } 1000 1001 /* It's not used right now! Comment it out to avoid warnings. 1002 static void __itt_reinit_all_pointers(void) 1003 { 1004 int i; 1005 // Fill all pointers with initial stubs 1006 for (i = 0; _N_(_ittapi_global).api_list_ptr[i].name != NULL; i++) 1007 *_N_(_ittapi_global).api_list_ptr[i].func_ptr = _N_(_ittapi_global).api_list_ptr[i].init_func; 1008 } 1009 */ 1010 1011 static void __itt_nullify_all_pointers(void) 1012 { 1013 int i; 1014 /* Nulify all pointers except domain_create, string_handle_create and counter_create */ 1015 for (i = 0; _N_(_ittapi_global).api_list_ptr[i].name != NULL; i++) 1016 *_N_(_ittapi_global).api_list_ptr[i].func_ptr = _N_(_ittapi_global).api_list_ptr[i].null_func; 1017 } 1018 1019 #if ITT_PLATFORM==ITT_PLATFORM_WIN && KMP_MSVC_COMPAT 1020 #pragma warning(push) 1021 #pragma warning(disable: 4054) /* warning C4054: 'type cast' : from function pointer 'XXX' to data pointer 'void *' */ 1022 #pragma warning(disable: 4055) /* warning C4055: 'type cast' : from data pointer 'void *' to function pointer 'XXX' */ 1023 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ 1024 1025 ITT_EXTERN_C void _N_(fini_ittlib)(void) 1026 { 1027 __itt_api_fini_t* __itt_api_fini_ptr = NULL; 1028 static volatile TIDT current_thread = 0; 1029 1030 if (_N_(_ittapi_global).api_initialized) 1031 { 1032 ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global)); 1033 if (_N_(_ittapi_global).api_initialized) 1034 { 1035 if (current_thread == 0) 1036 { 1037 if (PTHREAD_SYMBOLS) current_thread = __itt_thread_id(); 1038 if (_N_(_ittapi_global).lib != NULL) 1039 { 1040 __itt_api_fini_ptr = (__itt_api_fini_t*)(size_t)__itt_get_proc(_N_(_ittapi_global).lib, "__itt_api_fini"); 1041 } 1042 if (__itt_api_fini_ptr) 1043 { 1044 __itt_api_fini_ptr(&_N_(_ittapi_global)); 1045 } 1046 1047 __itt_nullify_all_pointers(); 1048 1049 /* TODO: !!! not safe !!! don't support unload so far. 1050 * if (_N_(_ittapi_global).lib != NULL) 1051 * __itt_unload_lib(_N_(_ittapi_global).lib); 1052 * _N_(_ittapi_global).lib = NULL; 1053 */ 1054 _N_(_ittapi_global).api_initialized = 0; 1055 current_thread = 0; 1056 } 1057 } 1058 if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex); 1059 } 1060 } 1061 1062 ITT_EXTERN_C int _N_(init_ittlib)(const char* lib_name, __itt_group_id init_groups) 1063 { 1064 int i; 1065 __itt_group_id groups; 1066 #ifdef ITT_COMPLETE_GROUP 1067 __itt_group_id zero_group = __itt_group_none; 1068 #endif /* ITT_COMPLETE_GROUP */ 1069 static volatile TIDT current_thread = 0; 1070 1071 if (!_N_(_ittapi_global).api_initialized) 1072 { 1073 #ifndef ITT_SIMPLE_INIT 1074 ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global)); 1075 #endif /* ITT_SIMPLE_INIT */ 1076 1077 if (!_N_(_ittapi_global).api_initialized) 1078 { 1079 if (current_thread == 0) 1080 { 1081 if (PTHREAD_SYMBOLS) current_thread = __itt_thread_id(); 1082 if (lib_name == NULL) 1083 { 1084 lib_name = __itt_get_lib_name(); 1085 } 1086 groups = __itt_get_groups(); 1087 if (DL_SYMBOLS && (groups != __itt_group_none || lib_name != NULL)) 1088 { 1089 _N_(_ittapi_global).lib = __itt_load_lib((lib_name == NULL) ? ittnotify_lib_name : lib_name); 1090 1091 if (_N_(_ittapi_global).lib != NULL) 1092 { 1093 __itt_api_init_t* __itt_api_init_ptr; 1094 int lib_version = __itt_lib_version(_N_(_ittapi_global).lib); 1095 1096 switch (lib_version) { 1097 case 0: 1098 groups = __itt_group_legacy; 1099 case 1: 1100 /* Fill all pointers from dynamic library */ 1101 for (i = 0; _N_(_ittapi_global).api_list_ptr[i].name != NULL; i++) 1102 { 1103 if (_N_(_ittapi_global).api_list_ptr[i].group & groups & init_groups) 1104 { 1105 *_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); 1106 if (*_N_(_ittapi_global).api_list_ptr[i].func_ptr == NULL) 1107 { 1108 /* Restore pointers for function with static implementation */ 1109 *_N_(_ittapi_global).api_list_ptr[i].func_ptr = _N_(_ittapi_global).api_list_ptr[i].null_func; 1110 __itt_report_error(__itt_error_no_symbol, lib_name, _N_(_ittapi_global).api_list_ptr[i].name); 1111 #ifdef ITT_COMPLETE_GROUP 1112 zero_group = (__itt_group_id)(zero_group | _N_(_ittapi_global).api_list_ptr[i].group); 1113 #endif /* ITT_COMPLETE_GROUP */ 1114 } 1115 } 1116 else 1117 *_N_(_ittapi_global).api_list_ptr[i].func_ptr = _N_(_ittapi_global).api_list_ptr[i].null_func; 1118 } 1119 1120 if (groups == __itt_group_legacy) 1121 { 1122 /* Compatibility with legacy tools */ 1123 ITTNOTIFY_NAME(thread_ignore) = ITTNOTIFY_NAME(thr_ignore); 1124 #if ITT_PLATFORM==ITT_PLATFORM_WIN 1125 ITTNOTIFY_NAME(sync_createA) = ITTNOTIFY_NAME(sync_set_nameA); 1126 ITTNOTIFY_NAME(sync_createW) = ITTNOTIFY_NAME(sync_set_nameW); 1127 #else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */ 1128 ITTNOTIFY_NAME(sync_create) = ITTNOTIFY_NAME(sync_set_name); 1129 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ 1130 ITTNOTIFY_NAME(sync_prepare) = ITTNOTIFY_NAME(notify_sync_prepare); 1131 ITTNOTIFY_NAME(sync_cancel) = ITTNOTIFY_NAME(notify_sync_cancel); 1132 ITTNOTIFY_NAME(sync_acquired) = ITTNOTIFY_NAME(notify_sync_acquired); 1133 ITTNOTIFY_NAME(sync_releasing) = ITTNOTIFY_NAME(notify_sync_releasing); 1134 } 1135 1136 #ifdef ITT_COMPLETE_GROUP 1137 for (i = 0; _N_(_ittapi_global).api_list_ptr[i].name != NULL; i++) 1138 if (_N_(_ittapi_global).api_list_ptr[i].group & zero_group) 1139 *_N_(_ittapi_global).api_list_ptr[i].func_ptr = _N_(_ittapi_global).api_list_ptr[i].null_func; 1140 #endif /* ITT_COMPLETE_GROUP */ 1141 break; 1142 case 2: 1143 __itt_api_init_ptr = (__itt_api_init_t*)(size_t)__itt_get_proc(_N_(_ittapi_global).lib, "__itt_api_init"); 1144 if (__itt_api_init_ptr) 1145 __itt_api_init_ptr(&_N_(_ittapi_global), init_groups); 1146 break; 1147 } 1148 } 1149 else 1150 { 1151 __itt_nullify_all_pointers(); 1152 1153 __itt_report_error(__itt_error_no_module, lib_name, 1154 #if ITT_PLATFORM==ITT_PLATFORM_WIN 1155 __itt_system_error() 1156 #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ 1157 dlerror() 1158 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ 1159 ); 1160 } 1161 } 1162 else 1163 { 1164 __itt_nullify_all_pointers(); 1165 } 1166 _N_(_ittapi_global).api_initialized = 1; 1167 current_thread = 0; 1168 /* !!! Just to avoid unused code elimination !!! */ 1169 if (__itt_fini_ittlib_ptr == _N_(fini_ittlib)) current_thread = 0; 1170 } 1171 } 1172 1173 #ifndef ITT_SIMPLE_INIT 1174 if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex); 1175 #endif /* ITT_SIMPLE_INIT */ 1176 } 1177 1178 /* Evaluating if any function ptr is non empty and it's in init_groups */ 1179 for (i = 0; _N_(_ittapi_global).api_list_ptr[i].name != NULL; i++) 1180 { 1181 if (*_N_(_ittapi_global).api_list_ptr[i].func_ptr != _N_(_ittapi_global).api_list_ptr[i].null_func && 1182 _N_(_ittapi_global).api_list_ptr[i].group & init_groups) 1183 { 1184 return 1; 1185 } 1186 } 1187 return 0; 1188 } 1189 1190 ITT_EXTERN_C __itt_error_handler_t* _N_(set_error_handler)(__itt_error_handler_t* handler) 1191 { 1192 __itt_error_handler_t* prev = (__itt_error_handler_t*)(size_t)_N_(_ittapi_global).error_handler; 1193 _N_(_ittapi_global).error_handler = (void*)(size_t)handler; 1194 return prev; 1195 } 1196 1197 #if ITT_PLATFORM==ITT_PLATFORM_WIN && KMP_MSVC_COMPAT 1198 #pragma warning(pop) 1199 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ 1200