2 //===----------------------------------------------------------------------===//
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
8 //===----------------------------------------------------------------------===//
10 #include "kmp_config.h"
11 #include "ittnotify_config.h"
13 #if ITT_PLATFORM==ITT_PLATFORM_WIN
14 #if defined(__MINGW32__)
19 #else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */
23 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
29 #define INTEL_NO_MACRO_BODY
30 #define INTEL_ITTNOTIFY_API_PRIVATE
31 #include "ittnotify.h"
32 #include "legacy/ittnotify.h"
35 #include "disable_warnings.h"
38 static const char api_version[] = API_VERSION "\0\n@(#) $Revision: 481659 $\n";
40 #define _N_(n) ITT_JOIN(INTEL_ITTNOTIFY_PREFIX,n)
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";
49 #error Unsupported or unknown OS.
53 #include <android/log.h>
56 #include <sys/types.h>
59 #include <linux/limits.h>
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__))
68 #define ITT_ANDROID_LOGI(...)
69 #define ITT_ANDROID_LOGW(...)
70 #define ITT_ANDROID_LOGE(...)
71 #define ITT_ANDROID_LOGD(...)
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"
78 #if ITT_ARCH==ITT_ARCH_IA32 || ITT_ARCH==ITT_ARCH_ARM
79 #define ANDROID_ITTNOTIFY_DEFAULT_PATH ANDROID_ITTNOTIFY_DEFAULT_PATH_MASK(32)
81 #define ANDROID_ITTNOTIFY_DEFAULT_PATH ANDROID_ITTNOTIFY_DEFAULT_PATH_MASK(64)
92 #if ITT_ARCH==ITT_ARCH_IA32 || ITT_ARCH==ITT_ARCH_ARM || ITT_ARCH==ITT_ARCH_MIPS
93 #define LIB_VAR_NAME INTEL_LIBITTNOTIFY32
95 #define LIB_VAR_NAME INTEL_LIBITTNOTIFY64
97 #endif /* LIB_VAR_NAME */
99 #define ITT_MUTEX_INIT_AND_LOCK(p) { \
100 if (PTHREAD_SYMBOLS) \
102 if (!p.mutex_initialized) \
104 if (__itt_interlocked_increment(&p.atomic_counter) == 1) \
106 __itt_mutex_init(&p.mutex); \
107 p.mutex_initialized = 1; \
110 while (!p.mutex_initialized) \
111 __itt_thread_yield(); \
113 __itt_mutex_lock(&p.mutex); \
117 typedef int (__itt_init_ittlib_t)(const char*, __itt_group_id);
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 */
126 typedef void (__itt_fini_ittlib_t)(void);
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 */
135 /* building pointers to imported funcs */
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 \
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; \
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 \
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; \
164 #undef __ITT_INTERNAL_INIT
165 #include "ittnotify_static.h"
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
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
179 #define __ITT_INTERNAL_INIT
180 #include "ittnotify_static.h"
181 #undef __ITT_INTERNAL_INIT
183 ITT_GROUP_LIST(group_list);
185 #pragma pack(push, 8)
187 typedef struct ___itt_group_alias
190 __itt_group_id groups;
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 !!! */
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 */
207 static __itt_api_info api_list[] = {
208 /* Define functions with static implementation */
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 */
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}
225 #if ITT_PLATFORM==ITT_PLATFORM_WIN && KMP_MSVC_COMPAT
227 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
229 static const char dll_path[PATH_MAX] = { 0 };
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 */
251 typedef void (__itt_api_init_t)(__itt_global*, __itt_group_id);
252 typedef void (__itt_api_fini_t)(__itt_global*);
254 /* ========================================================================= */
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 */
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 */
265 static void __itt_report_error(unsigned code_arg, ...)
268 va_start(args, code_arg);
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;
275 if (_N_(_ittapi_global).error_handler != NULL)
277 __itt_error_handler_t* handler = (__itt_error_handler_t*)(size_t)_N_(_ittapi_global).error_handler;
280 #ifdef ITT_NOTIFY_EXT_REPORT
281 _N_(error_handler)(code, args);
282 #endif /* ITT_NOTIFY_EXT_REPORT */
286 #if ITT_PLATFORM==ITT_PLATFORM_WIN && KMP_MSVC_COMPAT
288 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
290 #if ITT_PLATFORM==ITT_PLATFORM_WIN
291 static __itt_domain* ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(domain_createW),_init))(const wchar_t* name)
293 __itt_domain *h_tail = NULL, *h = NULL;
300 ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global));
301 if (_N_(_ittapi_global).api_initialized)
303 if (ITTNOTIFY_NAME(domain_createW) && ITTNOTIFY_NAME(domain_createW) != ITT_VERSIONIZE(ITT_JOIN(_N_(domain_createW),_init)))
305 __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
306 return ITTNOTIFY_NAME(domain_createW)(name);
309 for (h_tail = NULL, h = _N_(_ittapi_global).domain_list; h != NULL; h_tail = h, h = h->next)
311 if (h->nameW != NULL && !wcscmp(h->nameW, name)) break;
315 NEW_DOMAIN_W(&_N_(_ittapi_global),h,h_tail,name);
317 if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
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 */
326 __itt_domain *h_tail = NULL, *h = NULL;
333 ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global));
334 if (_N_(_ittapi_global).api_initialized)
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)))
339 __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
340 return ITTNOTIFY_NAME(domain_createA)(name);
343 if (ITTNOTIFY_NAME(domain_create) && ITTNOTIFY_NAME(domain_create) != ITT_VERSIONIZE(ITT_JOIN(_N_(domain_create),_init)))
345 if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
346 return ITTNOTIFY_NAME(domain_create)(name);
350 for (h_tail = NULL, h = _N_(_ittapi_global).domain_list; h != NULL; h_tail = h, h = h->next)
352 if (h->nameA != NULL && !__itt_fstrcmp(h->nameA, name)) break;
356 NEW_DOMAIN_A(&_N_(_ittapi_global),h,h_tail,name);
358 if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
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)
365 __itt_string_handle *h_tail = NULL, *h = NULL;
372 ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global));
373 if (_N_(_ittapi_global).api_initialized)
375 if (ITTNOTIFY_NAME(string_handle_createW) && ITTNOTIFY_NAME(string_handle_createW) != ITT_VERSIONIZE(ITT_JOIN(_N_(string_handle_createW),_init)))
377 __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
378 return ITTNOTIFY_NAME(string_handle_createW)(name);
381 for (h_tail = NULL, h = _N_(_ittapi_global).string_list; h != NULL; h_tail = h, h = h->next)
383 if (h->strW != NULL && !wcscmp(h->strW, name)) break;
387 NEW_STRING_HANDLE_W(&_N_(_ittapi_global),h,h_tail,name);
389 __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
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 */
398 __itt_string_handle *h_tail = NULL, *h = NULL;
405 ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global));
406 if (_N_(_ittapi_global).api_initialized)
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)))
411 __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
412 return ITTNOTIFY_NAME(string_handle_createA)(name);
415 if (ITTNOTIFY_NAME(string_handle_create) && ITTNOTIFY_NAME(string_handle_create) != ITT_VERSIONIZE(ITT_JOIN(_N_(string_handle_create),_init)))
417 if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
418 return ITTNOTIFY_NAME(string_handle_create)(name);
422 for (h_tail = NULL, h = _N_(_ittapi_global).string_list; h != NULL; h_tail = h, h = h->next)
424 if (h->strA != NULL && !__itt_fstrcmp(h->strA, name)) break;
428 NEW_STRING_HANDLE_A(&_N_(_ittapi_global),h,h_tail,name);
430 if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
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)
437 __itt_counter_info_t *h_tail = NULL, *h = NULL;
438 __itt_metadata_type type = __itt_metadata_u64;
445 ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global));
446 if (_N_(_ittapi_global).api_initialized)
448 if (ITTNOTIFY_NAME(counter_createW) && ITTNOTIFY_NAME(counter_createW) != ITT_VERSIONIZE(ITT_JOIN(_N_(counter_createW),_init)))
450 __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
451 return ITTNOTIFY_NAME(counter_createW)(name, domain);
454 for (h_tail = NULL, h = _N_(_ittapi_global).counter_list; h != NULL; h_tail = h, h = h->next)
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;
462 NEW_COUNTER_W(&_N_(_ittapi_global),h,h_tail,name,domain,type);
464 __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
465 return (__itt_counter)h;
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 */
473 __itt_counter_info_t *h_tail = NULL, *h = NULL;
474 __itt_metadata_type type = __itt_metadata_u64;
481 ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global));
482 if (_N_(_ittapi_global).api_initialized)
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)))
487 __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
488 return ITTNOTIFY_NAME(counter_createA)(name, domain);
491 if (ITTNOTIFY_NAME(counter_create) && ITTNOTIFY_NAME(counter_create) != ITT_VERSIONIZE(ITT_JOIN(_N_(counter_create),_init)))
493 if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
494 return ITTNOTIFY_NAME(counter_create)(name, domain);
498 for (h_tail = NULL, h = _N_(_ittapi_global).counter_list; h != NULL; h_tail = h, h = h->next)
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;
505 NEW_COUNTER_A(&_N_(_ittapi_global),h,h_tail,name,domain,type);
507 if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
508 return (__itt_counter)h;
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)
514 __itt_counter_info_t *h_tail = NULL, *h = NULL;
521 ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global));
522 if (_N_(_ittapi_global).api_initialized)
524 if (ITTNOTIFY_NAME(counter_create_typedW) && ITTNOTIFY_NAME(counter_create_typedW) != ITT_VERSIONIZE(ITT_JOIN(_N_(counter_create_typedW),_init)))
526 __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
527 return ITTNOTIFY_NAME(counter_create_typedW)(name, domain, type);
530 for (h_tail = NULL, h = _N_(_ittapi_global).counter_list; h != NULL; h_tail = h, h = h->next)
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;
538 NEW_COUNTER_W(&_N_(_ittapi_global),h,h_tail,name,domain,type);
540 __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
541 return (__itt_counter)h;
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 */
549 __itt_counter_info_t *h_tail = NULL, *h = NULL;
556 ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global));
557 if (_N_(_ittapi_global).api_initialized)
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)))
562 __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
563 return ITTNOTIFY_NAME(counter_create_typedA)(name, domain, type);
566 if (ITTNOTIFY_NAME(counter_create_typed) && ITTNOTIFY_NAME(counter_create_typed) != ITT_VERSIONIZE(ITT_JOIN(_N_(counter_create_typed),_init)))
568 if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
569 return ITTNOTIFY_NAME(counter_create_typed)(name, domain, type);
573 for (h_tail = NULL, h = _N_(_ittapi_global).counter_list; h != NULL; h_tail = h, h = h->next)
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;
580 NEW_COUNTER_A(&_N_(_ittapi_global),h,h_tail,name,domain,type);
582 if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
583 return (__itt_counter)h;
586 /* -------------------------------------------------------------------------- */
588 static void ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(pause),_init))(void)
590 if (!_N_(_ittapi_global).api_initialized && _N_(_ittapi_global).thread_list == NULL)
592 __itt_init_ittlib_name(NULL, __itt_group_all);
594 if (ITTNOTIFY_NAME(pause) && ITTNOTIFY_NAME(pause) != ITT_VERSIONIZE(ITT_JOIN(_N_(pause),_init)))
596 ITTNOTIFY_NAME(pause)();
600 _N_(_ittapi_global).state = __itt_collection_paused;
604 static void ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(resume),_init))(void)
606 if (!_N_(_ittapi_global).api_initialized && _N_(_ittapi_global).thread_list == NULL)
608 __itt_init_ittlib_name(NULL, __itt_group_all);
610 if (ITTNOTIFY_NAME(resume) && ITTNOTIFY_NAME(resume) != ITT_VERSIONIZE(ITT_JOIN(_N_(resume),_init)))
612 ITTNOTIFY_NAME(resume)();
616 _N_(_ittapi_global).state = __itt_collection_normal;
620 #if ITT_PLATFORM==ITT_PLATFORM_WIN
621 static void ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_nameW),_init))(const wchar_t* name)
623 if (!_N_(_ittapi_global).api_initialized && _N_(_ittapi_global).thread_list == NULL)
625 __itt_init_ittlib_name(NULL, __itt_group_all);
627 if (ITTNOTIFY_NAME(thread_set_nameW) && ITTNOTIFY_NAME(thread_set_nameW) != ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_nameW),_init)))
629 ITTNOTIFY_NAME(thread_set_nameW)(name);
633 static int ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(thr_name_setW),_init))(const wchar_t* name, int namelen)
636 ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_nameW),_init))(name);
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 */
645 if (!_N_(_ittapi_global).api_initialized && _N_(_ittapi_global).thread_list == NULL)
647 __itt_init_ittlib_name(NULL, __itt_group_all);
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)))
652 ITTNOTIFY_NAME(thread_set_nameA)(name);
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)))
657 ITTNOTIFY_NAME(thread_set_name)(name);
659 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
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)
666 ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_nameA),_init))(name);
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)
673 ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_name),_init))(name);
676 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
678 static void ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(thread_ignore),_init))(void)
680 if (!_N_(_ittapi_global).api_initialized && _N_(_ittapi_global).thread_list == NULL)
682 __itt_init_ittlib_name(NULL, __itt_group_all);
684 if (ITTNOTIFY_NAME(thread_ignore) && ITTNOTIFY_NAME(thread_ignore) != ITT_VERSIONIZE(ITT_JOIN(_N_(thread_ignore),_init)))
686 ITTNOTIFY_NAME(thread_ignore)();
690 static void ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(thr_ignore),_init))(void)
692 ITT_VERSIONIZE(ITT_JOIN(_N_(thread_ignore),_init))();
695 static void ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(enable_attach),_init))(void)
699 * if LIB_VAR_NAME env variable were set before then stay previous value
700 * else set default path
702 setenv(ITT_TO_STR(LIB_VAR_NAME), ANDROID_ITTNOTIFY_DEFAULT_PATH, 0);
706 /* -------------------------------------------------------------------------- */
708 static const char* __itt_fsplit(const char* s, const char* sep, const char** out, int* len)
713 if (!s || !sep || !out || !len)
716 for (i = 0; s[i]; i++)
719 for (j = 0; sep[j]; j++)
735 for (; s[i]; i++, (*len)++)
738 for (j = 0; sep[j]; j++)
751 for (j = 0; sep[j]; j++)
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.
769 static const char* __itt_get_env_var(const char* name)
771 #define MAX_ENV_VALUE_SIZE 4086
772 static char env_buff[MAX_ENV_VALUE_SIZE];
773 static char* env_value = (char*)env_buff;
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);
781 __itt_report_error(__itt_error_env_too_long, name, (size_t)rc - 1, (size_t)(max_len - 1));
784 const char* ret = (const char*)env_value;
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)
797 if (err != ERROR_ENVVAR_NOT_FOUND)
798 __itt_report_error(__itt_error_cant_read_env, name, (int)err);
800 #else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */
801 char* env = getenv(name);
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);
808 const char* ret = (const char*)env_value;
809 __itt_fstrcpyn(env_value, max_len, env, len + 1);
810 env_value += len + 1;
813 __itt_report_error(__itt_error_env_too_long, name, (size_t)len, (size_t)(max_len - 1));
815 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
820 static const char* __itt_get_lib_name(void)
822 const char* lib_name = __itt_get_env_var(ITT_TO_STR(LIB_VAR_NAME));
825 if (lib_name == NULL)
828 #if ITT_ARCH==ITT_ARCH_IA32 || ITT_ARCH==ITT_ARCH_ARM
829 const char* const marker_filename = "com.intel.itt.collector_lib_32";
831 const char* const marker_filename = "com.intel.itt.collector_lib_64";
834 char system_wide_marker_filename[PATH_MAX] = {0};
835 int itt_marker_file_fd = -1;
838 res = snprintf(system_wide_marker_filename, PATH_MAX - 1, "%s%s", "/data/local/tmp/", marker_filename);
841 ITT_ANDROID_LOGE("Unable to concatenate marker file string.");
844 itt_marker_file_fd = open(system_wide_marker_filename, O_RDONLY);
846 if (itt_marker_file_fd == -1)
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};
854 ITT_ANDROID_LOGI("Unable to open system-wide marker file.");
855 res = snprintf(cmdline_path, PATH_MAX - 1, "/proc/%d/cmdline", my_pid);
858 ITT_ANDROID_LOGE("Unable to get cmdline path string.");
862 ITT_ANDROID_LOGI("CMD file: %s\n", cmdline_path);
863 cmdline_fd = open(cmdline_path, O_RDONLY);
864 if (cmdline_fd == -1)
866 ITT_ANDROID_LOGE("Unable to open %s file!", cmdline_path);
869 res = read(cmdline_fd, package_name, PATH_MAX - 1);
872 ITT_ANDROID_LOGE("Unable to read %s file!", cmdline_path);
873 res = close(cmdline_fd);
876 ITT_ANDROID_LOGE("Unable to close %s file!", cmdline_path);
880 res = close(cmdline_fd);
883 ITT_ANDROID_LOGE("Unable to close %s file!", cmdline_path);
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);
890 ITT_ANDROID_LOGE("Unable to concatenate marker file string.");
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)
898 ITT_ANDROID_LOGE("Unable to open app marker file!");
904 char itt_lib_name[PATH_MAX] = {0};
906 res = read(itt_marker_file_fd, itt_lib_name, PATH_MAX - 1);
909 ITT_ANDROID_LOGE("Unable to read %s file!", itt_marker_file_fd);
910 res = close(itt_marker_file_fd);
913 ITT_ANDROID_LOGE("Unable to close %s file!", itt_marker_file_fd);
917 ITT_ANDROID_LOGI("ITT Lib path: %s", itt_lib_name);
918 res = close(itt_marker_file_fd);
921 ITT_ANDROID_LOGE("Unable to close %s file!", itt_marker_file_fd);
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);
928 ITT_ANDROID_LOGE("Unable to set env var!");
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);
940 /* Avoid clashes with std::min, reported by tbb team */
941 #define __itt_min(a,b) (a) < (b) ? (a) : (b)
943 static __itt_group_id __itt_get_groups(void)
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);
950 if (group_str != NULL)
955 while ((group_str = __itt_fsplit(group_str, ",; ", &chunk, &len)) != NULL)
957 int min_len = __itt_min(len, (int)(sizeof(gr) - 1));
958 __itt_fstrcpyn(gr, sizeof(gr) - 1, chunk, min_len);
961 for (i = 0; group_list[i].name != NULL; i++)
963 if (!__itt_fstrcmp(gr, group_list[i].name))
965 res = (__itt_group_id)(res | group_list[i].id);
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);
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;
992 static int __itt_lib_version(lib_t lib)
996 if (__itt_get_proc(lib, "__itt_api_init"))
998 if (__itt_get_proc(lib, "__itt_api_version"))
1003 /* It's not used right now! Comment it out to avoid warnings.
1004 static void __itt_reinit_all_pointers(void)
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;
1013 static void __itt_nullify_all_pointers(void)
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;
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 */
1027 ITT_EXTERN_C void _N_(fini_ittlib)(void)
1029 __itt_api_fini_t* __itt_api_fini_ptr = NULL;
1030 static volatile TIDT current_thread = 0;
1032 if (_N_(_ittapi_global).api_initialized)
1034 ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global));
1035 if (_N_(_ittapi_global).api_initialized)
1037 if (current_thread == 0)
1039 if (PTHREAD_SYMBOLS) current_thread = __itt_thread_id();
1040 if (_N_(_ittapi_global).lib != NULL)
1042 __itt_api_fini_ptr = (__itt_api_fini_t*)(size_t)__itt_get_proc(_N_(_ittapi_global).lib, "__itt_api_fini");
1044 if (__itt_api_fini_ptr)
1046 __itt_api_fini_ptr(&_N_(_ittapi_global));
1049 __itt_nullify_all_pointers();
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;
1056 _N_(_ittapi_global).api_initialized = 0;
1060 if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
1064 ITT_EXTERN_C int _N_(init_ittlib)(const char* lib_name, __itt_group_id init_groups)
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;
1073 if (!_N_(_ittapi_global).api_initialized)
1075 #ifndef ITT_SIMPLE_INIT
1076 ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global));
1077 #endif /* ITT_SIMPLE_INIT */
1079 if (!_N_(_ittapi_global).api_initialized)
1081 if (current_thread == 0)
1083 if (PTHREAD_SYMBOLS) current_thread = __itt_thread_id();
1084 if (lib_name == NULL)
1086 lib_name = __itt_get_lib_name();
1088 groups = __itt_get_groups();
1089 if (DL_SYMBOLS && (groups != __itt_group_none || lib_name != NULL))
1091 _N_(_ittapi_global).lib = __itt_load_lib((lib_name == NULL) ? ittnotify_lib_name : lib_name);
1093 if (_N_(_ittapi_global).lib != NULL)
1095 __itt_api_init_t* __itt_api_init_ptr;
1096 int lib_version = __itt_lib_version(_N_(_ittapi_global).lib);
1098 switch (lib_version) {
1100 groups = __itt_group_legacy;
1102 /* Fill all pointers from dynamic library */
1103 for (i = 0; _N_(_ittapi_global).api_list_ptr[i].name != NULL; i++)
1105 if (_N_(_ittapi_global).api_list_ptr[i].group & groups & init_groups)
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)
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 */
1119 *_N_(_ittapi_global).api_list_ptr[i].func_ptr = _N_(_ittapi_global).api_list_ptr[i].null_func;
1122 if (groups == __itt_group_legacy)
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);
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 */
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);
1153 __itt_nullify_all_pointers();
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 */
1160 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
1166 __itt_nullify_all_pointers();
1168 _N_(_ittapi_global).api_initialized = 1;
1170 /* !!! Just to avoid unused code elimination !!! */
1171 if (__itt_fini_ittlib_ptr == _N_(fini_ittlib)) current_thread = 0;
1175 #ifndef ITT_SIMPLE_INIT
1176 if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
1177 #endif /* ITT_SIMPLE_INIT */
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++)
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)
1192 ITT_EXTERN_C __itt_error_handler_t* _N_(set_error_handler)(__itt_error_handler_t* handler)
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;
1199 #if ITT_PLATFORM==ITT_PLATFORM_WIN && KMP_MSVC_COMPAT
1200 #pragma warning(pop)
1201 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */