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