1 #if USE_ITT_BUILD
2 /*
3  * kmp_itt.h -- ITT Notify interface.
4  */
5 
6 
7 //===----------------------------------------------------------------------===//
8 //
9 //                     The LLVM Compiler Infrastructure
10 //
11 // This file is dual licensed under the MIT and the University of Illinois Open
12 // Source Licenses. See LICENSE.txt for details.
13 //
14 //===----------------------------------------------------------------------===//
15 
16 
17 #ifndef KMP_ITT_H
18 #define KMP_ITT_H
19 
20 #include "kmp_lock.h"
21 
22 #define INTEL_ITTNOTIFY_API_PRIVATE
23 #include "ittnotify.h"
24 #include "legacy/ittnotify.h"
25 
26 #if KMP_DEBUG
27     #define __kmp_inline           // Turn off inlining in debug mode.
28 #else
29     #define __kmp_inline static inline
30 #endif
31 
32 #if USE_ITT_NOTIFY
33     extern kmp_int32  __kmp_itt_prepare_delay;
34 # ifdef __cplusplus
35     extern "C" void __kmp_itt_fini_ittlib(void);
36 # else
37     extern void __kmp_itt_fini_ittlib(void);
38 # endif
39 #endif
40 
41 // Simplify the handling of an argument that is only required when USE_ITT_BUILD is enabled.
42 #define USE_ITT_BUILD_ARG(x) ,x
43 
44 void __kmp_itt_initialize();
45 void __kmp_itt_destroy();
46 
47 // -------------------------------------------------------------------------------------------------
48 // New stuff for reporting high-level constructs.
49 // -------------------------------------------------------------------------------------------------
50 
51 // Note the naming convention:
52 //     __kmp_itt_xxxing() function should be called before action, while
53 //     __kmp_itt_xxxed()  function should be called after action.
54 
55 // --- Parallel region reporting ---
56 __kmp_inline void __kmp_itt_region_forking(  int gtid, int team_size, int barriers ); // Master only, before forking threads.
57 __kmp_inline void __kmp_itt_region_joined(   int gtid ); // Master only, after joining threads.
58     // (*) Note: A thread may execute tasks after this point, though.
59 
60 // --- Frame reporting ---
61 // region = 0 - no regions, region = 1 - parallel, region = 2 - serialized parallel
62 __kmp_inline void __kmp_itt_frame_submit( int gtid, __itt_timestamp begin, __itt_timestamp end, int imbalance, ident_t *loc, int team_size, int region = 0 );
63 
64 // --- Metadata reporting ---
65 // begin/end - begin/end timestamps of a barrier frame, imbalance - aggregated wait time value, reduction -if this is a reduction barrier
66 __kmp_inline void __kmp_itt_metadata_imbalance( int gtid, kmp_uint64 begin, kmp_uint64 end, kmp_uint64 imbalance, kmp_uint64 reduction );
67 // sched_type: 0 - static, 1 - dynamic, 2 - guided, 3 - custom (all others); iterations - loop trip count, chunk - chunk size
68 __kmp_inline void __kmp_itt_metadata_loop( ident_t * loc, kmp_uint64 sched_type, kmp_uint64 iterations, kmp_uint64 chunk );
69 __kmp_inline void __kmp_itt_metadata_single( ident_t * loc );
70 
71 // --- Barrier reporting ---
72 __kmp_inline void * __kmp_itt_barrier_object( int gtid, int bt, int set_name = 0, int delta = 0 );
73 __kmp_inline void   __kmp_itt_barrier_starting( int gtid, void * object );
74 __kmp_inline void   __kmp_itt_barrier_middle(   int gtid, void * object );
75 __kmp_inline void   __kmp_itt_barrier_finished( int gtid, void * object );
76 
77 // --- Taskwait reporting ---
78 __kmp_inline void * __kmp_itt_taskwait_object( int gtid );
79 __kmp_inline void   __kmp_itt_taskwait_starting( int gtid, void * object );
80 __kmp_inline void   __kmp_itt_taskwait_finished(   int gtid, void * object );
81 
82 // --- Task reporting ---
83 __kmp_inline void   __kmp_itt_task_starting( void * object );
84 __kmp_inline void   __kmp_itt_task_finished( void * object );
85 
86 // --- Lock reporting ---
87 #if KMP_USE_DYNAMIC_LOCK
88 __kmp_inline void   __kmp_itt_lock_creating(  kmp_user_lock_p lock, const ident_t * );
89 #else
90 __kmp_inline void   __kmp_itt_lock_creating(  kmp_user_lock_p lock );
91 #endif
92 __kmp_inline void   __kmp_itt_lock_acquiring( kmp_user_lock_p lock );
93 __kmp_inline void   __kmp_itt_lock_acquired(  kmp_user_lock_p lock );
94 __kmp_inline void   __kmp_itt_lock_releasing( kmp_user_lock_p lock );
95 __kmp_inline void   __kmp_itt_lock_cancelled( kmp_user_lock_p lock );
96 __kmp_inline void   __kmp_itt_lock_destroyed( kmp_user_lock_p lock );
97 
98 // --- Critical reporting ---
99 #if KMP_USE_DYNAMIC_LOCK
100 __kmp_inline void   __kmp_itt_critical_creating(  kmp_user_lock_p lock, const ident_t * );
101 #else
102 __kmp_inline void   __kmp_itt_critical_creating(  kmp_user_lock_p lock );
103 #endif
104 __kmp_inline void   __kmp_itt_critical_acquiring( kmp_user_lock_p lock );
105 __kmp_inline void   __kmp_itt_critical_acquired(  kmp_user_lock_p lock );
106 __kmp_inline void   __kmp_itt_critical_releasing( kmp_user_lock_p lock );
107 __kmp_inline void   __kmp_itt_critical_destroyed( kmp_user_lock_p lock );
108 
109 // --- Single reporting ---
110 __kmp_inline void   __kmp_itt_single_start( int gtid );
111 __kmp_inline void   __kmp_itt_single_end(   int gtid );
112 
113 // --- Ordered reporting ---
114 __kmp_inline void   __kmp_itt_ordered_init(  int gtid );
115 __kmp_inline void   __kmp_itt_ordered_prep(  int gtid );
116 __kmp_inline void   __kmp_itt_ordered_start( int gtid );
117 __kmp_inline void   __kmp_itt_ordered_end(   int gtid );
118 
119 // --- Threads reporting ---
120 __kmp_inline void  __kmp_itt_thread_ignore();
121 __kmp_inline void  __kmp_itt_thread_name( int gtid );
122 
123 // --- System objects ---
124 __kmp_inline void   __kmp_itt_system_object_created( void * object, char const * name );
125 
126 // --- Stack stitching ---
127 __kmp_inline __itt_caller __kmp_itt_stack_caller_create(void);
128 __kmp_inline void __kmp_itt_stack_caller_destroy(__itt_caller);
129 __kmp_inline void __kmp_itt_stack_callee_enter(__itt_caller);
130 __kmp_inline void __kmp_itt_stack_callee_leave(__itt_caller);
131 
132 // -------------------------------------------------------------------------------------------------
133 // Old stuff for reporting low-level internal synchronization.
134 // -------------------------------------------------------------------------------------------------
135 
136 #if USE_ITT_NOTIFY
137 
138     /*
139      * Support for SSC marks, which are used by SDE
140      * http://software.intel.com/en-us/articles/intel-software-development-emulator
141      * to mark points in instruction traces that represent spin-loops and are
142      * therefore uninteresting when collecting traces for architecture simulation.
143      */
144     #ifndef INCLUDE_SSC_MARKS
145     # define INCLUDE_SSC_MARKS (KMP_OS_LINUX && KMP_ARCH_X86_64)
146     #endif
147 
148     /* Linux 64 only for now */
149     #if (INCLUDE_SSC_MARKS && KMP_OS_LINUX && KMP_ARCH_X86_64)
150     // Portable (at least for gcc and icc) code to insert the necessary instructions
151     // to set %ebx and execute the unlikely no-op.
152       #if defined( __INTEL_COMPILER )
153       # define INSERT_SSC_MARK(tag) __SSC_MARK(tag)
154       #else
155       # define INSERT_SSC_MARK(tag)                                          \
156       __asm__ __volatile__ ("movl %0, %%ebx; .byte 0x64, 0x67, 0x90 " ::"i"(tag):"%ebx")
157       #endif
158     #else
159     # define INSERT_SSC_MARK(tag) ((void)0)
160     #endif
161 
162     /* Markers for the start and end of regions that represent polling and
163      * are therefore uninteresting to architectural simulations 0x4376 and
164      * 0x4377 are arbitrary numbers that should be unique in the space of
165      * SSC tags, but there is no central issuing authority rather
166      * randomness is expected to work.
167      */
168     #define SSC_MARK_SPIN_START() INSERT_SSC_MARK(0x4376)
169     #define SSC_MARK_SPIN_END()   INSERT_SSC_MARK(0x4377)
170 
171     // Markers for architecture simulation.
172     // FORKING      : Before the master thread forks.
173     // JOINING      : At the start of the join.
174     // INVOKING     : Before the threads invoke microtasks.
175     // DISPATCH_INIT: At the start of dynamically scheduled loop.
176     // DISPATCH_NEXT: After claming next iteration of dynamically scheduled loop.
177     #define SSC_MARK_FORKING()          INSERT_SSC_MARK(0xd693)
178     #define SSC_MARK_JOINING()          INSERT_SSC_MARK(0xd694)
179     #define SSC_MARK_INVOKING()         INSERT_SSC_MARK(0xd695)
180     #define SSC_MARK_DISPATCH_INIT()    INSERT_SSC_MARK(0xd696)
181     #define SSC_MARK_DISPATCH_NEXT()    INSERT_SSC_MARK(0xd697)
182 
183     // The object is an address that associates a specific set of the prepare, acquire, release,
184     // and cancel operations.
185 
186     /* Sync prepare indicates a thread is going to start waiting for another thread
187        to send a release event.  This operation should be done just before the thread
188        begins checking for the existence of the release event */
189 
190     /* Sync cancel indicates a thread is cancelling a wait on another thread anc
191        continuing execution without waiting for the other thread to release it */
192 
193     /* Sync acquired indicates a thread has received a release event from another
194        thread and has stopped waiting.  This operation must occur only after the release
195        event is received. */
196 
197     /* Sync release indicates a thread is going to send a release event to another thread
198        so it will stop waiting and continue execution. This operation must just happen before
199        the release event. */
200 
201     #define KMP_FSYNC_PREPARE(   obj )  __itt_fsync_prepare(   (void *)( obj ) )
202     #define KMP_FSYNC_CANCEL(    obj )  __itt_fsync_cancel(    (void *)( obj ) )
203     #define KMP_FSYNC_ACQUIRED(  obj )  __itt_fsync_acquired(  (void *)( obj ) )
204     #define KMP_FSYNC_RELEASING( obj )  __itt_fsync_releasing( (void *)( obj ) )
205 
206     /*
207         In case of waiting in a spin loop, ITT wants KMP_FSYNC_PREPARE() to be called with a delay
208         (and not called at all if waiting time is small). So, in spin loops, do not use
209         KMP_FSYNC_PREPARE(), but use KMP_FSYNC_SPIN_INIT() (before spin loop),
210         KMP_FSYNC_SPIN_PREPARE() (whithin the spin loop), and KMP_FSYNC_SPIN_ACQUIRED().
211         See KMP_WAIT_YIELD() for example.
212     */
213 
214     #undef  KMP_FSYNC_SPIN_INIT
215     #define KMP_FSYNC_SPIN_INIT( obj, spin )    \
216         int sync_iters = 0;                     \
217         if ( __itt_fsync_prepare_ptr ) {        \
218             if ( obj == NULL ) {                \
219                 obj = spin;                     \
220             } /* if */                          \
221         } /* if */                              \
222         SSC_MARK_SPIN_START()
223 
224     #undef  KMP_FSYNC_SPIN_PREPARE
225     #define KMP_FSYNC_SPIN_PREPARE( obj ) do {                          \
226         if ( __itt_fsync_prepare_ptr && sync_iters < __kmp_itt_prepare_delay ) { \
227             ++ sync_iters;                                              \
228             if ( sync_iters >= __kmp_itt_prepare_delay ) {              \
229                 KMP_FSYNC_PREPARE( (void*) obj );                       \
230             } /* if */                                                  \
231         } /* if */                                                      \
232      } while (0)
233     #undef  KMP_FSYNC_SPIN_ACQUIRED
234     #define KMP_FSYNC_SPIN_ACQUIRED( obj ) do {         \
235         SSC_MARK_SPIN_END();                            \
236         if ( sync_iters >= __kmp_itt_prepare_delay ) {  \
237             KMP_FSYNC_ACQUIRED( (void*) obj );          \
238         } /* if */                                      \
239      } while (0)
240 
241     /* ITT will not report objects created within KMP_ITT_IGNORE(), e. g.:
242            KMP_ITT_IGNORE(
243                ptr = malloc( size );
244            );
245     */
246     #define KMP_ITT_IGNORE( statement ) do {                            \
247             __itt_state_t __itt_state_;                                 \
248             if ( __itt_state_get_ptr ) {                                \
249                 __itt_state_ = __itt_state_get();                       \
250                 __itt_obj_mode_set( __itt_obj_prop_ignore, __itt_obj_state_set ); \
251             }  /* if */                                                 \
252             { statement }                                               \
253             if ( __itt_state_get_ptr ) {                                \
254                 __itt_state_set( __itt_state_ );                        \
255             }  /* if */                                                 \
256     } while (0)
257 
258     const int KMP_MAX_FRAME_DOMAINS = 512; // Maximum number of frame domains to use (maps to
259                                            // different OpenMP regions in the user source code).
260     extern kmp_int32 __kmp_barrier_domain_count;
261     extern kmp_int32 __kmp_region_domain_count;
262     extern __itt_domain* __kmp_itt_barrier_domains[KMP_MAX_FRAME_DOMAINS];
263     extern __itt_domain* __kmp_itt_region_domains[KMP_MAX_FRAME_DOMAINS];
264     extern __itt_domain* __kmp_itt_imbalance_domains[KMP_MAX_FRAME_DOMAINS];
265     extern kmp_int32 __kmp_itt_region_team_size[KMP_MAX_FRAME_DOMAINS];
266     extern __itt_domain * metadata_domain;
267     extern __itt_string_handle * string_handle_imbl;
268     extern __itt_string_handle * string_handle_loop;
269     extern __itt_string_handle * string_handle_sngl;
270 
271 #else
272 
273 // Null definitions of the synchronization tracing functions.
274 # define KMP_FSYNC_PREPARE(   obj )        ((void)0)
275 # define KMP_FSYNC_CANCEL(    obj )        ((void)0)
276 # define KMP_FSYNC_ACQUIRED(  obj )        ((void)0)
277 # define KMP_FSYNC_RELEASING( obj )        ((void)0)
278 
279 # define KMP_FSYNC_SPIN_INIT( obj, spin )  ((void)0)
280 # define KMP_FSYNC_SPIN_PREPARE(  obj )    ((void)0)
281 # define KMP_FSYNC_SPIN_ACQUIRED( obj )    ((void)0)
282 
283 # define KMP_ITT_IGNORE(stmt ) do { stmt } while (0)
284 
285 #endif // USE_ITT_NOTIFY
286 
287 #if ! KMP_DEBUG
288     // In release mode include definitions of inline functions.
289     #include "kmp_itt.inl"
290 #endif
291 
292 #endif // KMP_ITT_H
293 
294 #else  /* USE_ITT_BUILD */
295 
296 // Null definitions of the synchronization tracing functions.
297 // If USE_ITT_BULID is not enabled, USE_ITT_NOTIFY cannot be either.
298 // By defining these we avoid unpleasant ifdef tests in many places.
299 # define KMP_FSYNC_PREPARE(   obj )        ((void)0)
300 # define KMP_FSYNC_CANCEL(    obj )        ((void)0)
301 # define KMP_FSYNC_ACQUIRED(  obj )        ((void)0)
302 # define KMP_FSYNC_RELEASING( obj )        ((void)0)
303 
304 # define KMP_FSYNC_SPIN_INIT( obj, spin )  ((void)0)
305 # define KMP_FSYNC_SPIN_PREPARE(  obj )    ((void)0)
306 # define KMP_FSYNC_SPIN_ACQUIRED( obj )    ((void)0)
307 
308 # define KMP_ITT_IGNORE(stmt ) do { stmt } while (0)
309 
310 # define USE_ITT_BUILD_ARG(x)
311 
312 #endif /* USE_ITT_BUILD */
313