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