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