1 /*
2     Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
3 
4     This file is part of Threading Building Blocks. Threading Building Blocks is free software;
5     you can redistribute it and/or modify it under the terms of the GNU General Public License
6     version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
7     distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
8     implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
9     See  the GNU General Public License for more details.   You should have received a copy of
10     the  GNU General Public License along with Threading Building Blocks; if not, write to the
11     Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
12 
13     As a special exception,  you may use this file  as part of a free software library without
14     restriction.  Specifically,  if other files instantiate templates  or use macros or inline
15     functions from this file, or you compile this file and link it with other files to produce
16     an executable,  this file does not by itself cause the resulting executable to be covered
17     by the GNU General Public License. This exception does not however invalidate any other
18     reasons why the executable file might be covered by the GNU General Public License.
19 */
20 
21 #ifndef _ITTNOTIFY_CONFIG_H_
22 #define _ITTNOTIFY_CONFIG_H_
23 
24 /** @cond exclude_from_documentation */
25 #ifndef ITT_OS_WIN
26 #  define ITT_OS_WIN   1
27 #endif /* ITT_OS_WIN */
28 
29 #ifndef ITT_OS_LINUX
30 #  define ITT_OS_LINUX 2
31 #endif /* ITT_OS_LINUX */
32 
33 #ifndef ITT_OS_MAC
34 #  define ITT_OS_MAC   3
35 #endif /* ITT_OS_MAC */
36 
37 #ifndef ITT_OS
38 #  if defined WIN32 || defined _WIN32
39 #    define ITT_OS ITT_OS_WIN
40 #  elif defined( __APPLE__ ) && defined( __MACH__ )
41 #    define ITT_OS ITT_OS_MAC
42 #  else
43 #    define ITT_OS ITT_OS_LINUX
44 #  endif
45 #endif /* ITT_OS */
46 
47 #ifndef ITT_PLATFORM_WIN
48 #  define ITT_PLATFORM_WIN 1
49 #endif /* ITT_PLATFORM_WIN */
50 
51 #ifndef ITT_PLATFORM_POSIX
52 #  define ITT_PLATFORM_POSIX 2
53 #endif /* ITT_PLATFORM_POSIX */
54 
55 #ifndef ITT_PLATFORM_MAC
56 #  define ITT_PLATFORM_MAC 3
57 #endif /* ITT_PLATFORM_MAC */
58 
59 #ifndef ITT_PLATFORM
60 #  if ITT_OS==ITT_OS_WIN
61 #    define ITT_PLATFORM ITT_PLATFORM_WIN
62 #  elif ITT_OS==ITT_OS_MAC
63 #    define ITT_PLATFORM ITT_PLATFORM_MAC
64 #  else
65 #    define ITT_PLATFORM ITT_PLATFORM_POSIX
66 #  endif
67 #endif /* ITT_PLATFORM */
68 
69 #if defined(_UNICODE) && !defined(UNICODE)
70 #define UNICODE
71 #endif
72 
73 #include <stddef.h>
74 #if ITT_PLATFORM==ITT_PLATFORM_WIN
75 #include <tchar.h>
76 #else  /* ITT_PLATFORM==ITT_PLATFORM_WIN */
77 #include <stdint.h>
78 #if defined(UNICODE) || defined(_UNICODE)
79 #include <wchar.h>
80 #endif /* UNICODE || _UNICODE */
81 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
82 
83 #ifndef CDECL
84 #  if ITT_PLATFORM==ITT_PLATFORM_WIN
85 #    define CDECL __cdecl
86 #  else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
87 #    if defined _M_IX86 || defined __i386__
88 #      define CDECL __attribute__ ((cdecl))
89 #    else  /* _M_IX86 || __i386__ */
90 #      define CDECL /* actual only on x86 platform */
91 #    endif /* _M_IX86 || __i386__ */
92 #  endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
93 #endif /* CDECL */
94 
95 #ifndef STDCALL
96 #  if ITT_PLATFORM==ITT_PLATFORM_WIN
97 #    define STDCALL __stdcall
98 #  else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
99 #    if defined _M_IX86 || defined __i386__
100 #      define STDCALL __attribute__ ((stdcall))
101 #    else  /* _M_IX86 || __i386__ */
102 #      define STDCALL /* supported only on x86 platform */
103 #    endif /* _M_IX86 || __i386__ */
104 #  endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
105 #endif /* STDCALL */
106 
107 #define ITTAPI    CDECL
108 #define LIBITTAPI CDECL
109 
110 /* TODO: Temporary for compatibility! */
111 #define ITTAPI_CALL    CDECL
112 #define LIBITTAPI_CALL CDECL
113 
114 #if ITT_PLATFORM==ITT_PLATFORM_WIN
115 /* use __forceinline (VC++ specific) */
116 #define ITT_INLINE           __forceinline
117 #define ITT_INLINE_ATTRIBUTE /* nothing */
118 #else  /* ITT_PLATFORM==ITT_PLATFORM_WIN */
119 /*
120  * Generally, functions are not inlined unless optimization is specified.
121  * For functions declared inline, this attribute inlines the function even
122  * if no optimization level was specified.
123  */
124 #ifdef __STRICT_ANSI__
125 #define ITT_INLINE           static inline
126 #else  /* __STRICT_ANSI__ */
127 #define ITT_INLINE           static inline
128 #endif /* __STRICT_ANSI__ */
129 #define ITT_INLINE_ATTRIBUTE __attribute__ ((always_inline, unused))
130 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
131 /** @endcond */
132 
133 #ifndef ITT_ARCH_IA32
134 #  define ITT_ARCH_IA32  1
135 #endif /* ITT_ARCH_IA32 */
136 
137 #ifndef ITT_ARCH_IA32E
138 #  define ITT_ARCH_IA32E 2
139 #endif /* ITT_ARCH_IA32E */
140 
141 #ifndef ITT_ARCH_ARM
142 #  define ITT_ARCH_ARM  4
143 #endif /* ITT_ARCH_ARM */
144 
145 #ifndef ITT_ARCH
146 #  if defined _M_IX86 || defined __i386__
147 #    define ITT_ARCH ITT_ARCH_IA32
148 #  elif defined _M_X64 || defined _M_AMD64 || defined __x86_64__
149 #    define ITT_ARCH ITT_ARCH_IA32E
150 #  elif defined _M_IA64 || defined __ia64__
151 #    define ITT_ARCH ITT_ARCH_IA64
152 #  elif defined _M_ARM || __arm__
153 #    define ITT_ARCH ITT_ARCH_ARM
154 #  endif
155 #endif
156 
157 #ifdef __cplusplus
158 #  define ITT_EXTERN_C extern "C"
159 #else
160 #  define ITT_EXTERN_C /* nothing */
161 #endif /* __cplusplus */
162 
163 #define ITT_TO_STR_AUX(x) #x
164 #define ITT_TO_STR(x)     ITT_TO_STR_AUX(x)
165 
166 #define __ITT_BUILD_ASSERT(expr, suffix) do { \
167     static char __itt_build_check_##suffix[(expr) ? 1 : -1]; \
168     __itt_build_check_##suffix[0] = 0; \
169 } while(0)
170 #define _ITT_BUILD_ASSERT(expr, suffix)  __ITT_BUILD_ASSERT((expr), suffix)
171 #define ITT_BUILD_ASSERT(expr)           _ITT_BUILD_ASSERT((expr), __LINE__)
172 
173 #define ITT_MAGIC { 0xED, 0xAB, 0xAB, 0xEC, 0x0D, 0xEE, 0xDA, 0x30 }
174 
175 /* Replace with snapshot date YYYYMMDD for promotion build. */
176 #define API_VERSION_BUILD    20111111
177 
178 #ifndef API_VERSION_NUM
179 #define API_VERSION_NUM 0.0.0
180 #endif /* API_VERSION_NUM */
181 
182 #define API_VERSION "ITT-API-Version " ITT_TO_STR(API_VERSION_NUM) \
183                                 " (" ITT_TO_STR(API_VERSION_BUILD) ")"
184 
185 /* OS communication functions */
186 #if ITT_PLATFORM==ITT_PLATFORM_WIN
187 #include <windows.h>
188 typedef HMODULE           lib_t;
189 typedef DWORD             TIDT;
190 typedef CRITICAL_SECTION  mutex_t;
191 #define MUTEX_INITIALIZER { 0 }
192 #define strong_alias(name, aliasname) /* empty for Windows */
193 #else  /* ITT_PLATFORM==ITT_PLATFORM_WIN */
194 #include <dlfcn.h>
195 #if defined(UNICODE) || defined(_UNICODE)
196 #include <wchar.h>
197 #endif /* UNICODE */
198 #ifndef _GNU_SOURCE
199 #define _GNU_SOURCE 1 /* need for PTHREAD_MUTEX_RECURSIVE */
200 #endif /* _GNU_SOURCE */
201 #ifndef __USE_UNIX98
202 #define __USE_UNIX98 1 /* need for PTHREAD_MUTEX_RECURSIVE, on SLES11.1 with gcc 4.3.4 wherein pthread.h missing dependency on __USE_XOPEN2K8 */
203 #endif /*__USE_UNIX98*/
204 #include <pthread.h>
205 typedef void*             lib_t;
206 typedef pthread_t         TIDT;
207 typedef pthread_mutex_t   mutex_t;
208 #define MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
209 #define _strong_alias(name, aliasname) \
210             extern __typeof (name) aliasname __attribute__ ((alias (#name)));
211 #define strong_alias(name, aliasname) _strong_alias(name, aliasname)
212 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
213 
214 #if ITT_PLATFORM==ITT_PLATFORM_WIN
215 #define __itt_get_proc(lib, name) GetProcAddress(lib, name)
216 #define __itt_mutex_init(mutex)   InitializeCriticalSection(mutex)
217 #define __itt_mutex_lock(mutex)   EnterCriticalSection(mutex)
218 #define __itt_mutex_unlock(mutex) LeaveCriticalSection(mutex)
219 #define __itt_load_lib(name)      LoadLibraryA(name)
220 #define __itt_unload_lib(handle)  FreeLibrary(handle)
221 #define __itt_system_error()      (int)GetLastError()
222 #define __itt_fstrcmp(s1, s2)     lstrcmpA(s1, s2)
223 #define __itt_fstrlen(s)          lstrlenA(s)
224 #define __itt_fstrcpyn(s1, s2, l) lstrcpynA(s1, s2, l)
225 #define __itt_fstrdup(s)          _strdup(s)
226 #define __itt_thread_id()         GetCurrentThreadId()
227 #define __itt_thread_yield()      SwitchToThread()
228 #ifndef ITT_SIMPLE_INIT
229 ITT_INLINE long
230 __itt_interlocked_increment(volatile long* ptr) ITT_INLINE_ATTRIBUTE;
__itt_interlocked_increment(volatile long * ptr)231 ITT_INLINE long __itt_interlocked_increment(volatile long* ptr)
232 {
233     return InterlockedIncrement(ptr);
234 }
235 #endif /* ITT_SIMPLE_INIT */
236 #else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */
237 #define __itt_get_proc(lib, name) dlsym(lib, name)
238 #define __itt_mutex_init(mutex)   {\
239     pthread_mutexattr_t mutex_attr;                                         \
240     int error_code = pthread_mutexattr_init(&mutex_attr);                   \
241     if (error_code)                                                         \
242         __itt_report_error(__itt_error_system, "pthread_mutexattr_init",    \
243                            error_code);                                     \
244     error_code = pthread_mutexattr_settype(&mutex_attr,                     \
245                                            PTHREAD_MUTEX_RECURSIVE);        \
246     if (error_code)                                                         \
247         __itt_report_error(__itt_error_system, "pthread_mutexattr_settype", \
248                            error_code);                                     \
249     error_code = pthread_mutex_init(mutex, &mutex_attr);                    \
250     if (error_code)                                                         \
251         __itt_report_error(__itt_error_system, "pthread_mutex_init",        \
252                            error_code);                                     \
253     error_code = pthread_mutexattr_destroy(&mutex_attr);                    \
254     if (error_code)                                                         \
255         __itt_report_error(__itt_error_system, "pthread_mutexattr_destroy", \
256                            error_code);                                     \
257 }
258 #define __itt_mutex_lock(mutex)   pthread_mutex_lock(mutex)
259 #define __itt_mutex_unlock(mutex) pthread_mutex_unlock(mutex)
260 #define __itt_load_lib(name)      dlopen(name, RTLD_LAZY)
261 #define __itt_unload_lib(handle)  dlclose(handle)
262 #define __itt_system_error()      errno
263 #define __itt_fstrcmp(s1, s2)     strcmp(s1, s2)
264 #define __itt_fstrlen(s)          strlen(s)
265 #define __itt_fstrcpyn(s1, s2, l) strncpy(s1, s2, l)
266 #define __itt_fstrdup(s)          strdup(s)
267 #define __itt_thread_id()         pthread_self()
268 #define __itt_thread_yield()      sched_yield()
269 #if ITT_ARCH==ITT_ARCH_IA64
270 #ifdef __INTEL_COMPILER
271 #define __TBB_machine_fetchadd4(addr, val) __fetchadd4_acq((void *)addr, val)
272 #else  /* __INTEL_COMPILER */
273 /* TODO: Add Support for not Intel compilers for IA-64 architecture */
274 #endif /* __INTEL_COMPILER */
275 #elif ITT_ARCH==ITT_ARCH_IA32 || ITT_ARCH==ITT_ARCH_IA32E /* ITT_ARCH!=ITT_ARCH_IA64 */
276 ITT_INLINE long
277 __TBB_machine_fetchadd4(volatile void* ptr, long addend) ITT_INLINE_ATTRIBUTE;
__TBB_machine_fetchadd4(volatile void * ptr,long addend)278 ITT_INLINE long __TBB_machine_fetchadd4(volatile void* ptr, long addend)
279 {
280     long result;
281     __asm__ __volatile__("lock\nxadd %0,%1"
282                           : "=r"(result),"=m"(*(int*)ptr)
283                           : "0"(addend), "m"(*(int*)ptr)
284                           : "memory");
285     return result;
286 }
287 #elif ITT_ARCH==ITT_ARCH_ARM
288 #define __TBB_machine_fetchadd4(addr, val) __sync_fetch_and_add(addr, val)
289 #endif /* ITT_ARCH==ITT_ARCH_IA64 */
290 #ifndef ITT_SIMPLE_INIT
291 ITT_INLINE long
292 __itt_interlocked_increment(volatile long* ptr) ITT_INLINE_ATTRIBUTE;
__itt_interlocked_increment(volatile long * ptr)293 ITT_INLINE long __itt_interlocked_increment(volatile long* ptr)
294 {
295     return __TBB_machine_fetchadd4(ptr, 1) + 1L;
296 }
297 #endif /* ITT_SIMPLE_INIT */
298 #endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
299 
300 typedef enum {
301     __itt_collection_normal = 0,
302     __itt_collection_paused = 1
303 } __itt_collection_state;
304 
305 typedef enum {
306     __itt_thread_normal  = 0,
307     __itt_thread_ignored = 1
308 } __itt_thread_state;
309 
310 #pragma pack(push, 8)
311 
312 typedef struct ___itt_thread_info
313 {
314     const char* nameA; /*!< Copy of original name in ASCII. */
315 #if defined(UNICODE) || defined(_UNICODE)
316     const wchar_t* nameW; /*!< Copy of original name in UNICODE. */
317 #else  /* UNICODE || _UNICODE */
318     void* nameW;
319 #endif /* UNICODE || _UNICODE */
320     TIDT               tid;
321     __itt_thread_state state;   /*!< Thread state (paused or normal) */
322     int                extra1;  /*!< Reserved to the runtime */
323     void*              extra2;  /*!< Reserved to the runtime */
324     struct ___itt_thread_info* next;
325 } __itt_thread_info;
326 
327 #include "ittnotify_types.h" /* For __itt_group_id definition */
328 
329 typedef struct ___itt_api_info_20101001
330 {
331     const char*    name;
332     void**         func_ptr;
333     void*          init_func;
334     __itt_group_id group;
335 }  __itt_api_info_20101001;
336 
337 typedef struct ___itt_api_info
338 {
339     const char*    name;
340     void**         func_ptr;
341     void*          init_func;
342     void*          null_func;
343     __itt_group_id group;
344 }  __itt_api_info;
345 
346 struct ___itt_domain;
347 struct ___itt_string_handle;
348 
349 typedef struct ___itt_global
350 {
351     unsigned char          magic[8];
352     unsigned long          version_major;
353     unsigned long          version_minor;
354     unsigned long          version_build;
355     volatile long          api_initialized;
356     volatile long          mutex_initialized;
357     volatile long          atomic_counter;
358     mutex_t                mutex;
359     lib_t                  lib;
360     void*                  error_handler;
361     const char**           dll_path_ptr;
362     __itt_api_info*        api_list_ptr;
363     struct ___itt_global*  next;
364     /* Joinable structures below */
365     __itt_thread_info*     thread_list;
366     struct ___itt_domain*  domain_list;
367     struct ___itt_string_handle* string_list;
368     __itt_collection_state state;
369 } __itt_global;
370 
371 #pragma pack(pop)
372 
373 #define NEW_THREAD_INFO_W(gptr,h,h_tail,t,s,n) { \
374     h = (__itt_thread_info*)malloc(sizeof(__itt_thread_info)); \
375     if (h != NULL) { \
376         h->tid    = t; \
377         h->nameA  = NULL; \
378         h->nameW  = n ? _wcsdup(n) : NULL; \
379         h->state  = s; \
380         h->extra1 = 0;    /* reserved */ \
381         h->extra2 = NULL; /* reserved */ \
382         h->next   = NULL; \
383         if (h_tail == NULL) \
384             (gptr)->thread_list = h; \
385         else \
386             h_tail->next = h; \
387     } \
388 }
389 
390 #define NEW_THREAD_INFO_A(gptr,h,h_tail,t,s,n) { \
391     h = (__itt_thread_info*)malloc(sizeof(__itt_thread_info)); \
392     if (h != NULL) { \
393         h->tid    = t; \
394         h->nameA  = n ? __itt_fstrdup(n) : NULL; \
395         h->nameW  = NULL; \
396         h->state  = s; \
397         h->extra1 = 0;    /* reserved */ \
398         h->extra2 = NULL; /* reserved */ \
399         h->next   = NULL; \
400         if (h_tail == NULL) \
401             (gptr)->thread_list = h; \
402         else \
403             h_tail->next = h; \
404     } \
405 }
406 
407 #define NEW_DOMAIN_W(gptr,h,h_tail,name) { \
408     h = (__itt_domain*)malloc(sizeof(__itt_domain)); \
409     if (h != NULL) { \
410         h->flags  = 0;    /* domain is disabled by default */ \
411         h->nameA  = NULL; \
412         h->nameW  = name ? _wcsdup(name) : NULL; \
413         h->extra1 = 0;    /* reserved */ \
414         h->extra2 = NULL; /* reserved */ \
415         h->next   = NULL; \
416         if (h_tail == NULL) \
417             (gptr)->domain_list = h; \
418         else \
419             h_tail->next = h; \
420     } \
421 }
422 
423 #define NEW_DOMAIN_A(gptr,h,h_tail,name) { \
424     h = (__itt_domain*)malloc(sizeof(__itt_domain)); \
425     if (h != NULL) { \
426         h->flags  = 0;    /* domain is disabled by default */ \
427         h->nameA  = name ? __itt_fstrdup(name) : NULL; \
428         h->nameW  = NULL; \
429         h->extra1 = 0;    /* reserved */ \
430         h->extra2 = NULL; /* reserved */ \
431         h->next   = NULL; \
432         if (h_tail == NULL) \
433             (gptr)->domain_list = h; \
434         else \
435             h_tail->next = h; \
436     } \
437 }
438 
439 #define NEW_STRING_HANDLE_W(gptr,h,h_tail,name) { \
440     h = (__itt_string_handle*)malloc(sizeof(__itt_string_handle)); \
441     if (h != NULL) { \
442         h->strA   = NULL; \
443         h->strW   = name ? _wcsdup(name) : NULL; \
444         h->extra1 = 0;    /* reserved */ \
445         h->extra2 = NULL; /* reserved */ \
446         h->next   = NULL; \
447         if (h_tail == NULL) \
448             (gptr)->string_list = h; \
449         else \
450             h_tail->next = h; \
451     } \
452 }
453 
454 #define NEW_STRING_HANDLE_A(gptr,h,h_tail,name) { \
455     h = (__itt_string_handle*)malloc(sizeof(__itt_string_handle)); \
456     if (h != NULL) { \
457         h->strA   = name ? __itt_fstrdup(name) : NULL; \
458         h->strW   = NULL; \
459         h->extra1 = 0;    /* reserved */ \
460         h->extra2 = NULL; /* reserved */ \
461         h->next   = NULL; \
462         if (h_tail == NULL) \
463             (gptr)->string_list = h; \
464         else \
465             h_tail->next = h; \
466     } \
467 }
468 
469 #endif /* _ITTNOTIFY_CONFIG_H_ */
470