1/*
2 Copyright (C) 2005-2019 Intel Corporation
3
4 SPDX-License-Identifier: GPL-2.0-only OR BSD-3-Clause
5*/
6
7#define INTEL_NO_MACRO_BODY
8#define INTEL_ITTNOTIFY_API_PRIVATE
9#include "ittnotify_config.h"
10
11#if ITT_PLATFORM==ITT_PLATFORM_WIN
12#if !defined(PATH_MAX)
13#define PATH_MAX 512
14#endif
15#else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */
16#include <limits.h>
17#include <dlfcn.h>
18#include <errno.h>
19#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
20#include <stdio.h>
21#include <stdlib.h>
22#include <stdarg.h>
23#include <string.h>
24
25#include "ittnotify.h"
26#include "legacy/ittnotify.h"
27
28#include "disable_warnings.h"
29
30static const char api_version[] = API_VERSION "\0\n@(#) $Revision$\n";
31
32#define _N_(n) ITT_JOIN(INTEL_ITTNOTIFY_PREFIX,n)
33
34#ifndef HAS_CPP_ATTR
35#if defined(__cplusplus) && defined(__has_cpp_attribute)
36#define HAS_CPP_ATTR(X) __has_cpp_attribute(X)
37#else
38#define HAS_CPP_ATTR(X) 0
39#endif
40#endif
41
42#ifndef HAS_C_ATTR
43#if defined(__STDC__) && defined(__has_c_attribute)
44#define HAS_C_ATTR(X) __has_c_attribute(X)
45#else
46#define HAS_C_ATTR(X) 0
47#endif
48#endif
49
50#ifndef HAS_GNU_ATTR
51#if defined(__has_attribute)
52#define HAS_GNU_ATTR(X) __has_attribute(X)
53#else
54#define HAS_GNU_ATTR(X) 0
55#endif
56#endif
57
58#ifndef ITT_ATTRIBUTE_FALLTHROUGH
59#if (HAS_CPP_ATTR(fallthrough) || HAS_C_ATTR(fallthrough)) && (__cplusplus >= 201703L || _MSVC_LANG >= 201703L)
60#define ITT_ATTRIBUTE_FALLTHROUGH [[fallthrough]]
61#elif HAS_CPP_ATTR(gnu::fallthrough)
62#define ITT_ATTRIBUTE_FALLTHROUGH [[gnu::fallthrough]]
63#elif HAS_CPP_ATTR(clang::fallthrough)
64#define ITT_ATTRIBUTE_FALLTHROUGH [[clang::fallthrough]]
65#elif HAS_GNU_ATTR(fallthrough) && !__INTEL_COMPILER
66#define ITT_ATTRIBUTE_FALLTHROUGH __attribute__((fallthrough))
67#else
68#define ITT_ATTRIBUTE_FALLTHROUGH
69#endif
70#endif
71
72#if ITT_OS==ITT_OS_WIN
73static const char* ittnotify_lib_name = "libittnotify.dll";
74#elif ITT_OS==ITT_OS_LINUX || ITT_OS==ITT_OS_FREEBSD
75static const char* ittnotify_lib_name = "libittnotify.so";
76#elif ITT_OS==ITT_OS_MAC
77static const char* ittnotify_lib_name = "libittnotify.dylib";
78#else
79#error Unsupported or unknown OS.
80#endif
81
82#ifdef __ANDROID__
83#include <android/log.h>
84#include <stdio.h>
85#include <unistd.h>
86#include <sys/types.h>
87#include <sys/stat.h>
88#include <fcntl.h>
89#include <linux/limits.h>
90
91#ifdef ITT_ANDROID_LOG
92 #define ITT_ANDROID_LOG_TAG "INTEL_VTUNE_USERAPI"
93 #define ITT_ANDROID_LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, ITT_ANDROID_LOG_TAG, __VA_ARGS__))
94 #define ITT_ANDROID_LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, ITT_ANDROID_LOG_TAG, __VA_ARGS__))
95 #define ITT_ANDROID_LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR,ITT_ANDROID_LOG_TAG, __VA_ARGS__))
96 #define ITT_ANDROID_LOGD(...) ((void)__android_log_print(ANDROID_LOG_DEBUG,ITT_ANDROID_LOG_TAG, __VA_ARGS__))
97#else
98 #define ITT_ANDROID_LOGI(...)
99 #define ITT_ANDROID_LOGW(...)
100 #define ITT_ANDROID_LOGE(...)
101 #define ITT_ANDROID_LOGD(...)
102#endif
103
104/* default location of userapi collector on Android */
105#define ANDROID_ITTNOTIFY_DEFAULT_PATH_MASK(x) "/data/data/com.intel.vtune/perfrun/lib" \
106 #x "/runtime/libittnotify.so"
107
108#if ITT_ARCH==ITT_ARCH_IA32 || ITT_ARCH==ITT_ARCH_ARM
109#define ANDROID_ITTNOTIFY_DEFAULT_PATH ANDROID_ITTNOTIFY_DEFAULT_PATH_MASK(32)
110#else
111#define ANDROID_ITTNOTIFY_DEFAULT_PATH ANDROID_ITTNOTIFY_DEFAULT_PATH_MASK(64)
112#endif
113
114#endif
115
116
117#ifndef LIB_VAR_NAME
118#if ITT_ARCH==ITT_ARCH_IA32 || ITT_ARCH==ITT_ARCH_ARM
119#define LIB_VAR_NAME INTEL_LIBITTNOTIFY32
120#else
121#define LIB_VAR_NAME INTEL_LIBITTNOTIFY64
122#endif
123#endif /* LIB_VAR_NAME */
124
125#define ITT_MUTEX_INIT_AND_LOCK(p) { \
126 if (PTHREAD_SYMBOLS) \
127 { \
128 if (!p.mutex_initialized) \
129 { \
130 if (__itt_interlocked_compare_exchange(&p.atomic_counter, 1, 0) == 0) \
131 { \
132 __itt_mutex_init(&p.mutex); \
133 p.mutex_initialized = 1; \
134 } \
135 else \
136 while (!p.mutex_initialized) \
137 __itt_thread_yield(); \
138 } \
139 __itt_mutex_lock(&p.mutex); \
140 } \
141}
142
143#define ITT_MUTEX_DESTROY(p) { \
144 if (PTHREAD_SYMBOLS) \
145 { \
146 if (p.mutex_initialized) \
147 { \
148 if (__itt_interlocked_compare_exchange(&p.atomic_counter, 0, 1) == 1) \
149 { \
150 __itt_mutex_destroy(&p.mutex); \
151 p.mutex_initialized = 0; \
152 } \
153 } \
154 } \
155}
156
157#define ITT_MODULE_OBJECT_VERSION 1
158
159typedef int (__itt_init_ittlib_t)(const char*, __itt_group_id);
160
161/* this define used to control initialization function name. */
162#ifndef __itt_init_ittlib_name
163ITT_EXTERN_C int _N_(init_ittlib)(const char*, __itt_group_id);
164static __itt_init_ittlib_t* __itt_init_ittlib_ptr = _N_(init_ittlib);
165#define __itt_init_ittlib_name __itt_init_ittlib_ptr
166#endif /* __itt_init_ittlib_name */
167
168typedef void (__itt_fini_ittlib_t)(void);
169
170/* this define used to control finalization function name. */
171#ifndef __itt_fini_ittlib_name
172ITT_EXTERN_C void _N_(fini_ittlib)(void);
173static __itt_fini_ittlib_t* __itt_fini_ittlib_ptr = _N_(fini_ittlib);
174#define __itt_fini_ittlib_name __itt_fini_ittlib_ptr
175#endif /* __itt_fini_ittlib_name */
176
177extern __itt_global _N_(_ittapi_global);
178
179/* building pointers to imported funcs */
180#undef ITT_STUBV
181#undef ITT_STUB
182#define ITT_STUB(api,type,name,args,params,ptr,group,format) \
183static type api ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init)) args;\
184typedef type api ITT_JOIN(_N_(name),_t) args; \
185ITT_EXTERN_C_BEGIN ITT_JOIN(_N_(name),_t)* ITTNOTIFY_NAME(name) = ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init)); ITT_EXTERN_C_END \
186static type api ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init)) args \
187{ \
188 if (!_N_(_ittapi_global).api_initialized && _N_(_ittapi_global).thread_list == NULL) \
189 __itt_init_ittlib_name(NULL, __itt_group_all); \
190 if (ITTNOTIFY_NAME(name) && ITTNOTIFY_NAME(name) != ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init))) \
191 return ITTNOTIFY_NAME(name) params; \
192 else \
193 return (type)0; \
194}
195
196#define ITT_STUBV(api,type,name,args,params,ptr,group,format) \
197static type api ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init)) args;\
198typedef type api ITT_JOIN(_N_(name),_t) args; \
199ITT_EXTERN_C_BEGIN ITT_JOIN(_N_(name),_t)* ITTNOTIFY_NAME(name) = ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init)); ITT_EXTERN_C_END \
200static type api ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init)) args \
201{ \
202 if (!_N_(_ittapi_global).api_initialized && _N_(_ittapi_global).thread_list == NULL) \
203 __itt_init_ittlib_name(NULL, __itt_group_all); \
204 if (ITTNOTIFY_NAME(name) && ITTNOTIFY_NAME(name) != ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init))) \
205 ITTNOTIFY_NAME(name) params; \
206 else \
207 return; \
208}
209
210#undef __ITT_INTERNAL_INIT
211#include "ittnotify_static.h"
212
213#undef ITT_STUB
214#undef ITT_STUBV
215#define ITT_STUB(api,type,name,args,params,ptr,group,format) \
216static type api ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init)) args;\
217typedef type api ITT_JOIN(_N_(name),_t) args; \
218ITT_EXTERN_C_BEGIN ITT_JOIN(_N_(name),_t)* ITTNOTIFY_NAME(name) = ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init)); ITT_EXTERN_C_END
219
220#define ITT_STUBV(api,type,name,args,params,ptr,group,format) \
221static type api ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init)) args;\
222typedef type api ITT_JOIN(_N_(name),_t) args; \
223ITT_EXTERN_C_BEGIN ITT_JOIN(_N_(name),_t)* ITTNOTIFY_NAME(name) = ITT_VERSIONIZE(ITT_JOIN(_N_(name),_init)); ITT_EXTERN_C_END
224
225#define __ITT_INTERNAL_INIT
226#include "ittnotify_static.h"
227#undef __ITT_INTERNAL_INIT
228
229ITT_GROUP_LIST(group_list);
230
231#pragma pack(push, 8)
232
233typedef struct ___itt_group_alias
234{
235 const char* env_var;
236 __itt_group_id groups;
237} __itt_group_alias;
238
239static __itt_group_alias group_alias[] = {
240 { "KMP_FOR_TPROFILE", (__itt_group_id)(__itt_group_control | __itt_group_thread | __itt_group_sync | __itt_group_mark) },
241 { "KMP_FOR_TCHECK", (__itt_group_id)(__itt_group_control | __itt_group_thread | __itt_group_sync | __itt_group_fsync | __itt_group_mark | __itt_group_suppress) },
242 { NULL, (__itt_group_none) },
243 { api_version, (__itt_group_none) } /* !!! Just to avoid unused code elimination !!! */
244};
245
246#pragma pack(pop)
247
248#if ITT_PLATFORM==ITT_PLATFORM_WIN
249#if _MSC_VER
250#pragma warning(push)
251#pragma warning(disable: 4054) /* warning C4054: 'type cast' : from function pointer 'XXX' to data pointer 'void *' */
252#endif
253#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
254
255static __itt_api_info api_list[] = {
256/* Define functions with static implementation */
257#undef ITT_STUB
258#undef ITT_STUBV
259#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)},
260#define ITT_STUBV ITT_STUB
261#define __ITT_INTERNAL_INIT
262#include "ittnotify_static.h"
263#undef __ITT_INTERNAL_INIT
264/* Define functions without static implementation */
265#undef ITT_STUB
266#undef ITT_STUBV
267#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)},
268#define ITT_STUBV ITT_STUB
269#include "ittnotify_static.h"
270 {NULL, NULL, NULL, NULL, __itt_group_none}
271};
272
273#if ITT_PLATFORM==ITT_PLATFORM_WIN
274#if _MSC_VER
275#pragma warning(pop)
276#endif
277#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
278
279/* static part descriptor which handles. all notification api attributes. */
280__itt_global _N_(_ittapi_global) = {
281 ITT_MAGIC, /* identification info */
282 ITT_MAJOR, ITT_MINOR, API_VERSION_BUILD, /* version info */
283 0, /* api_initialized */
284 0, /* mutex_initialized */
285 0, /* atomic_counter */
286 MUTEX_INITIALIZER, /* mutex */
287 NULL, /* dynamic library handle */
288 NULL, /* error_handler */
289 NULL, /* dll_path_ptr */
290 (__itt_api_info*)&api_list, /* api_list_ptr */
291 NULL, /* next __itt_global */
292 NULL, /* thread_list */
293 NULL, /* domain_list */
294 NULL, /* string_list */
295 __itt_collection_uninitialized, /* collection state */
296 NULL, /* counter_list */
297 0, /* ipt_collect_events */
298 NULL /* histogram_list */
299};
300
301typedef void (__itt_api_init_t)(__itt_global*, __itt_group_id);
302typedef void (__itt_api_fini_t)(__itt_global*);
303
304static __itt_domain dummy_domain;
305/* ========================================================================= */
306
307#ifdef ITT_NOTIFY_EXT_REPORT
308ITT_EXTERN_C void _N_(error_handler)(__itt_error_code, va_list args);
309#endif /* ITT_NOTIFY_EXT_REPORT */
310
311#if ITT_PLATFORM==ITT_PLATFORM_WIN
312#if _MSC_VER
313#pragma warning(push)
314#pragma warning(disable: 4055) /* warning C4055: 'type cast' : from data pointer 'void *' to function pointer 'XXX' */
315#endif
316#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
317
318static void __itt_report_error(int code, ...)
319{
320 va_list args;
321 va_start(args, code);
322 if (_N_(_ittapi_global).error_handler != NULL)
323 {
324 __itt_error_handler_t* handler = (__itt_error_handler_t*)(size_t)_N_(_ittapi_global).error_handler;
325 handler((__itt_error_code)code, args);
326 }
327#ifdef ITT_NOTIFY_EXT_REPORT
328 _N_(error_handler)((__itt_error_code)code, args);
329#endif /* ITT_NOTIFY_EXT_REPORT */
330 va_end(args);
331}
332
333static int __itt_is_collector_available(void);
334
335#if ITT_PLATFORM==ITT_PLATFORM_WIN
336#if _MSC_VER
337#pragma warning(pop)
338#endif
339#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
340
341#if ITT_PLATFORM==ITT_PLATFORM_WIN
342static __itt_domain* ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(domain_createW),_init))(const wchar_t* name)
343{
344 __itt_domain *h_tail = NULL, *h = NULL;
345
346 if (name == NULL)
347 {
348 return NULL;
349 }
350
351 ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global));
352 if (_N_(_ittapi_global).api_initialized)
353 {
354 if (ITTNOTIFY_NAME(domain_createW) && ITTNOTIFY_NAME(domain_createW) != ITT_VERSIONIZE(ITT_JOIN(_N_(domain_createW),_init)))
355 {
356 __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
357 return ITTNOTIFY_NAME(domain_createW)(name);
358 }
359 else
360 {
361 __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
362 return &dummy_domain;
363 }
364 }
365 if (__itt_is_collector_available())
366 {
367 for (h_tail = NULL, h = _N_(_ittapi_global).domain_list; h != NULL; h_tail = h, h = h->next)
368 {
369 if (h->nameW != NULL && !wcscmp(h->nameW, name)) break;
370 }
371 if (h == NULL)
372 {
373 NEW_DOMAIN_W(&_N_(_ittapi_global), h, h_tail, name);
374 }
375 }
376 if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
377 return h;
378}
379
380static __itt_domain* ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(domain_createA),_init))(const char* name)
381#else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */
382static __itt_domain* ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(domain_create),_init))(const char* name)
383#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
384{
385 __itt_domain *h_tail = NULL, *h = NULL;
386
387 if (name == NULL)
388 {
389 return NULL;
390 }
391
392 ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global));
393 if (_N_(_ittapi_global).api_initialized)
394 {
395#if ITT_PLATFORM==ITT_PLATFORM_WIN
396 if (ITTNOTIFY_NAME(domain_createA) && ITTNOTIFY_NAME(domain_createA) != ITT_VERSIONIZE(ITT_JOIN(_N_(domain_createA),_init)))
397 {
398 __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
399 return ITTNOTIFY_NAME(domain_createA)(name);
400 }
401#else
402 if (ITTNOTIFY_NAME(domain_create) && ITTNOTIFY_NAME(domain_create) != ITT_VERSIONIZE(ITT_JOIN(_N_(domain_create),_init)))
403 {
404 if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
405 return ITTNOTIFY_NAME(domain_create)(name);
406 }
407#endif
408 else
409 {
410#if ITT_PLATFORM==ITT_PLATFORM_WIN
411 __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
412#else
413 if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
414#endif
415 return &dummy_domain;
416 }
417 }
418 if (__itt_is_collector_available())
419 {
420 for (h_tail = NULL, h = _N_(_ittapi_global).domain_list; h != NULL; h_tail = h, h = h->next)
421 {
422 if (h->nameA != NULL && !__itt_fstrcmp(h->nameA, name)) break;
423 }
424 if (h == NULL)
425 {
426 NEW_DOMAIN_A(&_N_(_ittapi_global), h, h_tail, name);
427 }
428 }
429 if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
430 return h;
431}
432
433static void ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(module_load_with_sections),_init))(__itt_module_object* module_obj)
434{
435 if (!_N_(_ittapi_global).api_initialized && _N_(_ittapi_global).thread_list == NULL)
436 {
437 __itt_init_ittlib_name(NULL, __itt_group_all);
438 }
439 if (ITTNOTIFY_NAME(module_load_with_sections) && ITTNOTIFY_NAME(module_load_with_sections) != ITT_VERSIONIZE(ITT_JOIN(_N_(module_load_with_sections),_init)))
440 {
441 if(module_obj != NULL)
442 {
443 module_obj->version = ITT_MODULE_OBJECT_VERSION;
444 ITTNOTIFY_NAME(module_load_with_sections)(module_obj);
445 }
446 }
447}
448
449static void ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(module_unload_with_sections),_init))(__itt_module_object* module_obj)
450{
451 if (!_N_(_ittapi_global).api_initialized && _N_(_ittapi_global).thread_list == NULL)
452 {
453 __itt_init_ittlib_name(NULL, __itt_group_all);
454 }
455 if (ITTNOTIFY_NAME(module_unload_with_sections) && ITTNOTIFY_NAME(module_unload_with_sections) != ITT_VERSIONIZE(ITT_JOIN(_N_(module_unload_with_sections),_init)))
456 {
457 if(module_obj != NULL)
458 {
459 module_obj->version = ITT_MODULE_OBJECT_VERSION;
460 ITTNOTIFY_NAME(module_unload_with_sections)(module_obj);
461 }
462 }
463}
464
465#if ITT_PLATFORM==ITT_PLATFORM_WIN
466static __itt_string_handle* ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(string_handle_createW),_init))(const wchar_t* name)
467{
468 __itt_string_handle *h_tail = NULL, *h = NULL;
469
470 if (name == NULL)
471 {
472 return NULL;
473 }
474
475 ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global));
476 if (_N_(_ittapi_global).api_initialized)
477 {
478 if (ITTNOTIFY_NAME(string_handle_createW) && ITTNOTIFY_NAME(string_handle_createW) != ITT_VERSIONIZE(ITT_JOIN(_N_(string_handle_createW),_init)))
479 {
480 __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
481 return ITTNOTIFY_NAME(string_handle_createW)(name);
482 }
483 else
484 {
485 __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
486 return NULL;
487 }
488 }
489 if (__itt_is_collector_available())
490 {
491 for (h_tail = NULL, h = _N_(_ittapi_global).string_list; h != NULL; h_tail = h, h = h->next)
492 {
493 if (h->strW != NULL && !wcscmp(h->strW, name)) break;
494 }
495 if (h == NULL)
496 {
497 NEW_STRING_HANDLE_W(&_N_(_ittapi_global), h, h_tail, name);
498 }
499 }
500 __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
501 return h;
502}
503
504static __itt_string_handle* ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(string_handle_createA),_init))(const char* name)
505#else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */
506static __itt_string_handle* ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(string_handle_create),_init))(const char* name)
507#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
508{
509 __itt_string_handle *h_tail = NULL, *h = NULL;
510
511 if (name == NULL)
512 {
513 return NULL;
514 }
515
516 ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global));
517 if (_N_(_ittapi_global).api_initialized)
518 {
519#if ITT_PLATFORM==ITT_PLATFORM_WIN
520 if (ITTNOTIFY_NAME(string_handle_createA) && ITTNOTIFY_NAME(string_handle_createA) != ITT_VERSIONIZE(ITT_JOIN(_N_(string_handle_createA),_init)))
521 {
522 __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
523 return ITTNOTIFY_NAME(string_handle_createA)(name);
524 }
525#else
526 if (ITTNOTIFY_NAME(string_handle_create) && ITTNOTIFY_NAME(string_handle_create) != ITT_VERSIONIZE(ITT_JOIN(_N_(string_handle_create),_init)))
527 {
528 if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
529 return ITTNOTIFY_NAME(string_handle_create)(name);
530 }
531#endif
532 else
533 {
534#if ITT_PLATFORM==ITT_PLATFORM_WIN
535 __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
536#else
537 if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
538#endif
539 return NULL;
540 }
541 }
542 if (__itt_is_collector_available())
543 {
544 for (h_tail = NULL, h = _N_(_ittapi_global).string_list; h != NULL; h_tail = h, h = h->next)
545 {
546 if (h->strA != NULL && !__itt_fstrcmp(h->strA, name)) break;
547 }
548 if (h == NULL)
549 {
550 NEW_STRING_HANDLE_A(&_N_(_ittapi_global), h, h_tail, name);
551 }
552 }
553 if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
554 return h;
555}
556
557#if ITT_PLATFORM==ITT_PLATFORM_WIN
558static __itt_counter ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(counter_createW),_init))(const wchar_t *name, const wchar_t *domain)
559{
560 __itt_counter_info_t *h_tail = NULL, *h = NULL;
561 __itt_metadata_type type = __itt_metadata_u64;
562
563 if (name == NULL)
564 {
565 return NULL;
566 }
567
568 ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global));
569 if (_N_(_ittapi_global).api_initialized)
570 {
571 if (ITTNOTIFY_NAME(counter_createW) && ITTNOTIFY_NAME(counter_createW) != ITT_VERSIONIZE(ITT_JOIN(_N_(counter_createW),_init)))
572 {
573 __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
574 return ITTNOTIFY_NAME(counter_createW)(name, domain);
575 }
576 else
577 {
578 __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
579 return NULL;
580 }
581 }
582 if (__itt_is_collector_available())
583 {
584 for (h_tail = NULL, h = _N_(_ittapi_global).counter_list; h != NULL; h_tail = h, h = h->next)
585 {
586 if (h->nameW != NULL && h->type == (int)type && !wcscmp(h->nameW, name) && ((h->domainW == NULL && domain == NULL) ||
587 (h->domainW != NULL && domain != NULL && !wcscmp(h->domainW, domain)))) break;
588
589 }
590 if (h == NULL)
591 {
592 NEW_COUNTER_W(&_N_(_ittapi_global), h, h_tail, name, domain, type);
593 }
594 }
595 __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
596 return (__itt_counter)h;
597}
598
599static __itt_counter ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(counter_createA),_init))(const char *name, const char *domain)
600#else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */
601static __itt_counter ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(counter_create),_init))(const char *name, const char *domain)
602#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
603{
604 __itt_counter_info_t *h_tail = NULL, *h = NULL;
605 __itt_metadata_type type = __itt_metadata_u64;
606
607 if (name == NULL)
608 {
609 return NULL;
610 }
611
612 ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global));
613 if (_N_(_ittapi_global).api_initialized)
614 {
615#if ITT_PLATFORM==ITT_PLATFORM_WIN
616 if (ITTNOTIFY_NAME(counter_createA) && ITTNOTIFY_NAME(counter_createA) != ITT_VERSIONIZE(ITT_JOIN(_N_(counter_createA),_init)))
617 {
618 __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
619 return ITTNOTIFY_NAME(counter_createA)(name, domain);
620 }
621#else
622 if (ITTNOTIFY_NAME(counter_create) && ITTNOTIFY_NAME(counter_create) != ITT_VERSIONIZE(ITT_JOIN(_N_(counter_create),_init)))
623 {
624 if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
625 return ITTNOTIFY_NAME(counter_create)(name, domain);
626 }
627#endif
628 else
629 {
630#if ITT_PLATFORM==ITT_PLATFORM_WIN
631 __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
632#else
633 if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
634#endif
635 return NULL;
636 }
637 }
638 if (__itt_is_collector_available())
639 {
640 for (h_tail = NULL, h = _N_(_ittapi_global).counter_list; h != NULL; h_tail = h, h = h->next)
641 {
642 if (h->nameA != NULL && h->type == (int)type && !__itt_fstrcmp(h->nameA, name) && ((h->domainA == NULL && domain == NULL) ||
643 (h->domainA != NULL && domain != NULL && !__itt_fstrcmp(h->domainA, domain)))) break;
644 }
645 if (h == NULL)
646 {
647 NEW_COUNTER_A(&_N_(_ittapi_global), h, h_tail, name, domain, type);
648 }
649 }
650 if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
651 return (__itt_counter)h;
652}
653
654#if ITT_PLATFORM==ITT_PLATFORM_WIN
655static __itt_counter ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(counter_create_typedW),_init))(const wchar_t *name, const wchar_t *domain, __itt_metadata_type type)
656{
657 __itt_counter_info_t *h_tail = NULL, *h = NULL;
658
659 if (name == NULL)
660 {
661 return NULL;
662 }
663
664 ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global));
665 if (_N_(_ittapi_global).api_initialized)
666 {
667 if (ITTNOTIFY_NAME(counter_create_typedW) && ITTNOTIFY_NAME(counter_create_typedW) != ITT_VERSIONIZE(ITT_JOIN(_N_(counter_create_typedW),_init)))
668 {
669 __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
670 return ITTNOTIFY_NAME(counter_create_typedW)(name, domain, type);
671 }
672 else
673 {
674 __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
675 return NULL;
676 }
677 }
678 if (__itt_is_collector_available())
679 {
680 for (h_tail = NULL, h = _N_(_ittapi_global).counter_list; h != NULL; h_tail = h, h = h->next)
681 {
682 if (h->nameW != NULL && h->type == (int)type && !wcscmp(h->nameW, name) && ((h->domainW == NULL && domain == NULL) ||
683 (h->domainW != NULL && domain != NULL && !wcscmp(h->domainW, domain)))) break;
684
685 }
686 if (h == NULL)
687 {
688 NEW_COUNTER_W(&_N_(_ittapi_global), h, h_tail, name, domain, type);
689 }
690 }
691 __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
692 return (__itt_counter)h;
693}
694
695static __itt_counter ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(counter_create_typedA),_init))(const char *name, const char *domain, __itt_metadata_type type)
696#else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */
697static __itt_counter ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(counter_create_typed),_init))(const char *name, const char *domain, __itt_metadata_type type)
698#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
699{
700 __itt_counter_info_t *h_tail = NULL, *h = NULL;
701
702 if (name == NULL)
703 {
704 return NULL;
705 }
706
707 ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global));
708 if (_N_(_ittapi_global).api_initialized)
709 {
710#if ITT_PLATFORM==ITT_PLATFORM_WIN
711 if (ITTNOTIFY_NAME(counter_create_typedA) && ITTNOTIFY_NAME(counter_create_typedA) != ITT_VERSIONIZE(ITT_JOIN(_N_(counter_create_typedA),_init)))
712 {
713 __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
714 return ITTNOTIFY_NAME(counter_create_typedA)(name, domain, type);
715 }
716#else
717 if (ITTNOTIFY_NAME(counter_create_typed) && ITTNOTIFY_NAME(counter_create_typed) != ITT_VERSIONIZE(ITT_JOIN(_N_(counter_create_typed),_init)))
718 {
719 if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
720 return ITTNOTIFY_NAME(counter_create_typed)(name, domain, type);
721 }
722#endif
723 else
724 {
725#if ITT_PLATFORM==ITT_PLATFORM_WIN
726 __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
727#else
728 if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
729#endif
730 return NULL;
731 }
732 }
733 if (__itt_is_collector_available())
734 {
735 for (h_tail = NULL, h = _N_(_ittapi_global).counter_list; h != NULL; h_tail = h, h = h->next)
736 {
737 if (h->nameA != NULL && h->type == (int)type && !__itt_fstrcmp(h->nameA, name) && ((h->domainA == NULL && domain == NULL) ||
738 (h->domainA != NULL && domain != NULL && !__itt_fstrcmp(h->domainA, domain)))) break;
739 }
740 if (h == NULL)
741 {
742 NEW_COUNTER_A(&_N_(_ittapi_global), h, h_tail, name, domain, type);
743 }
744 }
745 if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
746 return (__itt_counter)h;
747}
748
749#if ITT_PLATFORM==ITT_PLATFORM_WIN
750static __itt_histogram* ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(histogram_createW),_init))(const __itt_domain* domain, const wchar_t* name, __itt_metadata_type x_type, __itt_metadata_type y_type)
751{
752 __itt_histogram *h_tail = NULL, *h = NULL;
753
754 if (domain == NULL || name == NULL)
755 {
756 return NULL;
757 }
758
759 ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global));
760 if (_N_(_ittapi_global).api_initialized)
761 {
762 if (ITTNOTIFY_NAME(histogram_createW) && ITTNOTIFY_NAME(histogram_createW) != ITT_VERSIONIZE(ITT_JOIN(_N_(histogram_createW),_init)))
763 {
764 __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
765 return ITTNOTIFY_NAME(histogram_createW)(domain, name, x_type, y_type);
766 }
767 else
768 {
769 __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
770 return NULL;
771 }
772 }
773 if (__itt_is_collector_available())
774 {
775 for (h_tail = NULL, h = _N_(_ittapi_global).histogram_list; h != NULL; h_tail = h, h = h->next)
776 {
777 if (h->domain == NULL) continue;
778 else if (h->domain == domain && h->nameW != NULL && !wcscmp(h->nameW, name)) break;
779 }
780 if (h == NULL)
781 {
782 NEW_HISTOGRAM_W(&_N_(_ittapi_global), h, h_tail, domain, name, x_type, y_type);
783 }
784 }
785 __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
786 return (__itt_histogram*)h;
787}
788
789static __itt_histogram* ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(histogram_createA),_init))(const __itt_domain* domain, const char* name, __itt_metadata_type x_type, __itt_metadata_type y_type)
790#else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */
791static __itt_histogram* ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(histogram_create),_init))(const __itt_domain* domain, const char* name, __itt_metadata_type x_type, __itt_metadata_type y_type)
792#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
793{
794 __itt_histogram *h_tail = NULL, *h = NULL;
795
796 if (domain == NULL || name == NULL)
797 {
798 return NULL;
799 }
800
801 ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global));
802 if (_N_(_ittapi_global).api_initialized)
803 {
804#if ITT_PLATFORM==ITT_PLATFORM_WIN
805 if (ITTNOTIFY_NAME(histogram_createA) && ITTNOTIFY_NAME(histogram_createA) != ITT_VERSIONIZE(ITT_JOIN(_N_(histogram_createA),_init)))
806 {
807 __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
808 return ITTNOTIFY_NAME(histogram_createA)(domain, name, x_type, y_type);
809 }
810#else
811 if (ITTNOTIFY_NAME(histogram_create) && ITTNOTIFY_NAME(histogram_create) != ITT_VERSIONIZE(ITT_JOIN(_N_(histogram_create),_init)))
812 {
813 if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
814 return ITTNOTIFY_NAME(histogram_create)(domain, name, x_type, y_type);
815 }
816#endif
817 else
818 {
819#if ITT_PLATFORM==ITT_PLATFORM_WIN
820 __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
821#else
822 if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
823#endif
824 return NULL;
825 }
826 }
827 if (__itt_is_collector_available())
828 {
829 for (h_tail = NULL, h = _N_(_ittapi_global).histogram_list; h != NULL; h_tail = h, h = h->next)
830 {
831 if (h->domain == NULL) continue;
832 else if (h->domain == domain && h->nameA != NULL && !__itt_fstrcmp(h->nameA, name)) break;
833 }
834 if (h == NULL)
835 {
836 NEW_HISTOGRAM_A(&_N_(_ittapi_global), h, h_tail, domain, name, x_type, y_type);
837 }
838 }
839 if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
840 return (__itt_histogram*)h;
841}
842
843/* -------------------------------------------------------------------------- */
844
845static void ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(pause),_init))(void)
846{
847 if (!_N_(_ittapi_global).api_initialized && _N_(_ittapi_global).thread_list == NULL)
848 {
849 __itt_init_ittlib_name(NULL, __itt_group_all);
850 }
851 if (ITTNOTIFY_NAME(pause) && ITTNOTIFY_NAME(pause) != ITT_VERSIONIZE(ITT_JOIN(_N_(pause),_init)))
852 {
853 ITTNOTIFY_NAME(pause)();
854 }
855}
856
857static void ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(resume),_init))(void)
858{
859 if (!_N_(_ittapi_global).api_initialized && _N_(_ittapi_global).thread_list == NULL)
860 {
861 __itt_init_ittlib_name(NULL, __itt_group_all);
862 }
863 if (ITTNOTIFY_NAME(resume) && ITTNOTIFY_NAME(resume) != ITT_VERSIONIZE(ITT_JOIN(_N_(resume),_init)))
864 {
865 ITTNOTIFY_NAME(resume)();
866 }
867}
868
869#if ITT_PLATFORM==ITT_PLATFORM_WIN
870static void ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_nameW),_init))(const wchar_t* name)
871{
872 if (!_N_(_ittapi_global).api_initialized && _N_(_ittapi_global).thread_list == NULL)
873 {
874 __itt_init_ittlib_name(NULL, __itt_group_all);
875 }
876 if (ITTNOTIFY_NAME(thread_set_nameW) && ITTNOTIFY_NAME(thread_set_nameW) != ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_nameW),_init)))
877 {
878 ITTNOTIFY_NAME(thread_set_nameW)(name);
879 }
880}
881
882static int ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(thr_name_setW),_init))(const wchar_t* name, int namelen)
883{
884 (void)namelen;
885 ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_nameW),_init))(name);
886 return 0;
887}
888
889static void ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_nameA),_init))(const char* name)
890#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
891static void ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_name),_init))(const char* name)
892#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
893{
894 if (!_N_(_ittapi_global).api_initialized && _N_(_ittapi_global).thread_list == NULL)
895 {
896 __itt_init_ittlib_name(NULL, __itt_group_all);
897 }
898#if ITT_PLATFORM==ITT_PLATFORM_WIN
899 if (ITTNOTIFY_NAME(thread_set_nameA) && ITTNOTIFY_NAME(thread_set_nameA) != ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_nameA),_init)))
900 {
901 ITTNOTIFY_NAME(thread_set_nameA)(name);
902 }
903#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
904 if (ITTNOTIFY_NAME(thread_set_name) && ITTNOTIFY_NAME(thread_set_name) != ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_name),_init)))
905 {
906 ITTNOTIFY_NAME(thread_set_name)(name);
907 }
908#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
909}
910
911#if ITT_PLATFORM==ITT_PLATFORM_WIN
912static int ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(thr_name_setA),_init))(const char* name, int namelen)
913{
914 (void)namelen;
915 ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_nameA),_init))(name);
916 return 0;
917}
918#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
919static int ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(thr_name_set),_init))(const char* name, int namelen)
920{
921 (void)namelen;
922 ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_name),_init))(name);
923 return 0;
924}
925#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
926
927static void ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(thread_ignore),_init))(void)
928{
929 if (!_N_(_ittapi_global).api_initialized && _N_(_ittapi_global).thread_list == NULL)
930 {
931 __itt_init_ittlib_name(NULL, __itt_group_all);
932 }
933 if (ITTNOTIFY_NAME(thread_ignore) && ITTNOTIFY_NAME(thread_ignore) != ITT_VERSIONIZE(ITT_JOIN(_N_(thread_ignore),_init)))
934 {
935 ITTNOTIFY_NAME(thread_ignore)();
936 }
937}
938
939static void ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(thr_ignore),_init))(void)
940{
941 ITT_VERSIONIZE(ITT_JOIN(_N_(thread_ignore),_init))();
942}
943
944static void ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(enable_attach),_init))(void)
945{
946#ifdef __ANDROID__
947 /*
948 * if LIB_VAR_NAME env variable were set before then stay previous value
949 * else set default path
950 */
951 setenv(ITT_TO_STR(LIB_VAR_NAME), ANDROID_ITTNOTIFY_DEFAULT_PATH, 0);
952#endif
953}
954
955/* -------------------------------------------------------------------------- */
956
957static const char* __itt_fsplit(const char* s, const char* sep, const char** out, int* len)
958{
959 int i;
960 int j;
961
962 if (!s || !sep || !out || !len)
963 return NULL;
964
965 for (i = 0; s[i]; i++)
966 {
967 int b = 0;
968 for (j = 0; sep[j]; j++)
969 if (s[i] == sep[j])
970 {
971 b = 1;
972 break;
973 }
974 if (!b)
975 break;
976 }
977
978 if (!s[i])
979 return NULL;
980
981 *len = 0;
982 *out = &s[i];
983
984 for (; s[i]; i++, (*len)++)
985 {
986 int b = 0;
987 for (j = 0; sep[j]; j++)
988 if (s[i] == sep[j])
989 {
990 b = 1;
991 break;
992 }
993 if (b)
994 break;
995 }
996
997 for (; s[i]; i++)
998 {
999 int b = 0;
1000 for (j = 0; sep[j]; j++)
1001 if (s[i] == sep[j])
1002 {
1003 b = 1;
1004 break;
1005 }
1006 if (!b)
1007 break;
1008 }
1009
1010 return &s[i];
1011}
1012
1013/* This function return value of env variable that placed into static buffer.
1014 * !!! The same static buffer is used for subsequent calls. !!!
1015 * This was done to avoid dynamic allocation for few calls.
1016 * Actually we need this function only four times.
1017 */
1018static const char* __itt_get_env_var(const char* name)
1019{
1020#define MAX_ENV_VALUE_SIZE 4086
1021 static char env_buff[MAX_ENV_VALUE_SIZE];
1022 static char* env_value = (char*)env_buff;
1023
1024 if (name != NULL)
1025 {
1026#if ITT_PLATFORM==ITT_PLATFORM_WIN
1027 size_t max_len = MAX_ENV_VALUE_SIZE - (size_t)(env_value - env_buff);
1028 DWORD rc = GetEnvironmentVariableA(name, env_value, (DWORD)max_len);
1029 if (rc >= max_len)
1030 __itt_report_error(__itt_error_env_too_long, name, (size_t)rc - 1, (size_t)(max_len - 1));
1031 else if (rc > 0)
1032 {
1033 const char* ret = (const char*)env_value;
1034 env_value += rc + 1;
1035 return ret;
1036 }
1037 else
1038 {
1039 /* If environment variable is empty, GetEnvironmentVariables()
1040 * returns zero (number of characters (not including terminating null),
1041 * and GetLastError() returns ERROR_SUCCESS. */
1042 DWORD err = GetLastError();
1043 if (err == ERROR_SUCCESS)
1044 return env_value;
1045
1046 if (err != ERROR_ENVVAR_NOT_FOUND)
1047 __itt_report_error(__itt_error_cant_read_env, name, (int)err);
1048 }
1049#else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */
1050 char* env = getenv(name);
1051 if (env != NULL)
1052 {
1053 size_t len = __itt_fstrnlen(env, MAX_ENV_VALUE_SIZE);
1054 size_t max_len = MAX_ENV_VALUE_SIZE - (size_t)(env_value - env_buff);
1055 if (len < max_len)
1056 {
1057 const char* ret = (const char*)env_value;
1058 __itt_fstrcpyn(env_value, max_len, env, len + 1);
1059 env_value += len + 1;
1060 return ret;
1061 } else
1062 __itt_report_error(__itt_error_env_too_long, name, (size_t)len, (size_t)(max_len - 1));
1063 }
1064#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
1065 }
1066 return NULL;
1067}
1068
1069static const char* __itt_get_lib_name(void)
1070{
1071 const char* lib_name = __itt_get_env_var(ITT_TO_STR(LIB_VAR_NAME));
1072
1073#ifdef __ANDROID__
1074 if (lib_name == NULL)
1075 {
1076
1077#if ITT_ARCH==ITT_ARCH_IA32 || ITT_ARCH==ITT_ARCH_ARM
1078 const char* const marker_filename = "com.intel.itt.collector_lib_32";
1079#else
1080 const char* const marker_filename = "com.intel.itt.collector_lib_64";
1081#endif
1082
1083 char system_wide_marker_filename[PATH_MAX] = {0};
1084 int itt_marker_file_fd = -1;
1085 ssize_t res = 0;
1086
1087 res = snprintf(system_wide_marker_filename, PATH_MAX - 1, "%s%s", "/data/local/tmp/", marker_filename);
1088 if (res < 0)
1089 {
1090 ITT_ANDROID_LOGE("Unable to concatenate marker file string.");
1091 return lib_name;
1092 }
1093 itt_marker_file_fd = open(system_wide_marker_filename, O_RDONLY);
1094
1095 if (itt_marker_file_fd == -1)
1096 {
1097 const pid_t my_pid = getpid();
1098 char cmdline_path[PATH_MAX] = {0};
1099 char package_name[PATH_MAX] = {0};
1100 char app_sandbox_file[PATH_MAX] = {0};
1101 int cmdline_fd = 0;
1102
1103 ITT_ANDROID_LOGI("Unable to open system-wide marker file.");
1104 res = snprintf(cmdline_path, PATH_MAX - 1, "/proc/%d/cmdline", my_pid);
1105 if (res < 0)
1106 {
1107 ITT_ANDROID_LOGE("Unable to get cmdline path string.");
1108 return lib_name;
1109 }
1110
1111 ITT_ANDROID_LOGI("CMD file: %s\n", cmdline_path);
1112 cmdline_fd = open(cmdline_path, O_RDONLY);
1113 if (cmdline_fd == -1)
1114 {
1115 ITT_ANDROID_LOGE("Unable to open %s file!", cmdline_path);
1116 return lib_name;
1117 }
1118 res = read(cmdline_fd, package_name, PATH_MAX - 1);
1119 if (res == -1)
1120 {
1121 ITT_ANDROID_LOGE("Unable to read %s file!", cmdline_path);
1122 res = close(cmdline_fd);
1123 if (res == -1)
1124 {
1125 ITT_ANDROID_LOGE("Unable to close %s file!", cmdline_path);
1126 }
1127 return lib_name;
1128 }
1129 res = close(cmdline_fd);
1130 if (res == -1)
1131 {
1132 ITT_ANDROID_LOGE("Unable to close %s file!", cmdline_path);
1133 return lib_name;
1134 }
1135 ITT_ANDROID_LOGI("Package name: %s\n", package_name);
1136 res = snprintf(app_sandbox_file, PATH_MAX - 1, "/data/data/%s/%s", package_name, marker_filename);
1137 if (res < 0)
1138 {
1139 ITT_ANDROID_LOGE("Unable to concatenate marker file string.");
1140 return lib_name;
1141 }
1142
1143 ITT_ANDROID_LOGI("Lib marker file name: %s\n", app_sandbox_file);
1144 itt_marker_file_fd = open(app_sandbox_file, O_RDONLY);
1145 if (itt_marker_file_fd == -1)
1146 {
1147 ITT_ANDROID_LOGE("Unable to open app marker file!");
1148 return lib_name;
1149 }
1150 }
1151
1152 {
1153 char itt_lib_name[PATH_MAX] = {0};
1154
1155 res = read(itt_marker_file_fd, itt_lib_name, PATH_MAX - 1);
1156 if (res == -1)
1157 {
1158 ITT_ANDROID_LOGE("Unable to read %s file!", itt_marker_file_fd);
1159 res = close(itt_marker_file_fd);
1160 if (res == -1)
1161 {
1162 ITT_ANDROID_LOGE("Unable to close %s file!", itt_marker_file_fd);
1163 }
1164 return lib_name;
1165 }
1166 ITT_ANDROID_LOGI("ITT Lib path: %s", itt_lib_name);
1167 res = close(itt_marker_file_fd);
1168 if (res == -1)
1169 {
1170 ITT_ANDROID_LOGE("Unable to close %s file!", itt_marker_file_fd);
1171 return lib_name;
1172 }
1173 ITT_ANDROID_LOGI("Set env %s to %s", ITT_TO_STR(LIB_VAR_NAME), itt_lib_name);
1174 res = setenv(ITT_TO_STR(LIB_VAR_NAME), itt_lib_name, 0);
1175 if (res == -1)
1176 {
1177 ITT_ANDROID_LOGE("Unable to set env var!");
1178 return lib_name;
1179 }
1180 lib_name = __itt_get_env_var(ITT_TO_STR(LIB_VAR_NAME));
1181 ITT_ANDROID_LOGI("ITT Lib path from env: %s", lib_name);
1182 }
1183 }
1184#endif
1185
1186 return lib_name;
1187}
1188
1189/* Avoid clashes with std::min */
1190#define __itt_min(a,b) ((a) < (b) ? (a) : (b))
1191
1192static __itt_group_id __itt_get_groups(void)
1193{
1194 int i;
1195 __itt_group_id res = __itt_group_none;
1196 const char* var_name = "INTEL_ITTNOTIFY_GROUPS";
1197 const char* group_str = __itt_get_env_var(var_name);
1198
1199 if (group_str != NULL)
1200 {
1201 int len;
1202 char gr[255];
1203 const char* chunk;
1204 while ((group_str = __itt_fsplit(group_str, ",; ", &chunk, &len)) != NULL)
1205 {
1206 int min_len = __itt_min(len, (int)(sizeof(gr) - 1));
1207 __itt_fstrcpyn(gr, sizeof(gr) - 1, chunk, min_len);
1208 gr[min_len] = 0;
1209
1210 for (i = 0; group_list[i].name != NULL; i++)
1211 {
1212 if (!__itt_fstrcmp(gr, group_list[i].name))
1213 {
1214 res = (__itt_group_id)(res | group_list[i].id);
1215 break;
1216 }
1217 }
1218 }
1219 /* TODO: !!! Workaround for bug with warning for unknown group !!!
1220 * Should be fixed in new initialization scheme.
1221 * Now the following groups should be set always. */
1222 for (i = 0; group_list[i].id != __itt_group_none; i++)
1223 if (group_list[i].id != __itt_group_all &&
1224 group_list[i].id > __itt_group_splitter_min &&
1225 group_list[i].id < __itt_group_splitter_max)
1226 res = (__itt_group_id)(res | group_list[i].id);
1227 return res;
1228 }
1229 else
1230 {
1231 for (i = 0; group_alias[i].env_var != NULL; i++)
1232 if (__itt_get_env_var(group_alias[i].env_var) != NULL)
1233 return group_alias[i].groups;
1234 }
1235
1236 return res;
1237}
1238
1239#undef __itt_min
1240
1241static int __itt_lib_version(lib_t lib)
1242{
1243 if (lib == NULL)
1244 return 0;
1245 if (__itt_get_proc(lib, "__itt_api_init"))
1246 return 2;
1247 if (__itt_get_proc(lib, "__itt_api_version"))
1248 return 1;
1249 return 0;
1250}
1251
1252/* It's not used right now! Comment it out to avoid warnings.
1253static void __itt_reinit_all_pointers(void)
1254{
1255 register int i;
1256 // Fill all pointers with initial stubs
1257 for (i = 0; _N_(_ittapi_global).api_list_ptr[i].name != NULL; i++)
1258 *_N_(_ittapi_global).api_list_ptr[i].func_ptr = _N_(_ittapi_global).api_list_ptr[i].init_func;
1259}
1260*/
1261
1262static void __itt_nullify_all_pointers(void)
1263{
1264 int i;
1265 /* Nulify all pointers except domain_create, string_handle_create and counter_create */
1266 for (i = 0; _N_(_ittapi_global).api_list_ptr[i].name != NULL; i++)
1267 *_N_(_ittapi_global).api_list_ptr[i].func_ptr = _N_(_ittapi_global).api_list_ptr[i].null_func;
1268}
1269
1270static int __itt_is_collector_available(void)
1271{
1272 int is_available;
1273
1274 ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global));
1275 if (_N_(_ittapi_global).state == __itt_collection_uninitialized)
1276 {
1277 _N_(_ittapi_global).state = (NULL == __itt_get_lib_name()) ? __itt_collection_collector_absent : __itt_collection_collector_exists;
1278 }
1279 is_available = (_N_(_ittapi_global).state == __itt_collection_collector_exists ||
1280 _N_(_ittapi_global).state == __itt_collection_init_successful);
1281 __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
1282 return is_available;
1283}
1284
1285#if ITT_PLATFORM==ITT_PLATFORM_WIN
1286#if _MSC_VER
1287#pragma warning(push)
1288#pragma warning(disable: 4054) /* warning C4054: 'type cast' : from function pointer 'XXX' to data pointer 'void *' */
1289#pragma warning(disable: 4055) /* warning C4055: 'type cast' : from data pointer 'void *' to function pointer 'XXX' */
1290#endif
1291#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
1292
1293ITT_EXTERN_C void _N_(fini_ittlib)(void)
1294{
1295 __itt_api_fini_t* __itt_api_fini_ptr = NULL;
1296 static volatile TIDT current_thread = 0;
1297
1298 if (_N_(_ittapi_global).api_initialized)
1299 {
1300 ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global));
1301 if (_N_(_ittapi_global).api_initialized)
1302 {
1303 if (current_thread == 0)
1304 {
1305 if (PTHREAD_SYMBOLS) current_thread = __itt_thread_id();
1306 if (_N_(_ittapi_global).lib != NULL)
1307 {
1308 __itt_api_fini_ptr = (__itt_api_fini_t*)(size_t)__itt_get_proc(_N_(_ittapi_global).lib, "__itt_api_fini");
1309 }
1310 if (__itt_api_fini_ptr)
1311 {
1312 __itt_api_fini_ptr(&_N_(_ittapi_global));
1313 }
1314
1315 __itt_nullify_all_pointers();
1316
1317 /* TODO: !!! not safe !!! don't support unload so far.
1318 * if (_N_(_ittapi_global).lib != NULL)
1319 * __itt_unload_lib(_N_(_ittapi_global).lib);
1320 * _N_(_ittapi_global).lib = NULL;
1321 */
1322 _N_(_ittapi_global).api_initialized = 0;
1323 current_thread = 0;
1324 }
1325 }
1326 if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
1327 }
1328}
1329
1330/* !!! this function should be called under mutex lock !!! */
1331static void __itt_free_allocated_resources(void)
1332{
1333 __itt_string_handle* current_string = _N_(_ittapi_global).string_list;
1334 while (current_string != NULL)
1335 {
1336 __itt_string_handle* tmp = current_string->next;
1337 free((char*)current_string->strA);
1338#if ITT_PLATFORM==ITT_PLATFORM_WIN
1339 free((wchar_t*)current_string->strW);
1340#endif
1341 free(current_string);
1342 current_string = tmp;
1343 }
1344 _N_(_ittapi_global).string_list = NULL;
1345
1346 __itt_domain* current_domain = _N_(_ittapi_global).domain_list;
1347 while (current_domain != NULL)
1348 {
1349 __itt_domain* tmp = current_domain->next;
1350 free((char*)current_domain->nameA);
1351#if ITT_PLATFORM==ITT_PLATFORM_WIN
1352 free((wchar_t*)current_domain->nameW);
1353#endif
1354 free(current_domain);
1355 current_domain = tmp;
1356 }
1357 _N_(_ittapi_global).domain_list = NULL;
1358
1359 __itt_counter_info_t* current_couter = _N_(_ittapi_global).counter_list;
1360 while (current_couter != NULL)
1361 {
1362 __itt_counter_info_t* tmp = current_couter->next;
1363 free((char*)current_couter->nameA);
1364 free((char*)current_couter->domainA);
1365#if ITT_PLATFORM==ITT_PLATFORM_WIN
1366 free((wchar_t*)current_couter->nameW);
1367 free((wchar_t*)current_couter->domainW);
1368#endif
1369 free(current_couter);
1370 current_couter = tmp;
1371 }
1372 _N_(_ittapi_global).counter_list = NULL;
1373
1374 __itt_histogram* current_histogram = _N_(_ittapi_global).histogram_list;
1375 while (current_histogram != NULL)
1376 {
1377 __itt_histogram* tmp = current_histogram->next;
1378 free((char*)current_histogram->nameA);
1379#if ITT_PLATFORM==ITT_PLATFORM_WIN
1380 free((wchar_t*)current_histogram->nameW);
1381#endif
1382 free(current_histogram);
1383 current_histogram = tmp;
1384 }
1385 _N_(_ittapi_global).histogram_list = NULL;
1386}
1387
1388ITT_EXTERN_C int _N_(init_ittlib)(const char* lib_name, __itt_group_id init_groups)
1389{
1390 int i;
1391 __itt_group_id groups;
1392#ifdef ITT_COMPLETE_GROUP
1393 __itt_group_id zero_group = __itt_group_none;
1394#endif /* ITT_COMPLETE_GROUP */
1395 static volatile TIDT current_thread = 0;
1396
1397 if (!_N_(_ittapi_global).api_initialized)
1398 {
1399#ifndef ITT_SIMPLE_INIT
1400 ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global));
1401#endif /* ITT_SIMPLE_INIT */
1402
1403 if (!_N_(_ittapi_global).api_initialized)
1404 {
1405 if (current_thread == 0)
1406 {
1407 if (PTHREAD_SYMBOLS) current_thread = __itt_thread_id();
1408 if (lib_name == NULL)
1409 {
1410 lib_name = __itt_get_lib_name();
1411 }
1412 groups = __itt_get_groups();
1413 if (DL_SYMBOLS && (groups != __itt_group_none || lib_name != NULL))
1414 {
1415 _N_(_ittapi_global).lib = __itt_load_lib((lib_name == NULL) ? ittnotify_lib_name : lib_name);
1416
1417 if (_N_(_ittapi_global).lib != NULL)
1418 {
1419 _N_(_ittapi_global).state = __itt_collection_init_successful;
1420 __itt_api_init_t* __itt_api_init_ptr;
1421 int lib_version = __itt_lib_version(_N_(_ittapi_global).lib);
1422
1423 switch (lib_version)
1424 {
1425 case 0:
1426 groups = __itt_group_legacy;
1427 ITT_ATTRIBUTE_FALLTHROUGH;
1428 case 1:
1429 /* Fill all pointers from dynamic library */
1430 for (i = 0; _N_(_ittapi_global).api_list_ptr[i].name != NULL; i++)
1431 {
1432 if (_N_(_ittapi_global).api_list_ptr[i].group & groups & init_groups)
1433 {
1434 *_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);
1435 if (*_N_(_ittapi_global).api_list_ptr[i].func_ptr == NULL)
1436 {
1437 /* Restore pointers for function with static implementation */
1438 *_N_(_ittapi_global).api_list_ptr[i].func_ptr = _N_(_ittapi_global).api_list_ptr[i].null_func;
1439 __itt_report_error(__itt_error_no_symbol, lib_name, _N_(_ittapi_global).api_list_ptr[i].name);
1440#ifdef ITT_COMPLETE_GROUP
1441 zero_group = (__itt_group_id)(zero_group | _N_(_ittapi_global).api_list_ptr[i].group);
1442#endif /* ITT_COMPLETE_GROUP */
1443 }
1444 }
1445 else
1446 *_N_(_ittapi_global).api_list_ptr[i].func_ptr = _N_(_ittapi_global).api_list_ptr[i].null_func;
1447 }
1448
1449 if (groups == __itt_group_legacy)
1450 {
1451 /* Compatibility with legacy tools */
1452 ITTNOTIFY_NAME(thread_ignore) = ITTNOTIFY_NAME(thr_ignore);
1453#if ITT_PLATFORM==ITT_PLATFORM_WIN
1454 ITTNOTIFY_NAME(sync_createA) = ITTNOTIFY_NAME(sync_set_nameA);
1455 ITTNOTIFY_NAME(sync_createW) = ITTNOTIFY_NAME(sync_set_nameW);
1456#else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */
1457 ITTNOTIFY_NAME(sync_create) = ITTNOTIFY_NAME(sync_set_name);
1458#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
1459 ITTNOTIFY_NAME(sync_prepare) = ITTNOTIFY_NAME(notify_sync_prepare);
1460 ITTNOTIFY_NAME(sync_cancel) = ITTNOTIFY_NAME(notify_sync_cancel);
1461 ITTNOTIFY_NAME(sync_acquired) = ITTNOTIFY_NAME(notify_sync_acquired);
1462 ITTNOTIFY_NAME(sync_releasing) = ITTNOTIFY_NAME(notify_sync_releasing);
1463 }
1464
1465#ifdef ITT_COMPLETE_GROUP
1466 for (i = 0; _N_(_ittapi_global).api_list_ptr[i].name != NULL; i++)
1467 if (_N_(_ittapi_global).api_list_ptr[i].group & zero_group)
1468 *_N_(_ittapi_global).api_list_ptr[i].func_ptr = _N_(_ittapi_global).api_list_ptr[i].null_func;
1469#endif /* ITT_COMPLETE_GROUP */
1470 break;
1471 case 2:
1472 __itt_api_init_ptr = (__itt_api_init_t*)(size_t)__itt_get_proc(_N_(_ittapi_global).lib, "__itt_api_init");
1473 if (__itt_api_init_ptr)
1474 __itt_api_init_ptr(&_N_(_ittapi_global), init_groups);
1475 break;
1476 }
1477 }
1478 else
1479 {
1480 _N_(_ittapi_global).state = __itt_collection_init_fail;
1481 __itt_free_allocated_resources();
1482 __itt_nullify_all_pointers();
1483
1484 __itt_report_error(__itt_error_no_module, lib_name,
1485#if ITT_PLATFORM==ITT_PLATFORM_WIN
1486 __itt_system_error()
1487#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
1488 dlerror()
1489#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
1490 );
1491 }
1492 }
1493 else
1494 {
1495 _N_(_ittapi_global).state = __itt_collection_collector_absent;
1496 __itt_nullify_all_pointers();
1497 }
1498 _N_(_ittapi_global).api_initialized = 1;
1499 current_thread = 0;
1500 /* !!! Just to avoid unused code elimination !!! */
1501 if (__itt_fini_ittlib_ptr == _N_(fini_ittlib)) current_thread = 0;
1502 }
1503 }
1504
1505#ifndef ITT_SIMPLE_INIT
1506 if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
1507#endif /* ITT_SIMPLE_INIT */
1508 }
1509
1510 /* Evaluating if any function ptr is non empty and it's in init_groups */
1511 for (i = 0; _N_(_ittapi_global).api_list_ptr[i].name != NULL; i++)
1512 {
1513 if (*_N_(_ittapi_global).api_list_ptr[i].func_ptr != _N_(_ittapi_global).api_list_ptr[i].null_func &&
1514 _N_(_ittapi_global).api_list_ptr[i].group & init_groups)
1515 {
1516 return 1;
1517 }
1518 }
1519 return 0;
1520}
1521
1522ITT_EXTERN_C __itt_error_handler_t* _N_(set_error_handler)(__itt_error_handler_t* handler)
1523{
1524 __itt_error_handler_t* prev = (__itt_error_handler_t*)(size_t)_N_(_ittapi_global).error_handler;
1525 _N_(_ittapi_global).error_handler = (void*)(size_t)handler;
1526 return prev;
1527}
1528
1529#if ITT_PLATFORM==ITT_PLATFORM_WIN
1530#if _MSC_VER
1531#pragma warning(pop)
1532#endif
1533#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
1534
1535/** __itt_mark_pt_region functions marks region of interest
1536 * region parameter defines different regions.
1537 * 0 <= region < 8 */
1538
1539#if defined(ITT_API_IPT_SUPPORT) && (ITT_PLATFORM==ITT_PLATFORM_WIN || ITT_PLATFORM==ITT_PLATFORM_POSIX) && !defined(__ANDROID__)
1540void __itt_pt_mark(__itt_pt_region region);
1541void __itt_pt_mark_event(__itt_pt_region region);
1542#endif
1543
1544ITT_EXTERN_C void _N_(mark_pt_region_begin)(__itt_pt_region region)
1545{
1546#if defined(ITT_API_IPT_SUPPORT) && (ITT_PLATFORM==ITT_PLATFORM_WIN || ITT_PLATFORM==ITT_PLATFORM_POSIX) && !defined(__ANDROID__)
1547 if (_N_(_ittapi_global).ipt_collect_events == 1)
1548 {
1549 __itt_pt_mark_event(2*region);
1550 }
1551 else
1552 {
1553 __itt_pt_mark(2*region);
1554 }
1555#else
1556 (void)region;
1557#endif
1558}
1559
1560ITT_EXTERN_C void _N_(mark_pt_region_end)(__itt_pt_region region)
1561{
1562#if defined(ITT_API_IPT_SUPPORT) && (ITT_PLATFORM==ITT_PLATFORM_WIN || ITT_PLATFORM==ITT_PLATFORM_POSIX) && !defined(__ANDROID__)
1563 if (_N_(_ittapi_global).ipt_collect_events == 1)
1564 {
1565 __itt_pt_mark_event(2*region + 1);
1566 }
1567 else
1568 {
1569 __itt_pt_mark(2*region + 1);
1570 }
1571#else
1572 (void)region;
1573#endif
1574}
1575
1576ITT_EXTERN_C __itt_collection_state (_N_(get_collection_state))(void)
1577{
1578 if (!_N_(_ittapi_global).api_initialized && _N_(_ittapi_global).thread_list == NULL)
1579 {
1580 __itt_init_ittlib_name(NULL, __itt_group_all);
1581 }
1582 return _N_(_ittapi_global).state;
1583}
1584
1585/* !!! should be called from the library destructor !!!
1586 * this function destroys the mutex and frees resources
1587 * allocated by ITT API static part
1588 */
1589ITT_EXTERN_C void (_N_(release_resources))(void)
1590{
1591 ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global));
1592 __itt_free_allocated_resources();
1593 if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
1594 ITT_MUTEX_DESTROY(_N_(_ittapi_global));
1595}
1596