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