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