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 char dll_path[PATH_MAX] = { 0 }; 230 231 /* static part descriptor which handles. all notification api attributes. */ 232 __itt_global _N_(_ittapi_global) = { 233 ITT_MAGIC, /* identification info */ 234 ITT_MAJOR, ITT_MINOR, API_VERSION_BUILD, /* version info */ 235 0, /* api_initialized */ 236 0, /* mutex_initialized */ 237 0, /* atomic_counter */ 238 MUTEX_INITIALIZER, /* mutex */ 239 NULL, /* dynamic library handle */ 240 NULL, /* error_handler */ 241 (const char**)&dll_path, /* dll_path_ptr */ 242 (__itt_api_info*)&api_list, /* api_list_ptr */ 243 NULL, /* next __itt_global */ 244 NULL, /* thread_list */ 245 NULL, /* domain_list */ 246 NULL, /* string_list */ 247 __itt_collection_normal, /* collection state */ 248 NULL /* counter_list */ 249 }; 250 251 typedef void (__itt_api_init_t)(__itt_global*, __itt_group_id); 252 typedef void (__itt_api_fini_t)(__itt_global*); 253 254 /* ========================================================================= */ 255 256 #ifdef ITT_NOTIFY_EXT_REPORT 257 ITT_EXTERN_C void _N_(error_handler)(__itt_error_code, va_list args); 258 #endif /* ITT_NOTIFY_EXT_REPORT */ 259 260 #if ITT_PLATFORM==ITT_PLATFORM_WIN && KMP_MSVC_COMPAT 261 #pragma warning(push) 262 #pragma warning(disable: 4055) /* warning C4055: 'type cast' : from data pointer 'void *' to function pointer 'XXX' */ 263 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ 264 265 static void __itt_report_error(unsigned code_arg, ...) 266 { 267 va_list args; 268 va_start(args, code_arg); 269 270 // We use unsigned for the code argument and explicitly cast it here to the 271 // right enumerator because variadic functions are not compatible with 272 // default promotions. 273 __itt_error_code code = (__itt_error_code)code_arg; 274 275 if (_N_(_ittapi_global).error_handler != NULL) 276 { 277 __itt_error_handler_t* handler = (__itt_error_handler_t*)(size_t)_N_(_ittapi_global).error_handler; 278 handler(code, args); 279 } 280 #ifdef ITT_NOTIFY_EXT_REPORT 281 _N_(error_handler)(code, args); 282 #endif /* ITT_NOTIFY_EXT_REPORT */ 283 va_end(args); 284 } 285 286 #if ITT_PLATFORM==ITT_PLATFORM_WIN && KMP_MSVC_COMPAT 287 #pragma warning(pop) 288 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ 289 290 #if ITT_PLATFORM==ITT_PLATFORM_WIN 291 static __itt_domain* ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(domain_createW),_init))(const wchar_t* name) 292 { 293 __itt_domain *h_tail = NULL, *h = NULL; 294 295 if (name == NULL) 296 { 297 return NULL; 298 } 299 300 ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global)); 301 if (_N_(_ittapi_global).api_initialized) 302 { 303 if (ITTNOTIFY_NAME(domain_createW) && ITTNOTIFY_NAME(domain_createW) != ITT_VERSIONIZE(ITT_JOIN(_N_(domain_createW),_init))) 304 { 305 __itt_mutex_unlock(&_N_(_ittapi_global).mutex); 306 return ITTNOTIFY_NAME(domain_createW)(name); 307 } 308 } 309 for (h_tail = NULL, h = _N_(_ittapi_global).domain_list; h != NULL; h_tail = h, h = h->next) 310 { 311 if (h->nameW != NULL && !wcscmp(h->nameW, name)) break; 312 } 313 if (h == NULL) 314 { 315 NEW_DOMAIN_W(&_N_(_ittapi_global),h,h_tail,name); 316 } 317 if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex); 318 return h; 319 } 320 321 static __itt_domain* ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(domain_createA),_init))(const char* name) 322 #else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */ 323 static __itt_domain* ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(domain_create),_init))(const char* name) 324 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ 325 { 326 __itt_domain *h_tail = NULL, *h = NULL; 327 328 if (name == NULL) 329 { 330 return NULL; 331 } 332 333 ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global)); 334 if (_N_(_ittapi_global).api_initialized) 335 { 336 #if ITT_PLATFORM==ITT_PLATFORM_WIN 337 if (ITTNOTIFY_NAME(domain_createA) && ITTNOTIFY_NAME(domain_createA) != ITT_VERSIONIZE(ITT_JOIN(_N_(domain_createA),_init))) 338 { 339 __itt_mutex_unlock(&_N_(_ittapi_global).mutex); 340 return ITTNOTIFY_NAME(domain_createA)(name); 341 } 342 #else 343 if (ITTNOTIFY_NAME(domain_create) && ITTNOTIFY_NAME(domain_create) != ITT_VERSIONIZE(ITT_JOIN(_N_(domain_create),_init))) 344 { 345 if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex); 346 return ITTNOTIFY_NAME(domain_create)(name); 347 } 348 #endif 349 } 350 for (h_tail = NULL, h = _N_(_ittapi_global).domain_list; h != NULL; h_tail = h, h = h->next) 351 { 352 if (h->nameA != NULL && !__itt_fstrcmp(h->nameA, name)) break; 353 } 354 if (h == NULL) 355 { 356 NEW_DOMAIN_A(&_N_(_ittapi_global),h,h_tail,name); 357 } 358 if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex); 359 return h; 360 } 361 362 #if ITT_PLATFORM==ITT_PLATFORM_WIN 363 static __itt_string_handle* ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(string_handle_createW),_init))(const wchar_t* name) 364 { 365 __itt_string_handle *h_tail = NULL, *h = NULL; 366 367 if (name == NULL) 368 { 369 return NULL; 370 } 371 372 ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global)); 373 if (_N_(_ittapi_global).api_initialized) 374 { 375 if (ITTNOTIFY_NAME(string_handle_createW) && ITTNOTIFY_NAME(string_handle_createW) != ITT_VERSIONIZE(ITT_JOIN(_N_(string_handle_createW),_init))) 376 { 377 __itt_mutex_unlock(&_N_(_ittapi_global).mutex); 378 return ITTNOTIFY_NAME(string_handle_createW)(name); 379 } 380 } 381 for (h_tail = NULL, h = _N_(_ittapi_global).string_list; h != NULL; h_tail = h, h = h->next) 382 { 383 if (h->strW != NULL && !wcscmp(h->strW, name)) break; 384 } 385 if (h == NULL) 386 { 387 NEW_STRING_HANDLE_W(&_N_(_ittapi_global),h,h_tail,name); 388 } 389 __itt_mutex_unlock(&_N_(_ittapi_global).mutex); 390 return h; 391 } 392 393 static __itt_string_handle* ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(string_handle_createA),_init))(const char* name) 394 #else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */ 395 static __itt_string_handle* ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(string_handle_create),_init))(const char* name) 396 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ 397 { 398 __itt_string_handle *h_tail = NULL, *h = NULL; 399 400 if (name == NULL) 401 { 402 return NULL; 403 } 404 405 ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global)); 406 if (_N_(_ittapi_global).api_initialized) 407 { 408 #if ITT_PLATFORM==ITT_PLATFORM_WIN 409 if (ITTNOTIFY_NAME(string_handle_createA) && ITTNOTIFY_NAME(string_handle_createA) != ITT_VERSIONIZE(ITT_JOIN(_N_(string_handle_createA),_init))) 410 { 411 __itt_mutex_unlock(&_N_(_ittapi_global).mutex); 412 return ITTNOTIFY_NAME(string_handle_createA)(name); 413 } 414 #else 415 if (ITTNOTIFY_NAME(string_handle_create) && ITTNOTIFY_NAME(string_handle_create) != ITT_VERSIONIZE(ITT_JOIN(_N_(string_handle_create),_init))) 416 { 417 if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex); 418 return ITTNOTIFY_NAME(string_handle_create)(name); 419 } 420 #endif 421 } 422 for (h_tail = NULL, h = _N_(_ittapi_global).string_list; h != NULL; h_tail = h, h = h->next) 423 { 424 if (h->strA != NULL && !__itt_fstrcmp(h->strA, name)) break; 425 } 426 if (h == NULL) 427 { 428 NEW_STRING_HANDLE_A(&_N_(_ittapi_global),h,h_tail,name); 429 } 430 if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex); 431 return h; 432 } 433 434 #if ITT_PLATFORM==ITT_PLATFORM_WIN 435 static __itt_counter ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(counter_createW),_init))(const wchar_t *name, const wchar_t *domain) 436 { 437 __itt_counter_info_t *h_tail = NULL, *h = NULL; 438 __itt_metadata_type type = __itt_metadata_u64; 439 440 if (name == NULL) 441 { 442 return NULL; 443 } 444 445 ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global)); 446 if (_N_(_ittapi_global).api_initialized) 447 { 448 if (ITTNOTIFY_NAME(counter_createW) && ITTNOTIFY_NAME(counter_createW) != ITT_VERSIONIZE(ITT_JOIN(_N_(counter_createW),_init))) 449 { 450 __itt_mutex_unlock(&_N_(_ittapi_global).mutex); 451 return ITTNOTIFY_NAME(counter_createW)(name, domain); 452 } 453 } 454 for (h_tail = NULL, h = _N_(_ittapi_global).counter_list; h != NULL; h_tail = h, h = h->next) 455 { 456 if (h->nameW != NULL && h->type == type && !wcscmp(h->nameW, name) && ((h->domainW == NULL && domain == NULL) || 457 (h->domainW != NULL && domain != NULL && !wcscmp(h->domainW, domain)))) break; 458 459 } 460 if (h == NULL) 461 { 462 NEW_COUNTER_W(&_N_(_ittapi_global),h,h_tail,name,domain,type); 463 } 464 __itt_mutex_unlock(&_N_(_ittapi_global).mutex); 465 return (__itt_counter)h; 466 } 467 468 static __itt_counter ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(counter_createA),_init))(const char *name, const char *domain) 469 #else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */ 470 static __itt_counter ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(counter_create),_init))(const char *name, const char *domain) 471 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ 472 { 473 __itt_counter_info_t *h_tail = NULL, *h = NULL; 474 __itt_metadata_type type = __itt_metadata_u64; 475 476 if (name == NULL) 477 { 478 return NULL; 479 } 480 481 ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global)); 482 if (_N_(_ittapi_global).api_initialized) 483 { 484 #if ITT_PLATFORM==ITT_PLATFORM_WIN 485 if (ITTNOTIFY_NAME(counter_createA) && ITTNOTIFY_NAME(counter_createA) != ITT_VERSIONIZE(ITT_JOIN(_N_(counter_createA),_init))) 486 { 487 __itt_mutex_unlock(&_N_(_ittapi_global).mutex); 488 return ITTNOTIFY_NAME(counter_createA)(name, domain); 489 } 490 #else 491 if (ITTNOTIFY_NAME(counter_create) && ITTNOTIFY_NAME(counter_create) != ITT_VERSIONIZE(ITT_JOIN(_N_(counter_create),_init))) 492 { 493 if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex); 494 return ITTNOTIFY_NAME(counter_create)(name, domain); 495 } 496 #endif 497 } 498 for (h_tail = NULL, h = _N_(_ittapi_global).counter_list; h != NULL; h_tail = h, h = h->next) 499 { 500 if (h->nameA != NULL && h->type == type && !__itt_fstrcmp(h->nameA, name) && ((h->domainA == NULL && domain == NULL) || 501 (h->domainA != NULL && domain != NULL && !__itt_fstrcmp(h->domainA, domain)))) break; 502 } 503 if (h == NULL) 504 { 505 NEW_COUNTER_A(&_N_(_ittapi_global),h,h_tail,name,domain,type); 506 } 507 if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex); 508 return (__itt_counter)h; 509 } 510 511 #if ITT_PLATFORM==ITT_PLATFORM_WIN 512 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) 513 { 514 __itt_counter_info_t *h_tail = NULL, *h = NULL; 515 516 if (name == NULL) 517 { 518 return NULL; 519 } 520 521 ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global)); 522 if (_N_(_ittapi_global).api_initialized) 523 { 524 if (ITTNOTIFY_NAME(counter_create_typedW) && ITTNOTIFY_NAME(counter_create_typedW) != ITT_VERSIONIZE(ITT_JOIN(_N_(counter_create_typedW),_init))) 525 { 526 __itt_mutex_unlock(&_N_(_ittapi_global).mutex); 527 return ITTNOTIFY_NAME(counter_create_typedW)(name, domain, type); 528 } 529 } 530 for (h_tail = NULL, h = _N_(_ittapi_global).counter_list; h != NULL; h_tail = h, h = h->next) 531 { 532 if (h->nameW != NULL && h->type == type && !wcscmp(h->nameW, name) && ((h->domainW == NULL && domain == NULL) || 533 (h->domainW != NULL && domain != NULL && !wcscmp(h->domainW, domain)))) break; 534 535 } 536 if (h == NULL) 537 { 538 NEW_COUNTER_W(&_N_(_ittapi_global),h,h_tail,name,domain,type); 539 } 540 __itt_mutex_unlock(&_N_(_ittapi_global).mutex); 541 return (__itt_counter)h; 542 } 543 544 static __itt_counter ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(counter_create_typedA),_init))(const char *name, const char *domain, __itt_metadata_type type) 545 #else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */ 546 static __itt_counter ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(counter_create_typed),_init))(const char *name, const char *domain, __itt_metadata_type type) 547 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ 548 { 549 __itt_counter_info_t *h_tail = NULL, *h = NULL; 550 551 if (name == NULL) 552 { 553 return NULL; 554 } 555 556 ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global)); 557 if (_N_(_ittapi_global).api_initialized) 558 { 559 #if ITT_PLATFORM==ITT_PLATFORM_WIN 560 if (ITTNOTIFY_NAME(counter_create_typedA) && ITTNOTIFY_NAME(counter_create_typedA) != ITT_VERSIONIZE(ITT_JOIN(_N_(counter_create_typedA),_init))) 561 { 562 __itt_mutex_unlock(&_N_(_ittapi_global).mutex); 563 return ITTNOTIFY_NAME(counter_create_typedA)(name, domain, type); 564 } 565 #else 566 if (ITTNOTIFY_NAME(counter_create_typed) && ITTNOTIFY_NAME(counter_create_typed) != ITT_VERSIONIZE(ITT_JOIN(_N_(counter_create_typed),_init))) 567 { 568 if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex); 569 return ITTNOTIFY_NAME(counter_create_typed)(name, domain, type); 570 } 571 #endif 572 } 573 for (h_tail = NULL, h = _N_(_ittapi_global).counter_list; h != NULL; h_tail = h, h = h->next) 574 { 575 if (h->nameA != NULL && h->type == type && !__itt_fstrcmp(h->nameA, name) && ((h->domainA == NULL && domain == NULL) || 576 (h->domainA != NULL && domain != NULL && !__itt_fstrcmp(h->domainA, domain)))) break; 577 } 578 if (h == NULL) 579 { 580 NEW_COUNTER_A(&_N_(_ittapi_global),h,h_tail,name,domain,type); 581 } 582 if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex); 583 return (__itt_counter)h; 584 } 585 586 /* -------------------------------------------------------------------------- */ 587 588 static void ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(pause),_init))(void) 589 { 590 if (!_N_(_ittapi_global).api_initialized && _N_(_ittapi_global).thread_list == NULL) 591 { 592 __itt_init_ittlib_name(NULL, __itt_group_all); 593 } 594 if (ITTNOTIFY_NAME(pause) && ITTNOTIFY_NAME(pause) != ITT_VERSIONIZE(ITT_JOIN(_N_(pause),_init))) 595 { 596 ITTNOTIFY_NAME(pause)(); 597 } 598 else 599 { 600 _N_(_ittapi_global).state = __itt_collection_paused; 601 } 602 } 603 604 static void ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(resume),_init))(void) 605 { 606 if (!_N_(_ittapi_global).api_initialized && _N_(_ittapi_global).thread_list == NULL) 607 { 608 __itt_init_ittlib_name(NULL, __itt_group_all); 609 } 610 if (ITTNOTIFY_NAME(resume) && ITTNOTIFY_NAME(resume) != ITT_VERSIONIZE(ITT_JOIN(_N_(resume),_init))) 611 { 612 ITTNOTIFY_NAME(resume)(); 613 } 614 else 615 { 616 _N_(_ittapi_global).state = __itt_collection_normal; 617 } 618 } 619 620 #if ITT_PLATFORM==ITT_PLATFORM_WIN 621 static void ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_nameW),_init))(const wchar_t* name) 622 { 623 if (!_N_(_ittapi_global).api_initialized && _N_(_ittapi_global).thread_list == NULL) 624 { 625 __itt_init_ittlib_name(NULL, __itt_group_all); 626 } 627 if (ITTNOTIFY_NAME(thread_set_nameW) && ITTNOTIFY_NAME(thread_set_nameW) != ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_nameW),_init))) 628 { 629 ITTNOTIFY_NAME(thread_set_nameW)(name); 630 } 631 } 632 633 static int ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(thr_name_setW),_init))(const wchar_t* name, int namelen) 634 { 635 (void)namelen; 636 ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_nameW),_init))(name); 637 return 0; 638 } 639 640 static void ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_nameA),_init))(const char* name) 641 #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ 642 static void ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_name),_init))(const char* name) 643 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ 644 { 645 if (!_N_(_ittapi_global).api_initialized && _N_(_ittapi_global).thread_list == NULL) 646 { 647 __itt_init_ittlib_name(NULL, __itt_group_all); 648 } 649 #if ITT_PLATFORM==ITT_PLATFORM_WIN 650 if (ITTNOTIFY_NAME(thread_set_nameA) && ITTNOTIFY_NAME(thread_set_nameA) != ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_nameA),_init))) 651 { 652 ITTNOTIFY_NAME(thread_set_nameA)(name); 653 } 654 #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ 655 if (ITTNOTIFY_NAME(thread_set_name) && ITTNOTIFY_NAME(thread_set_name) != ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_name),_init))) 656 { 657 ITTNOTIFY_NAME(thread_set_name)(name); 658 } 659 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ 660 } 661 662 #if ITT_PLATFORM==ITT_PLATFORM_WIN 663 static int ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(thr_name_setA),_init))(const char* name, int namelen) 664 { 665 (void)namelen; 666 ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_nameA),_init))(name); 667 return 0; 668 } 669 #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */ 670 static int ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(thr_name_set),_init))(const char* name, int namelen) 671 { 672 (void)namelen; 673 ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_name),_init))(name); 674 return 0; 675 } 676 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ 677 678 static void ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(thread_ignore),_init))(void) 679 { 680 if (!_N_(_ittapi_global).api_initialized && _N_(_ittapi_global).thread_list == NULL) 681 { 682 __itt_init_ittlib_name(NULL, __itt_group_all); 683 } 684 if (ITTNOTIFY_NAME(thread_ignore) && ITTNOTIFY_NAME(thread_ignore) != ITT_VERSIONIZE(ITT_JOIN(_N_(thread_ignore),_init))) 685 { 686 ITTNOTIFY_NAME(thread_ignore)(); 687 } 688 } 689 690 static void ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(thr_ignore),_init))(void) 691 { 692 ITT_VERSIONIZE(ITT_JOIN(_N_(thread_ignore),_init))(); 693 } 694 695 static void ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(enable_attach),_init))(void) 696 { 697 #ifdef __ANDROID__ 698 /* 699 * if LIB_VAR_NAME env variable were set before then stay previous value 700 * else set default path 701 */ 702 setenv(ITT_TO_STR(LIB_VAR_NAME), ANDROID_ITTNOTIFY_DEFAULT_PATH, 0); 703 #endif 704 } 705 706 /* -------------------------------------------------------------------------- */ 707 708 static const char* __itt_fsplit(const char* s, const char* sep, const char** out, int* len) 709 { 710 int i; 711 int j; 712 713 if (!s || !sep || !out || !len) 714 return NULL; 715 716 for (i = 0; s[i]; i++) 717 { 718 int b = 0; 719 for (j = 0; sep[j]; j++) 720 if (s[i] == sep[j]) 721 { 722 b = 1; 723 break; 724 } 725 if (!b) 726 break; 727 } 728 729 if (!s[i]) 730 return NULL; 731 732 *len = 0; 733 *out = &s[i]; 734 735 for (; s[i]; i++, (*len)++) 736 { 737 int b = 0; 738 for (j = 0; sep[j]; j++) 739 if (s[i] == sep[j]) 740 { 741 b = 1; 742 break; 743 } 744 if (b) 745 break; 746 } 747 748 for (; s[i]; i++) 749 { 750 int b = 0; 751 for (j = 0; sep[j]; j++) 752 if (s[i] == sep[j]) 753 { 754 b = 1; 755 break; 756 } 757 if (!b) 758 break; 759 } 760 761 return &s[i]; 762 } 763 764 /* This function return value of env variable that placed into static buffer. 765 * !!! The same static buffer is used for subsequent calls. !!! 766 * This was done to aviod dynamic allocation for few calls. 767 * Actually we need this function only four times. 768 */ 769 static const char* __itt_get_env_var(const char* name) 770 { 771 #define MAX_ENV_VALUE_SIZE 4086 772 static char env_buff[MAX_ENV_VALUE_SIZE]; 773 static char* env_value = (char*)env_buff; 774 775 if (name != NULL) 776 { 777 #if ITT_PLATFORM==ITT_PLATFORM_WIN 778 size_t max_len = MAX_ENV_VALUE_SIZE - (size_t)(env_value - env_buff); 779 DWORD rc = GetEnvironmentVariableA(name, env_value, (DWORD)max_len); 780 if (rc >= max_len) 781 __itt_report_error(__itt_error_env_too_long, name, (size_t)rc - 1, (size_t)(max_len - 1)); 782 else if (rc > 0) 783 { 784 const char* ret = (const char*)env_value; 785 env_value += rc + 1; 786 return ret; 787 } 788 else 789 { 790 /* If environment variable is empty, GetEnvirornmentVariables() 791 * returns zero (number of characters (not including terminating null), 792 * and GetLastError() returns ERROR_SUCCESS. */ 793 DWORD err = GetLastError(); 794 if (err == ERROR_SUCCESS) 795 return env_value; 796 797 if (err != ERROR_ENVVAR_NOT_FOUND) 798 __itt_report_error(__itt_error_cant_read_env, name, (int)err); 799 } 800 #else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */ 801 char* env = getenv(name); 802 if (env != NULL) 803 { 804 size_t len = __itt_fstrnlen(env, MAX_ENV_VALUE_SIZE); 805 size_t max_len = MAX_ENV_VALUE_SIZE - (size_t)(env_value - env_buff); 806 if (len < max_len) 807 { 808 const char* ret = (const char*)env_value; 809 __itt_fstrcpyn(env_value, max_len, env, len + 1); 810 env_value += len + 1; 811 return ret; 812 } else 813 __itt_report_error(__itt_error_env_too_long, name, (size_t)len, (size_t)(max_len - 1)); 814 } 815 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ 816 } 817 return NULL; 818 } 819 820 static const char* __itt_get_lib_name(void) 821 { 822 const char* lib_name = __itt_get_env_var(ITT_TO_STR(LIB_VAR_NAME)); 823 824 #ifdef __ANDROID__ 825 if (lib_name == NULL) 826 { 827 828 #if ITT_ARCH==ITT_ARCH_IA32 || ITT_ARCH==ITT_ARCH_ARM 829 const char* const marker_filename = "com.intel.itt.collector_lib_32"; 830 #else 831 const char* const marker_filename = "com.intel.itt.collector_lib_64"; 832 #endif 833 834 char system_wide_marker_filename[PATH_MAX] = {0}; 835 int itt_marker_file_fd = -1; 836 ssize_t res = 0; 837 838 res = snprintf(system_wide_marker_filename, PATH_MAX - 1, "%s%s", "/data/local/tmp/", marker_filename); 839 if (res < 0) 840 { 841 ITT_ANDROID_LOGE("Unable to concatenate marker file string."); 842 return lib_name; 843 } 844 itt_marker_file_fd = open(system_wide_marker_filename, O_RDONLY); 845 846 if (itt_marker_file_fd == -1) 847 { 848 const pid_t my_pid = getpid(); 849 char cmdline_path[PATH_MAX] = {0}; 850 char package_name[PATH_MAX] = {0}; 851 char app_sandbox_file[PATH_MAX] = {0}; 852 int cmdline_fd = 0; 853 854 ITT_ANDROID_LOGI("Unable to open system-wide marker file."); 855 res = snprintf(cmdline_path, PATH_MAX - 1, "/proc/%d/cmdline", my_pid); 856 if (res < 0) 857 { 858 ITT_ANDROID_LOGE("Unable to get cmdline path string."); 859 return lib_name; 860 } 861 862 ITT_ANDROID_LOGI("CMD file: %s\n", cmdline_path); 863 cmdline_fd = open(cmdline_path, O_RDONLY); 864 if (cmdline_fd == -1) 865 { 866 ITT_ANDROID_LOGE("Unable to open %s file!", cmdline_path); 867 return lib_name; 868 } 869 res = read(cmdline_fd, package_name, PATH_MAX - 1); 870 if (res == -1) 871 { 872 ITT_ANDROID_LOGE("Unable to read %s file!", cmdline_path); 873 res = close(cmdline_fd); 874 if (res == -1) 875 { 876 ITT_ANDROID_LOGE("Unable to close %s file!", cmdline_path); 877 } 878 return lib_name; 879 } 880 res = close(cmdline_fd); 881 if (res == -1) 882 { 883 ITT_ANDROID_LOGE("Unable to close %s file!", cmdline_path); 884 return lib_name; 885 } 886 ITT_ANDROID_LOGI("Package name: %s\n", package_name); 887 res = snprintf(app_sandbox_file, PATH_MAX - 1, "/data/data/%s/%s", package_name, marker_filename); 888 if (res < 0) 889 { 890 ITT_ANDROID_LOGE("Unable to concatenate marker file string."); 891 return lib_name; 892 } 893 894 ITT_ANDROID_LOGI("Lib marker file name: %s\n", app_sandbox_file); 895 itt_marker_file_fd = open(app_sandbox_file, O_RDONLY); 896 if (itt_marker_file_fd == -1) 897 { 898 ITT_ANDROID_LOGE("Unable to open app marker file!"); 899 return lib_name; 900 } 901 } 902 903 { 904 char itt_lib_name[PATH_MAX] = {0}; 905 906 res = read(itt_marker_file_fd, itt_lib_name, PATH_MAX - 1); 907 if (res == -1) 908 { 909 ITT_ANDROID_LOGE("Unable to read %s file!", itt_marker_file_fd); 910 res = close(itt_marker_file_fd); 911 if (res == -1) 912 { 913 ITT_ANDROID_LOGE("Unable to close %s file!", itt_marker_file_fd); 914 } 915 return lib_name; 916 } 917 ITT_ANDROID_LOGI("ITT Lib path: %s", itt_lib_name); 918 res = close(itt_marker_file_fd); 919 if (res == -1) 920 { 921 ITT_ANDROID_LOGE("Unable to close %s file!", itt_marker_file_fd); 922 return lib_name; 923 } 924 ITT_ANDROID_LOGI("Set env %s to %s", ITT_TO_STR(LIB_VAR_NAME), itt_lib_name); 925 res = setenv(ITT_TO_STR(LIB_VAR_NAME), itt_lib_name, 0); 926 if (res == -1) 927 { 928 ITT_ANDROID_LOGE("Unable to set env var!"); 929 return lib_name; 930 } 931 lib_name = __itt_get_env_var(ITT_TO_STR(LIB_VAR_NAME)); 932 ITT_ANDROID_LOGI("ITT Lib path from env: %s", lib_name); 933 } 934 } 935 #endif 936 937 return lib_name; 938 } 939 940 /* Avoid clashes with std::min, reported by tbb team */ 941 #define __itt_min(a,b) (a) < (b) ? (a) : (b) 942 943 static __itt_group_id __itt_get_groups(void) 944 { 945 int i; 946 __itt_group_id res = __itt_group_none; 947 const char* var_name = "INTEL_ITTNOTIFY_GROUPS"; 948 const char* group_str = __itt_get_env_var(var_name); 949 950 if (group_str != NULL) 951 { 952 int len; 953 char gr[255]; 954 const char* chunk; 955 while ((group_str = __itt_fsplit(group_str, ",; ", &chunk, &len)) != NULL) 956 { 957 int min_len = __itt_min(len, (int)(sizeof(gr) - 1)); 958 __itt_fstrcpyn(gr, sizeof(gr) - 1, chunk, min_len); 959 gr[min_len] = 0; 960 961 for (i = 0; group_list[i].name != NULL; i++) 962 { 963 if (!__itt_fstrcmp(gr, group_list[i].name)) 964 { 965 res = (__itt_group_id)(res | group_list[i].id); 966 break; 967 } 968 } 969 } 970 /* TODO: !!! Workaround for bug with warning for unknown group !!! 971 * Should be fixed in new initialization scheme. 972 * Now the following groups should be set always. */ 973 for (i = 0; group_list[i].id != __itt_group_none; i++) 974 if (group_list[i].id != __itt_group_all && 975 group_list[i].id > __itt_group_splitter_min && 976 group_list[i].id < __itt_group_splitter_max) 977 res = (__itt_group_id)(res | group_list[i].id); 978 return res; 979 } 980 else 981 { 982 for (i = 0; group_alias[i].env_var != NULL; i++) 983 if (__itt_get_env_var(group_alias[i].env_var) != NULL) 984 return group_alias[i].groups; 985 } 986 987 return res; 988 } 989 990 #undef __itt_min 991 992 static int __itt_lib_version(lib_t lib) 993 { 994 if (lib == NULL) 995 return 0; 996 if (__itt_get_proc(lib, "__itt_api_init")) 997 return 2; 998 if (__itt_get_proc(lib, "__itt_api_version")) 999 return 1; 1000 return 0; 1001 } 1002 1003 /* It's not used right now! Comment it out to avoid warnings. 1004 static void __itt_reinit_all_pointers(void) 1005 { 1006 int i; 1007 // Fill all pointers with initial stubs 1008 for (i = 0; _N_(_ittapi_global).api_list_ptr[i].name != NULL; i++) 1009 *_N_(_ittapi_global).api_list_ptr[i].func_ptr = _N_(_ittapi_global).api_list_ptr[i].init_func; 1010 } 1011 */ 1012 1013 static void __itt_nullify_all_pointers(void) 1014 { 1015 int i; 1016 /* Nulify all pointers except domain_create, string_handle_create and counter_create */ 1017 for (i = 0; _N_(_ittapi_global).api_list_ptr[i].name != NULL; i++) 1018 *_N_(_ittapi_global).api_list_ptr[i].func_ptr = _N_(_ittapi_global).api_list_ptr[i].null_func; 1019 } 1020 1021 #if ITT_PLATFORM==ITT_PLATFORM_WIN && KMP_MSVC_COMPAT 1022 #pragma warning(push) 1023 #pragma warning(disable: 4054) /* warning C4054: 'type cast' : from function pointer 'XXX' to data pointer 'void *' */ 1024 #pragma warning(disable: 4055) /* warning C4055: 'type cast' : from data pointer 'void *' to function pointer 'XXX' */ 1025 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */ 1026 1027 ITT_EXTERN_C void _N_(fini_ittlib)(void) 1028 { 1029 __itt_api_fini_t* __itt_api_fini_ptr = NULL; 1030 static volatile TIDT current_thread = 0; 1031 1032 if (_N_(_ittapi_global).api_initialized) 1033 { 1034 ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global)); 1035 if (_N_(_ittapi_global).api_initialized) 1036 { 1037 if (current_thread == 0) 1038 { 1039 if (PTHREAD_SYMBOLS) current_thread = __itt_thread_id(); 1040 if (_N_(_ittapi_global).lib != NULL) 1041 { 1042 __itt_api_fini_ptr = (__itt_api_fini_t*)(size_t)__itt_get_proc(_N_(_ittapi_global).lib, "__itt_api_fini"); 1043 } 1044 if (__itt_api_fini_ptr) 1045 { 1046 __itt_api_fini_ptr(&_N_(_ittapi_global)); 1047 } 1048 1049 __itt_nullify_all_pointers(); 1050 1051 /* TODO: !!! not safe !!! don't support unload so far. 1052 * if (_N_(_ittapi_global).lib != NULL) 1053 * __itt_unload_lib(_N_(_ittapi_global).lib); 1054 * _N_(_ittapi_global).lib = NULL; 1055 */ 1056 _N_(_ittapi_global).api_initialized = 0; 1057 current_thread = 0; 1058 } 1059 } 1060 if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex); 1061 } 1062 } 1063 1064 ITT_EXTERN_C int _N_(init_ittlib)(const char* lib_name, __itt_group_id init_groups) 1065 { 1066 int i; 1067 __itt_group_id groups; 1068 #ifdef ITT_COMPLETE_GROUP 1069 __itt_group_id zero_group = __itt_group_none; 1070 #endif /* ITT_COMPLETE_GROUP */ 1071 static volatile TIDT current_thread = 0; 1072 1073 if (!_N_(_ittapi_global).api_initialized) 1074 { 1075 #ifndef ITT_SIMPLE_INIT 1076 ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global)); 1077 #endif /* ITT_SIMPLE_INIT */ 1078 1079 if (!_N_(_ittapi_global).api_initialized) 1080 { 1081 if (current_thread == 0) 1082 { 1083 if (PTHREAD_SYMBOLS) current_thread = __itt_thread_id(); 1084 if (lib_name == NULL) 1085 { 1086 lib_name = __itt_get_lib_name(); 1087 } 1088 groups = __itt_get_groups(); 1089 if (DL_SYMBOLS && (groups != __itt_group_none || lib_name != NULL)) 1090 { 1091 _N_(_ittapi_global).lib = __itt_load_lib((lib_name == NULL) ? ittnotify_lib_name : lib_name); 1092 1093 if (_N_(_ittapi_global).lib != NULL) 1094 { 1095 __itt_api_init_t* __itt_api_init_ptr; 1096 int lib_version = __itt_lib_version(_N_(_ittapi_global).lib); 1097 1098 switch (lib_version) { 1099 case 0: 1100 groups = __itt_group_legacy; 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