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