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