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