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