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