Intel® OpenMP* Runtime Library
 All Classes Functions Variables Typedefs Enumerations Enumerator Groups Pages
kmp_itt.h
1 #if USE_ITT_BUILD
2 /*
3  * kmp_itt.h -- ITT Notify interface.
4  * $Revision: 42616 $
5  * $Date: 2013-08-26 11:47:32 -0500 (Mon, 26 Aug 2013) $
6  */
7 
8 /* <copyright>
9  Copyright (c) 1997-2013 Intel Corporation. All Rights Reserved.
10 
11  Redistribution and use in source and binary forms, with or without
12  modification, are permitted provided that the following conditions
13  are met:
14 
15  * Redistributions of source code must retain the above copyright
16  notice, this list of conditions and the following disclaimer.
17  * Redistributions in binary form must reproduce the above copyright
18  notice, this list of conditions and the following disclaimer in the
19  documentation and/or other materials provided with the distribution.
20  * Neither the name of Intel Corporation nor the names of its
21  contributors may be used to endorse or promote products derived
22  from this software without specific prior written permission.
23 
24  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
27  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
28  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
30  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
34  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 
36 </copyright> */
37 
38 #ifndef KMP_ITT_H
39 #define KMP_ITT_H
40 
41 #include "kmp_lock.h"
42 
43 #define INTEL_ITTNOTIFY_API_PRIVATE
44 #include "ittnotify.h"
45 #include "legacy/ittnotify.h"
46 
47 #if KMP_DEBUG
48  #define __kmp_inline // Turn off inlining in debug mode.
49 #else
50  #define __kmp_inline static inline
51 #endif
52 
53 #if USE_ITT_NOTIFY
54  extern kmp_int32 __kmp_itt_prepare_delay;
55 # ifdef __cplusplus
56  extern "C" void __kmp_itt_fini_ittlib(void);
57 # else
58  extern void __kmp_itt_fini_ittlib(void);
59 # endif
60 #endif
61 
62 // Simplify the handling of an argument that is only required when USE_ITT_BUILD is enabled.
63 #define USE_ITT_BUILD_ARG(x) ,x
64 
65 void __kmp_itt_initialize();
66 void __kmp_itt_destroy();
67 
68 // -------------------------------------------------------------------------------------------------
69 // New stuff for reporting high-level constructs.
70 // -------------------------------------------------------------------------------------------------
71 
72 // Note the naming convention:
73 // __kmp_itt_xxxing() function should be called before action, while
74 // __kmp_itt_xxxed() function should be called after action.
75 
76 // --- Parallel region reporting ---
77 __kmp_inline void __kmp_itt_region_forking( int gtid, int serialized = 0 ); // Master only, before forking threads.
78 __kmp_inline void __kmp_itt_region_joined( int gtid, int serialized = 0 ); // Master only, after joining threads.
79  // (*) Note: A thread may execute tasks after this point, though.
80 
81 // --- Barrier reporting ---
82 __kmp_inline void * __kmp_itt_barrier_object( int gtid, int bt, int set_name = 0, int delta = 0 );
83 __kmp_inline void __kmp_itt_barrier_starting( int gtid, void * object );
84 __kmp_inline void __kmp_itt_barrier_middle( int gtid, void * object );
85 __kmp_inline void __kmp_itt_barrier_finished( int gtid, void * object );
86 
87 // --- Taskwait reporting ---
88 __kmp_inline void * __kmp_itt_taskwait_object( int gtid );
89 __kmp_inline void __kmp_itt_taskwait_starting( int gtid, void * object );
90 __kmp_inline void __kmp_itt_taskwait_finished( int gtid, void * object );
91 
92 // --- Task reporting ---
93 __kmp_inline void __kmp_itt_task_starting( void * object );
94 __kmp_inline void __kmp_itt_task_finished( void * object );
95 
96 // --- Lock reporting ---
97 __kmp_inline void __kmp_itt_lock_creating( kmp_user_lock_p lock );
98 __kmp_inline void __kmp_itt_lock_acquiring( kmp_user_lock_p lock );
99 __kmp_inline void __kmp_itt_lock_acquired( kmp_user_lock_p lock );
100 __kmp_inline void __kmp_itt_lock_releasing( kmp_user_lock_p lock );
101 __kmp_inline void __kmp_itt_lock_cancelled( kmp_user_lock_p lock );
102 __kmp_inline void __kmp_itt_lock_destroyed( kmp_user_lock_p lock );
103 
104 // --- Critical reporting ---
105 __kmp_inline void __kmp_itt_critical_creating( kmp_user_lock_p lock );
106 __kmp_inline void __kmp_itt_critical_acquiring( kmp_user_lock_p lock );
107 __kmp_inline void __kmp_itt_critical_acquired( kmp_user_lock_p lock );
108 __kmp_inline void __kmp_itt_critical_releasing( kmp_user_lock_p lock );
109 __kmp_inline void __kmp_itt_critical_destroyed( kmp_user_lock_p lock );
110 
111 // --- Single reporting ---
112 __kmp_inline void __kmp_itt_single_start( int gtid );
113 __kmp_inline void __kmp_itt_single_end( int gtid );
114 
115 // --- Ordered reporting ---
116 __kmp_inline void __kmp_itt_ordered_init( int gtid );
117 __kmp_inline void __kmp_itt_ordered_prep( int gtid );
118 __kmp_inline void __kmp_itt_ordered_start( int gtid );
119 __kmp_inline void __kmp_itt_ordered_end( int gtid );
120 
121 // --- Threads reporting ---
122 __kmp_inline void __kmp_itt_thread_ignore();
123 __kmp_inline void __kmp_itt_thread_name( int gtid );
124 
125 // --- System objects ---
126 __kmp_inline void __kmp_itt_system_object_created( void * object, char const * name );
127 
128 // --- Stack stitching ---
129 __kmp_inline __itt_caller __kmp_itt_stack_caller_create(void);
130 __kmp_inline void __kmp_itt_stack_caller_destroy(__itt_caller);
131 __kmp_inline void __kmp_itt_stack_callee_enter(__itt_caller);
132 __kmp_inline void __kmp_itt_stack_callee_leave(__itt_caller);
133 
134 // -------------------------------------------------------------------------------------------------
135 // Old stuff for reporting low-level internal synchronization.
136 // -------------------------------------------------------------------------------------------------
137 
138 #if USE_ITT_NOTIFY
139 
140  /*
141  * Support for SSC marks, which are used by SDE
142  * http://software.intel.com/en-us/articles/intel-software-development-emulator
143  * to mark points in instruction traces that represent spin-loops and are
144  * therefore uninteresting when collecting traces for architecture simulation.
145  */
146  #ifndef INCLUDE_SSC_MARKS
147  # define INCLUDE_SSC_MARKS (KMP_OS_LINUX && KMP_ARCH_X86_64)
148  #endif
149 
150  /* Linux 64 only for now */
151  #if (INCLUDE_SSC_MARKS && KMP_OS_LINUX && KMP_ARCH_X86_64)
152  // Portable (at least for gcc and icc) code to insert the necessary instructions
153  // to set %ebx and execute the unlikely no-op.
154  # define INSERT_SSC_MARK(tag) \
155  __asm__ __volatile__ ("movl %0, %%ebx; .byte 0x64, 0x67, 0x90 " ::"i"(tag):"%ebx")
156  #else
157  # define INSERT_SSC_MARK(tag) ((void)0)
158  #endif
159 
160  /* Markers for the start and end of regions that represent polling and
161  * are therefore uninteresting to architectural simulations 0x4376 and
162  * 0x4377 are arbitrary numbers that should be unique in the space of
163  * SSC tags, but there is no central issuing authority rather
164  * randomness is expected to work.
165  */
166  #define SSC_MARK_SPIN_START() INSERT_SSC_MARK(0x4376)
167  #define SSC_MARK_SPIN_END() INSERT_SSC_MARK(0x4377)
168 
169  // The object is an address that associates a specific set of the prepare, acquire, release,
170  // and cancel operations.
171 
172  /* Sync prepare indicates a thread is going to start waiting for another thread
173  to send a release event. This operation should be done just before the thread
174  begins checking for the existence of the release event */
175 
176  /* Sync cancel indicates a thread is cancelling a wait on another thread anc
177  continuing execution without waiting for the other thread to release it */
178 
179  /* Sync acquired indicates a thread has received a release event from another
180  thread and has stopped waiting. This operation must occur only after the release
181  event is received. */
182 
183  /* Sync release indicates a thread is going to send a release event to another thread
184  so it will stop waiting and continue execution. This operation must just happen before
185  the release event. */
186 
187  #define KMP_FSYNC_PREPARE( obj ) __itt_fsync_prepare( (void *)( obj ) )
188  #define KMP_FSYNC_CANCEL( obj ) __itt_fsync_cancel( (void *)( obj ) )
189  #define KMP_FSYNC_ACQUIRED( obj ) __itt_fsync_acquired( (void *)( obj ) )
190  #define KMP_FSYNC_RELEASING( obj ) __itt_fsync_releasing( (void *)( obj ) )
191 
192  /*
193  In case of waiting in a spin loop, ITT wants KMP_FSYNC_PREPARE() to be called with a delay
194  (and not called at all if waiting time is small). So, in spin loops, do not use
195  KMP_FSYNC_PREPARE(), but use KMP_FSYNC_SPIN_INIT() (before spin loop),
196  KMP_FSYNC_SPIN_PREPARE() (whithin the spin loop), and KMP_FSYNC_SPIN_ACQUIRED().
197  See KMP_WAIT_YIELD() for example.
198  */
199 
200  #undef KMP_FSYNC_SPIN_INIT
201  #define KMP_FSYNC_SPIN_INIT( obj, spin ) \
202  int sync_iters = 0; \
203  if ( __itt_fsync_prepare_ptr ) { \
204  if ( obj == NULL ) { \
205  obj = spin; \
206  } /* if */ \
207  } /* if */ \
208  SSC_MARK_SPIN_START()
209 
210  #undef KMP_FSYNC_SPIN_PREPARE
211  #define KMP_FSYNC_SPIN_PREPARE( obj ) do { \
212  if ( __itt_fsync_prepare_ptr && sync_iters < __kmp_itt_prepare_delay ) { \
213  ++ sync_iters; \
214  if ( sync_iters >= __kmp_itt_prepare_delay ) { \
215  KMP_FSYNC_PREPARE( (void*) obj ); \
216  } /* if */ \
217  } /* if */ \
218  } while (0)
219  #undef KMP_FSYNC_SPIN_ACQUIRED
220  #define KMP_FSYNC_SPIN_ACQUIRED( obj ) do { \
221  SSC_MARK_SPIN_END(); \
222  if ( sync_iters >= __kmp_itt_prepare_delay ) { \
223  KMP_FSYNC_ACQUIRED( (void*) obj ); \
224  } /* if */ \
225  } while (0)
226 
227  /* ITT will not report objects created within KMP_ITT_IGNORE(), e. g.:
228  KMP_ITT_IGNORE(
229  ptr = malloc( size );
230  );
231  */
232  #define KMP_ITT_IGNORE( statement ) do { \
233  __itt_state_t __itt_state_; \
234  if ( __itt_state_get_ptr ) { \
235  __itt_state_ = __itt_state_get(); \
236  __itt_obj_mode_set( __itt_obj_prop_ignore, __itt_obj_state_set ); \
237  } /* if */ \
238  { statement } \
239  if ( __itt_state_get_ptr ) { \
240  __itt_state_set( __itt_state_ ); \
241  } /* if */ \
242  } while (0)
243 
244  const int KMP_MAX_FRAME_DOMAINS = 512; // Maximum number of frame domains to use (maps to
245  // different OpenMP regions in the user source code).
246  extern kmp_int32 __kmp_frame_domain_count;
247  extern __itt_domain* __kmp_itt_domains[KMP_MAX_FRAME_DOMAINS];
248 #else
249 
250 // Null definitions of the synchronization tracing functions.
251 # define KMP_FSYNC_PREPARE( obj ) ((void)0)
252 # define KMP_FSYNC_CANCEL( obj ) ((void)0)
253 # define KMP_FSYNC_ACQUIRED( obj ) ((void)0)
254 # define KMP_FSYNC_RELEASING( obj ) ((void)0)
255 
256 # define KMP_FSYNC_SPIN_INIT( obj, spin ) ((void)0)
257 # define KMP_FSYNC_SPIN_PREPARE( obj ) ((void)0)
258 # define KMP_FSYNC_SPIN_ACQUIRED( obj ) ((void)0)
259 
260 # define KMP_ITT_IGNORE(stmt ) do { stmt } while (0)
261 
262 #endif // USE_ITT_NOTIFY
263 
264 #if ! KMP_DEBUG
265  // In release mode include definitions of inline functions.
266  #include "kmp_itt.inl"
267 #endif
268 
269 #endif // KMP_ITT_H
270 
271 #else /* USE_ITT_BUILD */
272 
273 // Null definitions of the synchronization tracing functions.
274 // If USE_ITT_BULID is not enabled, USE_ITT_NOTIFY cannot be either.
275 // By defining these we avoid unpleasant ifdef tests in many places.
276 # define KMP_FSYNC_PREPARE( obj ) ((void)0)
277 # define KMP_FSYNC_CANCEL( obj ) ((void)0)
278 # define KMP_FSYNC_ACQUIRED( obj ) ((void)0)
279 # define KMP_FSYNC_RELEASING( obj ) ((void)0)
280 
281 # define KMP_FSYNC_SPIN_INIT( obj, spin ) ((void)0)
282 # define KMP_FSYNC_SPIN_PREPARE( obj ) ((void)0)
283 # define KMP_FSYNC_SPIN_ACQUIRED( obj ) ((void)0)
284 
285 # define KMP_ITT_IGNORE(stmt ) do { stmt } while (0)
286 
287 # define USE_ITT_BUILD_ARG(x)
288 
289 #endif /* USE_ITT_BUILD */