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 "kmp_os.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 part descriptor which handles. all notification api attributes. */
231 __itt_global _N_(_ittapi_global) = {
232 ITT_MAGIC, /* identification info */
233 ITT_MAJOR, ITT_MINOR, API_VERSION_BUILD, /* version info */
234 0, /* api_initialized */
235 0, /* mutex_initialized */
236 0, /* atomic_counter */
237 MUTEX_INITIALIZER, /* mutex */
238 NULL, /* dynamic library handle */
239 NULL, /* error_handler */
240 NULL, /* dll_path_ptr */
241 (__itt_api_info*)&api_list, /* api_list_ptr */
242 NULL, /* next __itt_global */
243 NULL, /* thread_list */
244 NULL, /* domain_list */
245 NULL, /* string_list */
246 __itt_collection_normal, /* collection state */
247 NULL /* counter_list */
248 };
249
250 typedef void (__itt_api_init_t)(__itt_global*, __itt_group_id);
251 typedef void (__itt_api_fini_t)(__itt_global*);
252
253 /* ========================================================================= */
254
255 #ifdef ITT_NOTIFY_EXT_REPORT
256 ITT_EXTERN_C void _N_(error_handler)(__itt_error_code, va_list args);
257 #endif /* ITT_NOTIFY_EXT_REPORT */
258
259 #if ITT_PLATFORM==ITT_PLATFORM_WIN && KMP_MSVC_COMPAT
260 #pragma warning(push)
261 #pragma warning(disable: 4055) /* warning C4055: 'type cast' : from data pointer 'void *' to function pointer 'XXX' */
262 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
263
__itt_report_error(unsigned code_arg,...)264 static void __itt_report_error(unsigned code_arg, ...)
265 {
266 va_list args;
267 va_start(args, code_arg);
268
269 // We use unsigned for the code argument and explicitly cast it here to the
270 // right enumerator because variadic functions are not compatible with
271 // default promotions.
272 __itt_error_code code = (__itt_error_code)code_arg;
273
274 if (_N_(_ittapi_global).error_handler != NULL)
275 {
276 __itt_error_handler_t* handler = (__itt_error_handler_t*)(size_t)_N_(_ittapi_global).error_handler;
277 handler(code, args);
278 }
279 #ifdef ITT_NOTIFY_EXT_REPORT
280 _N_(error_handler)(code, args);
281 #endif /* ITT_NOTIFY_EXT_REPORT */
282 va_end(args);
283 }
284
285 #if ITT_PLATFORM==ITT_PLATFORM_WIN && KMP_MSVC_COMPAT
286 #pragma warning(pop)
287 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
288
289 #if ITT_PLATFORM==ITT_PLATFORM_WIN
ITT_VERSIONIZE(ITT_JOIN (_N_ (domain_createW),_init))290 static __itt_domain* ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(domain_createW),_init))(const wchar_t* name)
291 {
292 __itt_domain *h_tail = NULL, *h = NULL;
293
294 if (name == NULL)
295 {
296 return NULL;
297 }
298
299 ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global));
300 if (_N_(_ittapi_global).api_initialized)
301 {
302 if (ITTNOTIFY_NAME(domain_createW) && ITTNOTIFY_NAME(domain_createW) != ITT_VERSIONIZE(ITT_JOIN(_N_(domain_createW),_init)))
303 {
304 __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
305 return ITTNOTIFY_NAME(domain_createW)(name);
306 }
307 }
308 for (h_tail = NULL, h = _N_(_ittapi_global).domain_list; h != NULL; h_tail = h, h = h->next)
309 {
310 if (h->nameW != NULL && !wcscmp(h->nameW, name)) break;
311 }
312 if (h == NULL)
313 {
314 NEW_DOMAIN_W(&_N_(_ittapi_global),h,h_tail,name);
315 }
316 if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
317 return h;
318 }
319
ITT_VERSIONIZE(ITT_JOIN (_N_ (domain_createA),_init))320 static __itt_domain* ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(domain_createA),_init))(const char* name)
321 #else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */
322 static __itt_domain* ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(domain_create),_init))(const char* name)
323 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
324 {
325 __itt_domain *h_tail = NULL, *h = NULL;
326
327 if (name == NULL)
328 {
329 return NULL;
330 }
331
332 ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global));
333 if (_N_(_ittapi_global).api_initialized)
334 {
335 #if ITT_PLATFORM==ITT_PLATFORM_WIN
336 if (ITTNOTIFY_NAME(domain_createA) && ITTNOTIFY_NAME(domain_createA) != ITT_VERSIONIZE(ITT_JOIN(_N_(domain_createA),_init)))
337 {
338 __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
339 return ITTNOTIFY_NAME(domain_createA)(name);
340 }
341 #else
342 if (ITTNOTIFY_NAME(domain_create) && ITTNOTIFY_NAME(domain_create) != ITT_VERSIONIZE(ITT_JOIN(_N_(domain_create),_init)))
343 {
344 if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
345 return ITTNOTIFY_NAME(domain_create)(name);
346 }
347 #endif
348 }
349 for (h_tail = NULL, h = _N_(_ittapi_global).domain_list; h != NULL; h_tail = h, h = h->next)
350 {
351 if (h->nameA != NULL && !__itt_fstrcmp(h->nameA, name)) break;
352 }
353 if (h == NULL)
354 {
355 NEW_DOMAIN_A(&_N_(_ittapi_global),h,h_tail,name);
356 }
357 if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
358 return h;
359 }
360
361 #if ITT_PLATFORM==ITT_PLATFORM_WIN
ITT_VERSIONIZE(ITT_JOIN (_N_ (string_handle_createW),_init))362 static __itt_string_handle* ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(string_handle_createW),_init))(const wchar_t* name)
363 {
364 __itt_string_handle *h_tail = NULL, *h = NULL;
365
366 if (name == NULL)
367 {
368 return NULL;
369 }
370
371 ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global));
372 if (_N_(_ittapi_global).api_initialized)
373 {
374 if (ITTNOTIFY_NAME(string_handle_createW) && ITTNOTIFY_NAME(string_handle_createW) != ITT_VERSIONIZE(ITT_JOIN(_N_(string_handle_createW),_init)))
375 {
376 __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
377 return ITTNOTIFY_NAME(string_handle_createW)(name);
378 }
379 }
380 for (h_tail = NULL, h = _N_(_ittapi_global).string_list; h != NULL; h_tail = h, h = h->next)
381 {
382 if (h->strW != NULL && !wcscmp(h->strW, name)) break;
383 }
384 if (h == NULL)
385 {
386 NEW_STRING_HANDLE_W(&_N_(_ittapi_global),h,h_tail,name);
387 }
388 __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
389 return h;
390 }
391
ITT_VERSIONIZE(ITT_JOIN (_N_ (string_handle_createA),_init))392 static __itt_string_handle* ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(string_handle_createA),_init))(const char* name)
393 #else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */
394 static __itt_string_handle* ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(string_handle_create),_init))(const char* name)
395 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
396 {
397 __itt_string_handle *h_tail = NULL, *h = NULL;
398
399 if (name == NULL)
400 {
401 return NULL;
402 }
403
404 ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global));
405 if (_N_(_ittapi_global).api_initialized)
406 {
407 #if ITT_PLATFORM==ITT_PLATFORM_WIN
408 if (ITTNOTIFY_NAME(string_handle_createA) && ITTNOTIFY_NAME(string_handle_createA) != ITT_VERSIONIZE(ITT_JOIN(_N_(string_handle_createA),_init)))
409 {
410 __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
411 return ITTNOTIFY_NAME(string_handle_createA)(name);
412 }
413 #else
414 if (ITTNOTIFY_NAME(string_handle_create) && ITTNOTIFY_NAME(string_handle_create) != ITT_VERSIONIZE(ITT_JOIN(_N_(string_handle_create),_init)))
415 {
416 if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
417 return ITTNOTIFY_NAME(string_handle_create)(name);
418 }
419 #endif
420 }
421 for (h_tail = NULL, h = _N_(_ittapi_global).string_list; h != NULL; h_tail = h, h = h->next)
422 {
423 if (h->strA != NULL && !__itt_fstrcmp(h->strA, name)) break;
424 }
425 if (h == NULL)
426 {
427 NEW_STRING_HANDLE_A(&_N_(_ittapi_global),h,h_tail,name);
428 }
429 if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
430 return h;
431 }
432
433 #if ITT_PLATFORM==ITT_PLATFORM_WIN
ITT_VERSIONIZE(ITT_JOIN (_N_ (counter_createW),_init))434 static __itt_counter ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(counter_createW),_init))(const wchar_t *name, const wchar_t *domain)
435 {
436 __itt_counter_info_t *h_tail = NULL, *h = NULL;
437 __itt_metadata_type type = __itt_metadata_u64;
438
439 if (name == NULL)
440 {
441 return NULL;
442 }
443
444 ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global));
445 if (_N_(_ittapi_global).api_initialized)
446 {
447 if (ITTNOTIFY_NAME(counter_createW) && ITTNOTIFY_NAME(counter_createW) != ITT_VERSIONIZE(ITT_JOIN(_N_(counter_createW),_init)))
448 {
449 __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
450 return ITTNOTIFY_NAME(counter_createW)(name, domain);
451 }
452 }
453 for (h_tail = NULL, h = _N_(_ittapi_global).counter_list; h != NULL; h_tail = h, h = h->next)
454 {
455 if (h->nameW != NULL && h->type == type && !wcscmp(h->nameW, name) && ((h->domainW == NULL && domain == NULL) ||
456 (h->domainW != NULL && domain != NULL && !wcscmp(h->domainW, domain)))) break;
457
458 }
459 if (h == NULL)
460 {
461 NEW_COUNTER_W(&_N_(_ittapi_global),h,h_tail,name,domain,type);
462 }
463 __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
464 return (__itt_counter)h;
465 }
466
ITT_VERSIONIZE(ITT_JOIN (_N_ (counter_createA),_init))467 static __itt_counter ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(counter_createA),_init))(const char *name, const char *domain)
468 #else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */
469 static __itt_counter ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(counter_create),_init))(const char *name, const char *domain)
470 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
471 {
472 __itt_counter_info_t *h_tail = NULL, *h = NULL;
473 __itt_metadata_type type = __itt_metadata_u64;
474
475 if (name == NULL)
476 {
477 return NULL;
478 }
479
480 ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global));
481 if (_N_(_ittapi_global).api_initialized)
482 {
483 #if ITT_PLATFORM==ITT_PLATFORM_WIN
484 if (ITTNOTIFY_NAME(counter_createA) && ITTNOTIFY_NAME(counter_createA) != ITT_VERSIONIZE(ITT_JOIN(_N_(counter_createA),_init)))
485 {
486 __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
487 return ITTNOTIFY_NAME(counter_createA)(name, domain);
488 }
489 #else
490 if (ITTNOTIFY_NAME(counter_create) && ITTNOTIFY_NAME(counter_create) != ITT_VERSIONIZE(ITT_JOIN(_N_(counter_create),_init)))
491 {
492 if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
493 return ITTNOTIFY_NAME(counter_create)(name, domain);
494 }
495 #endif
496 }
497 for (h_tail = NULL, h = _N_(_ittapi_global).counter_list; h != NULL; h_tail = h, h = h->next)
498 {
499 if (h->nameA != NULL && h->type == type && !__itt_fstrcmp(h->nameA, name) && ((h->domainA == NULL && domain == NULL) ||
500 (h->domainA != NULL && domain != NULL && !__itt_fstrcmp(h->domainA, domain)))) break;
501 }
502 if (h == NULL)
503 {
504 NEW_COUNTER_A(&_N_(_ittapi_global),h,h_tail,name,domain,type);
505 }
506 if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
507 return (__itt_counter)h;
508 }
509
510 #if ITT_PLATFORM==ITT_PLATFORM_WIN
ITT_VERSIONIZE(ITT_JOIN (_N_ (counter_create_typedW),_init))511 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)
512 {
513 __itt_counter_info_t *h_tail = NULL, *h = NULL;
514
515 if (name == NULL)
516 {
517 return NULL;
518 }
519
520 ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global));
521 if (_N_(_ittapi_global).api_initialized)
522 {
523 if (ITTNOTIFY_NAME(counter_create_typedW) && ITTNOTIFY_NAME(counter_create_typedW) != ITT_VERSIONIZE(ITT_JOIN(_N_(counter_create_typedW),_init)))
524 {
525 __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
526 return ITTNOTIFY_NAME(counter_create_typedW)(name, domain, type);
527 }
528 }
529 for (h_tail = NULL, h = _N_(_ittapi_global).counter_list; h != NULL; h_tail = h, h = h->next)
530 {
531 if (h->nameW != NULL && h->type == type && !wcscmp(h->nameW, name) && ((h->domainW == NULL && domain == NULL) ||
532 (h->domainW != NULL && domain != NULL && !wcscmp(h->domainW, domain)))) break;
533
534 }
535 if (h == NULL)
536 {
537 NEW_COUNTER_W(&_N_(_ittapi_global),h,h_tail,name,domain,type);
538 }
539 __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
540 return (__itt_counter)h;
541 }
542
ITT_VERSIONIZE(ITT_JOIN (_N_ (counter_create_typedA),_init))543 static __itt_counter ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(counter_create_typedA),_init))(const char *name, const char *domain, __itt_metadata_type type)
544 #else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */
545 static __itt_counter ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(counter_create_typed),_init))(const char *name, const char *domain, __itt_metadata_type type)
546 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
547 {
548 __itt_counter_info_t *h_tail = NULL, *h = NULL;
549
550 if (name == NULL)
551 {
552 return NULL;
553 }
554
555 ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global));
556 if (_N_(_ittapi_global).api_initialized)
557 {
558 #if ITT_PLATFORM==ITT_PLATFORM_WIN
559 if (ITTNOTIFY_NAME(counter_create_typedA) && ITTNOTIFY_NAME(counter_create_typedA) != ITT_VERSIONIZE(ITT_JOIN(_N_(counter_create_typedA),_init)))
560 {
561 __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
562 return ITTNOTIFY_NAME(counter_create_typedA)(name, domain, type);
563 }
564 #else
565 if (ITTNOTIFY_NAME(counter_create_typed) && ITTNOTIFY_NAME(counter_create_typed) != ITT_VERSIONIZE(ITT_JOIN(_N_(counter_create_typed),_init)))
566 {
567 if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
568 return ITTNOTIFY_NAME(counter_create_typed)(name, domain, type);
569 }
570 #endif
571 }
572 for (h_tail = NULL, h = _N_(_ittapi_global).counter_list; h != NULL; h_tail = h, h = h->next)
573 {
574 if (h->nameA != NULL && h->type == type && !__itt_fstrcmp(h->nameA, name) && ((h->domainA == NULL && domain == NULL) ||
575 (h->domainA != NULL && domain != NULL && !__itt_fstrcmp(h->domainA, domain)))) break;
576 }
577 if (h == NULL)
578 {
579 NEW_COUNTER_A(&_N_(_ittapi_global),h,h_tail,name,domain,type);
580 }
581 if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
582 return (__itt_counter)h;
583 }
584
585 /* -------------------------------------------------------------------------- */
586
ITT_VERSIONIZE(ITT_JOIN (_N_ (pause),_init))587 static void ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(pause),_init))(void)
588 {
589 if (!_N_(_ittapi_global).api_initialized && _N_(_ittapi_global).thread_list == NULL)
590 {
591 __itt_init_ittlib_name(NULL, __itt_group_all);
592 }
593 if (ITTNOTIFY_NAME(pause) && ITTNOTIFY_NAME(pause) != ITT_VERSIONIZE(ITT_JOIN(_N_(pause),_init)))
594 {
595 ITTNOTIFY_NAME(pause)();
596 }
597 else
598 {
599 _N_(_ittapi_global).state = __itt_collection_paused;
600 }
601 }
602
ITT_VERSIONIZE(ITT_JOIN (_N_ (resume),_init))603 static void ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(resume),_init))(void)
604 {
605 if (!_N_(_ittapi_global).api_initialized && _N_(_ittapi_global).thread_list == NULL)
606 {
607 __itt_init_ittlib_name(NULL, __itt_group_all);
608 }
609 if (ITTNOTIFY_NAME(resume) && ITTNOTIFY_NAME(resume) != ITT_VERSIONIZE(ITT_JOIN(_N_(resume),_init)))
610 {
611 ITTNOTIFY_NAME(resume)();
612 }
613 else
614 {
615 _N_(_ittapi_global).state = __itt_collection_normal;
616 }
617 }
618
619 #if ITT_PLATFORM==ITT_PLATFORM_WIN
ITT_VERSIONIZE(ITT_JOIN (_N_ (thread_set_nameW),_init))620 static void ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_nameW),_init))(const wchar_t* name)
621 {
622 if (!_N_(_ittapi_global).api_initialized && _N_(_ittapi_global).thread_list == NULL)
623 {
624 __itt_init_ittlib_name(NULL, __itt_group_all);
625 }
626 if (ITTNOTIFY_NAME(thread_set_nameW) && ITTNOTIFY_NAME(thread_set_nameW) != ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_nameW),_init)))
627 {
628 ITTNOTIFY_NAME(thread_set_nameW)(name);
629 }
630 }
631
ITT_VERSIONIZE(ITT_JOIN (_N_ (thr_name_setW),_init))632 static int ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(thr_name_setW),_init))(const wchar_t* name, int namelen)
633 {
634 (void)namelen;
635 ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_nameW),_init))(name);
636 return 0;
637 }
638
ITT_VERSIONIZE(ITT_JOIN (_N_ (thread_set_nameA),_init))639 static void ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_nameA),_init))(const char* name)
640 #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
641 static void ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_name),_init))(const char* name)
642 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
643 {
644 if (!_N_(_ittapi_global).api_initialized && _N_(_ittapi_global).thread_list == NULL)
645 {
646 __itt_init_ittlib_name(NULL, __itt_group_all);
647 }
648 #if ITT_PLATFORM==ITT_PLATFORM_WIN
649 if (ITTNOTIFY_NAME(thread_set_nameA) && ITTNOTIFY_NAME(thread_set_nameA) != ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_nameA),_init)))
650 {
651 ITTNOTIFY_NAME(thread_set_nameA)(name);
652 }
653 #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
654 if (ITTNOTIFY_NAME(thread_set_name) && ITTNOTIFY_NAME(thread_set_name) != ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_name),_init)))
655 {
656 ITTNOTIFY_NAME(thread_set_name)(name);
657 }
658 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
659 }
660
661 #if ITT_PLATFORM==ITT_PLATFORM_WIN
ITT_VERSIONIZE(ITT_JOIN (_N_ (thr_name_setA),_init))662 static int ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(thr_name_setA),_init))(const char* name, int namelen)
663 {
664 (void)namelen;
665 ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_nameA),_init))(name);
666 return 0;
667 }
668 #else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
ITT_VERSIONIZE(ITT_JOIN (_N_ (thr_name_set),_init))669 static int ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(thr_name_set),_init))(const char* name, int namelen)
670 {
671 (void)namelen;
672 ITT_VERSIONIZE(ITT_JOIN(_N_(thread_set_name),_init))(name);
673 return 0;
674 }
675 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
676
ITT_VERSIONIZE(ITT_JOIN (_N_ (thread_ignore),_init))677 static void ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(thread_ignore),_init))(void)
678 {
679 if (!_N_(_ittapi_global).api_initialized && _N_(_ittapi_global).thread_list == NULL)
680 {
681 __itt_init_ittlib_name(NULL, __itt_group_all);
682 }
683 if (ITTNOTIFY_NAME(thread_ignore) && ITTNOTIFY_NAME(thread_ignore) != ITT_VERSIONIZE(ITT_JOIN(_N_(thread_ignore),_init)))
684 {
685 ITTNOTIFY_NAME(thread_ignore)();
686 }
687 }
688
ITT_VERSIONIZE(ITT_JOIN (_N_ (thr_ignore),_init))689 static void ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(thr_ignore),_init))(void)
690 {
691 ITT_VERSIONIZE(ITT_JOIN(_N_(thread_ignore),_init))();
692 }
693
ITT_VERSIONIZE(ITT_JOIN (_N_ (enable_attach),_init))694 static void ITTAPI ITT_VERSIONIZE(ITT_JOIN(_N_(enable_attach),_init))(void)
695 {
696 #ifdef __ANDROID__
697 /*
698 * if LIB_VAR_NAME env variable were set before then stay previous value
699 * else set default path
700 */
701 setenv(ITT_TO_STR(LIB_VAR_NAME), ANDROID_ITTNOTIFY_DEFAULT_PATH, 0);
702 #endif
703 }
704
705 /* -------------------------------------------------------------------------- */
706
__itt_fsplit(const char * s,const char * sep,const char ** out,int * len)707 static const char* __itt_fsplit(const char* s, const char* sep, const char** out, int* len)
708 {
709 int i;
710 int j;
711
712 if (!s || !sep || !out || !len)
713 return NULL;
714
715 for (i = 0; s[i]; i++)
716 {
717 int b = 0;
718 for (j = 0; sep[j]; j++)
719 if (s[i] == sep[j])
720 {
721 b = 1;
722 break;
723 }
724 if (!b)
725 break;
726 }
727
728 if (!s[i])
729 return NULL;
730
731 *len = 0;
732 *out = &s[i];
733
734 for (; s[i]; i++, (*len)++)
735 {
736 int b = 0;
737 for (j = 0; sep[j]; j++)
738 if (s[i] == sep[j])
739 {
740 b = 1;
741 break;
742 }
743 if (b)
744 break;
745 }
746
747 for (; s[i]; i++)
748 {
749 int b = 0;
750 for (j = 0; sep[j]; j++)
751 if (s[i] == sep[j])
752 {
753 b = 1;
754 break;
755 }
756 if (!b)
757 break;
758 }
759
760 return &s[i];
761 }
762
763 /* This function return value of env variable that placed into static buffer.
764 * !!! The same static buffer is used for subsequent calls. !!!
765 * This was done to avoid dynamic allocation for few calls.
766 * Actually we need this function only four times.
767 */
__itt_get_env_var(const char * name)768 static const char* __itt_get_env_var(const char* name)
769 {
770 #define MAX_ENV_VALUE_SIZE 4086
771 static char env_buff[MAX_ENV_VALUE_SIZE];
772 static char* env_value = (char*)env_buff;
773
774 if (name != NULL)
775 {
776 #if ITT_PLATFORM==ITT_PLATFORM_WIN
777 size_t max_len = MAX_ENV_VALUE_SIZE - (size_t)(env_value - env_buff);
778 DWORD rc = GetEnvironmentVariableA(name, env_value, (DWORD)max_len);
779 if (rc >= max_len)
780 __itt_report_error(__itt_error_env_too_long, name, (size_t)rc - 1, (size_t)(max_len - 1));
781 else if (rc > 0)
782 {
783 const char* ret = (const char*)env_value;
784 env_value += rc + 1;
785 return ret;
786 }
787 else
788 {
789 /* If environment variable is empty, GetEnvironmentVariables()
790 * returns zero (number of characters (not including terminating null),
791 * and GetLastError() returns ERROR_SUCCESS. */
792 DWORD err = GetLastError();
793 if (err == ERROR_SUCCESS)
794 return env_value;
795
796 if (err != ERROR_ENVVAR_NOT_FOUND)
797 __itt_report_error(__itt_error_cant_read_env, name, (int)err);
798 }
799 #else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */
800 char* env = getenv(name);
801 if (env != NULL)
802 {
803 size_t len = __itt_fstrnlen(env, MAX_ENV_VALUE_SIZE);
804 size_t max_len = MAX_ENV_VALUE_SIZE - (size_t)(env_value - env_buff);
805 if (len < max_len)
806 {
807 const char* ret = (const char*)env_value;
808 __itt_fstrcpyn(env_value, max_len, env, len + 1);
809 env_value += len + 1;
810 return ret;
811 } else
812 __itt_report_error(__itt_error_env_too_long, name, (size_t)len, (size_t)(max_len - 1));
813 }
814 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
815 }
816 return NULL;
817 }
818
__itt_get_lib_name(void)819 static const char* __itt_get_lib_name(void)
820 {
821 const char* lib_name = __itt_get_env_var(ITT_TO_STR(LIB_VAR_NAME));
822
823 #ifdef __ANDROID__
824 if (lib_name == NULL)
825 {
826
827 #if ITT_ARCH==ITT_ARCH_IA32 || ITT_ARCH==ITT_ARCH_ARM
828 const char* const marker_filename = "com.intel.itt.collector_lib_32";
829 #else
830 const char* const marker_filename = "com.intel.itt.collector_lib_64";
831 #endif
832
833 char system_wide_marker_filename[PATH_MAX] = {0};
834 int itt_marker_file_fd = -1;
835 ssize_t res = 0;
836
837 res = snprintf(system_wide_marker_filename, PATH_MAX - 1, "%s%s", "/data/local/tmp/", marker_filename);
838 if (res < 0)
839 {
840 ITT_ANDROID_LOGE("Unable to concatenate marker file string.");
841 return lib_name;
842 }
843 itt_marker_file_fd = open(system_wide_marker_filename, O_RDONLY);
844
845 if (itt_marker_file_fd == -1)
846 {
847 const pid_t my_pid = getpid();
848 char cmdline_path[PATH_MAX] = {0};
849 char package_name[PATH_MAX] = {0};
850 char app_sandbox_file[PATH_MAX] = {0};
851 int cmdline_fd = 0;
852
853 ITT_ANDROID_LOGI("Unable to open system-wide marker file.");
854 res = snprintf(cmdline_path, PATH_MAX - 1, "/proc/%d/cmdline", my_pid);
855 if (res < 0)
856 {
857 ITT_ANDROID_LOGE("Unable to get cmdline path string.");
858 return lib_name;
859 }
860
861 ITT_ANDROID_LOGI("CMD file: %s\n", cmdline_path);
862 cmdline_fd = open(cmdline_path, O_RDONLY);
863 if (cmdline_fd == -1)
864 {
865 ITT_ANDROID_LOGE("Unable to open %s file!", cmdline_path);
866 return lib_name;
867 }
868 res = read(cmdline_fd, package_name, PATH_MAX - 1);
869 if (res == -1)
870 {
871 ITT_ANDROID_LOGE("Unable to read %s file!", cmdline_path);
872 res = close(cmdline_fd);
873 if (res == -1)
874 {
875 ITT_ANDROID_LOGE("Unable to close %s file!", cmdline_path);
876 }
877 return lib_name;
878 }
879 res = close(cmdline_fd);
880 if (res == -1)
881 {
882 ITT_ANDROID_LOGE("Unable to close %s file!", cmdline_path);
883 return lib_name;
884 }
885 ITT_ANDROID_LOGI("Package name: %s\n", package_name);
886 res = snprintf(app_sandbox_file, PATH_MAX - 1, "/data/data/%s/%s", package_name, marker_filename);
887 if (res < 0)
888 {
889 ITT_ANDROID_LOGE("Unable to concatenate marker file string.");
890 return lib_name;
891 }
892
893 ITT_ANDROID_LOGI("Lib marker file name: %s\n", app_sandbox_file);
894 itt_marker_file_fd = open(app_sandbox_file, O_RDONLY);
895 if (itt_marker_file_fd == -1)
896 {
897 ITT_ANDROID_LOGE("Unable to open app marker file!");
898 return lib_name;
899 }
900 }
901
902 {
903 char itt_lib_name[PATH_MAX] = {0};
904
905 res = read(itt_marker_file_fd, itt_lib_name, PATH_MAX - 1);
906 if (res == -1)
907 {
908 ITT_ANDROID_LOGE("Unable to read %s file!", itt_marker_file_fd);
909 res = close(itt_marker_file_fd);
910 if (res == -1)
911 {
912 ITT_ANDROID_LOGE("Unable to close %s file!", itt_marker_file_fd);
913 }
914 return lib_name;
915 }
916 ITT_ANDROID_LOGI("ITT Lib path: %s", itt_lib_name);
917 res = close(itt_marker_file_fd);
918 if (res == -1)
919 {
920 ITT_ANDROID_LOGE("Unable to close %s file!", itt_marker_file_fd);
921 return lib_name;
922 }
923 ITT_ANDROID_LOGI("Set env %s to %s", ITT_TO_STR(LIB_VAR_NAME), itt_lib_name);
924 res = setenv(ITT_TO_STR(LIB_VAR_NAME), itt_lib_name, 0);
925 if (res == -1)
926 {
927 ITT_ANDROID_LOGE("Unable to set env var!");
928 return lib_name;
929 }
930 lib_name = __itt_get_env_var(ITT_TO_STR(LIB_VAR_NAME));
931 ITT_ANDROID_LOGI("ITT Lib path from env: %s", lib_name);
932 }
933 }
934 #endif
935
936 return lib_name;
937 }
938
939 /* Avoid clashes with std::min, reported by tbb team */
940 #define __itt_min(a,b) (a) < (b) ? (a) : (b)
941
__itt_get_groups(void)942 static __itt_group_id __itt_get_groups(void)
943 {
944 int i;
945 __itt_group_id res = __itt_group_none;
946 const char* var_name = "INTEL_ITTNOTIFY_GROUPS";
947 const char* group_str = __itt_get_env_var(var_name);
948
949 if (group_str != NULL)
950 {
951 int len;
952 char gr[255];
953 const char* chunk;
954 while ((group_str = __itt_fsplit(group_str, ",; ", &chunk, &len)) != NULL)
955 {
956 int min_len = __itt_min(len, (int)(sizeof(gr) - 1));
957 __itt_fstrcpyn(gr, sizeof(gr) - 1, chunk, min_len);
958 gr[min_len] = 0;
959
960 for (i = 0; group_list[i].name != NULL; i++)
961 {
962 if (!__itt_fstrcmp(gr, group_list[i].name))
963 {
964 res = (__itt_group_id)(res | group_list[i].id);
965 break;
966 }
967 }
968 }
969 /* TODO: !!! Workaround for bug with warning for unknown group !!!
970 * Should be fixed in new initialization scheme.
971 * Now the following groups should be set always. */
972 for (i = 0; group_list[i].id != __itt_group_none; i++)
973 if (group_list[i].id != __itt_group_all &&
974 group_list[i].id > __itt_group_splitter_min &&
975 group_list[i].id < __itt_group_splitter_max)
976 res = (__itt_group_id)(res | group_list[i].id);
977 return res;
978 }
979 else
980 {
981 for (i = 0; group_alias[i].env_var != NULL; i++)
982 if (__itt_get_env_var(group_alias[i].env_var) != NULL)
983 return group_alias[i].groups;
984 }
985
986 return res;
987 }
988
989 #undef __itt_min
990
__itt_lib_version(lib_t lib)991 static int __itt_lib_version(lib_t lib)
992 {
993 if (lib == NULL)
994 return 0;
995 if (__itt_get_proc(lib, "__itt_api_init"))
996 return 2;
997 if (__itt_get_proc(lib, "__itt_api_version"))
998 return 1;
999 return 0;
1000 }
1001
1002 /* It's not used right now! Comment it out to avoid warnings.
1003 static void __itt_reinit_all_pointers(void)
1004 {
1005 int i;
1006 // Fill all pointers with initial stubs
1007 for (i = 0; _N_(_ittapi_global).api_list_ptr[i].name != NULL; i++)
1008 *_N_(_ittapi_global).api_list_ptr[i].func_ptr = _N_(_ittapi_global).api_list_ptr[i].init_func;
1009 }
1010 */
1011
__itt_nullify_all_pointers(void)1012 static void __itt_nullify_all_pointers(void)
1013 {
1014 int i;
1015 /* Nullify all pointers except domain_create, string_handle_create and counter_create */
1016 for (i = 0; _N_(_ittapi_global).api_list_ptr[i].name != NULL; i++)
1017 *_N_(_ittapi_global).api_list_ptr[i].func_ptr = _N_(_ittapi_global).api_list_ptr[i].null_func;
1018 }
1019
1020 #if ITT_PLATFORM==ITT_PLATFORM_WIN && KMP_MSVC_COMPAT
1021 #pragma warning(push)
1022 #pragma warning(disable: 4054) /* warning C4054: 'type cast' : from function pointer 'XXX' to data pointer 'void *' */
1023 #pragma warning(disable: 4055) /* warning C4055: 'type cast' : from data pointer 'void *' to function pointer 'XXX' */
1024 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
1025
_N_(fini_ittlib)1026 ITT_EXTERN_C void _N_(fini_ittlib)(void)
1027 {
1028 __itt_api_fini_t* __itt_api_fini_ptr = NULL;
1029 static volatile TIDT current_thread = 0;
1030
1031 if (_N_(_ittapi_global).api_initialized)
1032 {
1033 ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global));
1034 if (_N_(_ittapi_global).api_initialized)
1035 {
1036 if (current_thread == 0)
1037 {
1038 if (PTHREAD_SYMBOLS) current_thread = __itt_thread_id();
1039 if (_N_(_ittapi_global).lib != NULL)
1040 {
1041 __itt_api_fini_ptr = (__itt_api_fini_t*)(size_t)__itt_get_proc(_N_(_ittapi_global).lib, "__itt_api_fini");
1042 }
1043 if (__itt_api_fini_ptr)
1044 {
1045 __itt_api_fini_ptr(&_N_(_ittapi_global));
1046 }
1047
1048 __itt_nullify_all_pointers();
1049
1050 /* TODO: !!! not safe !!! don't support unload so far.
1051 * if (_N_(_ittapi_global).lib != NULL)
1052 * __itt_unload_lib(_N_(_ittapi_global).lib);
1053 * _N_(_ittapi_global).lib = NULL;
1054 */
1055 _N_(_ittapi_global).api_initialized = 0;
1056 current_thread = 0;
1057 }
1058 }
1059 if (PTHREAD_SYMBOLS) __itt_mutex_unlock(&_N_(_ittapi_global).mutex);
1060 }
1061 }
1062
_N_(init_ittlib)1063 ITT_EXTERN_C int _N_(init_ittlib)(const char* lib_name, __itt_group_id init_groups)
1064 {
1065 int i;
1066 __itt_group_id groups;
1067 #ifdef ITT_COMPLETE_GROUP
1068 __itt_group_id zero_group = __itt_group_none;
1069 #endif /* ITT_COMPLETE_GROUP */
1070 static volatile TIDT current_thread = 0;
1071
1072 if (!_N_(_ittapi_global).api_initialized)
1073 {
1074 #ifndef ITT_SIMPLE_INIT
1075 ITT_MUTEX_INIT_AND_LOCK(_N_(_ittapi_global));
1076 #endif /* ITT_SIMPLE_INIT */
1077
1078 if (!_N_(_ittapi_global).api_initialized)
1079 {
1080 if (current_thread == 0)
1081 {
1082 if (PTHREAD_SYMBOLS) current_thread = __itt_thread_id();
1083 if (lib_name == NULL)
1084 {
1085 lib_name = __itt_get_lib_name();
1086 }
1087 groups = __itt_get_groups();
1088 if (DL_SYMBOLS && (groups != __itt_group_none || lib_name != NULL))
1089 {
1090 _N_(_ittapi_global).lib = __itt_load_lib((lib_name == NULL) ? ittnotify_lib_name : lib_name);
1091
1092 if (_N_(_ittapi_global).lib != NULL)
1093 {
1094 __itt_api_init_t* __itt_api_init_ptr;
1095 int lib_version = __itt_lib_version(_N_(_ittapi_global).lib);
1096
1097 switch (lib_version) {
1098 case 0:
1099 groups = __itt_group_legacy;
1100 KMP_FALLTHROUGH();
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
_N_(set_error_handler)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 */
1202