Intel(R) Threading Building Blocks Doxygen Documentation version 4.2.3
_flow_graph_trace_impl.h
Go to the documentation of this file.
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#ifndef _FGT_GRAPH_TRACE_IMPL_H
18#define _FGT_GRAPH_TRACE_IMPL_H
19
20#include "../tbb_profiling.h"
21#if (_MSC_VER >= 1900)
22 #include <intrin.h>
23#endif
24
25namespace tbb {
26 namespace internal {
27
28#if TBB_USE_THREADING_TOOLS
29 #if TBB_PREVIEW_FLOW_GRAPH_TRACE
30 #if (_MSC_VER >= 1900)
31 #define CODEPTR() (_ReturnAddress())
32 #elif __TBB_GCC_VERSION >= 40800
33 #define CODEPTR() ( __builtin_return_address(0))
34 #else
35 #define CODEPTR() NULL
36 #endif
37 #else
38 #define CODEPTR() NULL
39 #endif /* TBB_PREVIEW_FLOW_GRAPH_TRACE */
40
41static inline void fgt_alias_port(void *node, void *p, bool visible) {
42 if(visible)
43 itt_relation_add( ITT_DOMAIN_FLOW, node, FLOW_NODE, __itt_relation_is_parent_of, p, FLOW_NODE );
44 else
45 itt_relation_add( ITT_DOMAIN_FLOW, p, FLOW_NODE, __itt_relation_is_child_of, node, FLOW_NODE );
46}
47
48static inline void fgt_composite ( void* codeptr, void *node, void *graph ) {
49 itt_make_task_group( ITT_DOMAIN_FLOW, node, FLOW_NODE, graph, FLOW_GRAPH, FLOW_COMPOSITE_NODE );
50 suppress_unused_warning( codeptr );
51#if TBB_PREVIEW_FLOW_GRAPH_TRACE
52 if (codeptr != NULL) {
53 register_node_addr(ITT_DOMAIN_FLOW, node, FLOW_NODE, CODE_ADDRESS, &codeptr);
54 }
55#endif
56}
57
58static inline void fgt_internal_alias_input_port( void *node, void *p, string_index name_index ) {
59 itt_make_task_group( ITT_DOMAIN_FLOW, p, FLOW_INPUT_PORT, node, FLOW_NODE, name_index );
60 itt_relation_add( ITT_DOMAIN_FLOW, node, FLOW_NODE, __itt_relation_is_parent_of, p, FLOW_INPUT_PORT );
61}
62
63static inline void fgt_internal_alias_output_port( void *node, void *p, string_index name_index ) {
64 itt_make_task_group( ITT_DOMAIN_FLOW, p, FLOW_OUTPUT_PORT, node, FLOW_NODE, name_index );
65 itt_relation_add( ITT_DOMAIN_FLOW, node, FLOW_NODE, __itt_relation_is_parent_of, p, FLOW_OUTPUT_PORT );
66}
67
68template<typename InputType>
69void alias_input_port(void *node, tbb::flow::receiver<InputType>* port, string_index name_index) {
70 // TODO: Make fgt_internal_alias_input_port a function template?
71 fgt_internal_alias_input_port( node, port, name_index);
72}
73
74template < typename PortsTuple, int N >
75struct fgt_internal_input_alias_helper {
76 static void alias_port( void *node, PortsTuple &ports ) {
77 alias_input_port( node, &(tbb::flow::get<N-1>(ports)), static_cast<tbb::internal::string_index>(FLOW_INPUT_PORT_0 + N - 1) );
79 }
80};
81
82template < typename PortsTuple >
83struct fgt_internal_input_alias_helper<PortsTuple, 0> {
84 static void alias_port( void * /* node */, PortsTuple & /* ports */ ) { }
85};
86
87template<typename OutputType>
88void alias_output_port(void *node, tbb::flow::sender<OutputType>* port, string_index name_index) {
89 // TODO: Make fgt_internal_alias_output_port a function template?
90 fgt_internal_alias_output_port( node, static_cast<void *>(port), name_index);
91}
92
93template < typename PortsTuple, int N >
94struct fgt_internal_output_alias_helper {
95 static void alias_port( void *node, PortsTuple &ports ) {
96 alias_output_port( node, &(tbb::flow::get<N-1>(ports)), static_cast<tbb::internal::string_index>(FLOW_OUTPUT_PORT_0 + N - 1) );
98 }
99};
100
101template < typename PortsTuple >
102struct fgt_internal_output_alias_helper<PortsTuple, 0> {
103 static void alias_port( void * /*node*/, PortsTuple &/*ports*/ ) {
104 }
105};
106
107static inline void fgt_internal_create_input_port( void *node, void *p, string_index name_index ) {
108 itt_make_task_group( ITT_DOMAIN_FLOW, p, FLOW_INPUT_PORT, node, FLOW_NODE, name_index );
109}
110
111static inline void fgt_internal_create_output_port( void* codeptr, void *node, void *p, string_index name_index ) {
112 itt_make_task_group(ITT_DOMAIN_FLOW, p, FLOW_OUTPUT_PORT, node, FLOW_NODE, name_index);
113 suppress_unused_warning( codeptr );
114#if TBB_PREVIEW_FLOW_GRAPH_TRACE
115 if (codeptr != NULL) {
116 register_node_addr(ITT_DOMAIN_FLOW, node, FLOW_NODE, CODE_ADDRESS, &codeptr);
117 }
118#endif
119}
120
121template<typename InputType>
122void register_input_port(void *node, tbb::flow::receiver<InputType>* port, string_index name_index) {
123 // TODO: Make fgt_internal_create_input_port a function template?
124 // In C++03 dependent name lookup from the template definition context
125 // works only for function declarations with external linkage:
126 // http://www.open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#561
127 fgt_internal_create_input_port(node, static_cast<void*>(port), name_index);
128}
129
130template < typename PortsTuple, int N >
131struct fgt_internal_input_helper {
132 static void register_port( void *node, PortsTuple &ports ) {
133 register_input_port( node, &(tbb::flow::get<N-1>(ports)), static_cast<tbb::internal::string_index>(FLOW_INPUT_PORT_0 + N - 1) );
134 fgt_internal_input_helper<PortsTuple, N-1>::register_port( node, ports );
135 }
136};
137
138template < typename PortsTuple >
139struct fgt_internal_input_helper<PortsTuple, 1> {
140 static void register_port( void *node, PortsTuple &ports ) {
141 register_input_port( node, &(tbb::flow::get<0>(ports)), FLOW_INPUT_PORT_0 );
142 }
143};
144
145template<typename OutputType>
146void register_output_port(void* codeptr, void *node, tbb::flow::sender<OutputType>* port, string_index name_index) {
147 // TODO: Make fgt_internal_create_output_port a function template?
148 fgt_internal_create_output_port( codeptr, node, static_cast<void *>(port), name_index);
149}
150
151template < typename PortsTuple, int N >
152struct fgt_internal_output_helper {
153 static void register_port( void* codeptr, void *node, PortsTuple &ports ) {
154 register_output_port( codeptr, node, &(tbb::flow::get<N-1>(ports)), static_cast<tbb::internal::string_index>(FLOW_OUTPUT_PORT_0 + N - 1) );
155 fgt_internal_output_helper<PortsTuple, N-1>::register_port( codeptr, node, ports );
156 }
157};
158
159template < typename PortsTuple >
160struct fgt_internal_output_helper<PortsTuple,1> {
161 static void register_port( void* codeptr, void *node, PortsTuple &ports ) {
162 register_output_port( codeptr, node, &(tbb::flow::get<0>(ports)), FLOW_OUTPUT_PORT_0 );
163 }
164};
165
166template< typename NodeType >
167void fgt_multioutput_node_desc( const NodeType *node, const char *desc ) {
168 void *addr = (void *)( static_cast< tbb::flow::receiver< typename NodeType::input_type > * >(const_cast< NodeType *>(node)) );
169 itt_metadata_str_add( ITT_DOMAIN_FLOW, addr, FLOW_NODE, FLOW_OBJECT_NAME, desc );
170}
171
172template< typename NodeType >
173void fgt_multiinput_multioutput_node_desc( const NodeType *node, const char *desc ) {
174 void *addr = const_cast<NodeType *>(node);
175 itt_metadata_str_add( ITT_DOMAIN_FLOW, addr, FLOW_NODE, FLOW_OBJECT_NAME, desc );
176}
177
178template< typename NodeType >
179static inline void fgt_node_desc( const NodeType *node, const char *desc ) {
180 void *addr = (void *)( static_cast< tbb::flow::sender< typename NodeType::output_type > * >(const_cast< NodeType *>(node)) );
181 itt_metadata_str_add( ITT_DOMAIN_FLOW, addr, FLOW_NODE, FLOW_OBJECT_NAME, desc );
182}
183
184static inline void fgt_graph_desc( void *g, const char *desc ) {
185 itt_metadata_str_add( ITT_DOMAIN_FLOW, g, FLOW_GRAPH, FLOW_OBJECT_NAME, desc );
186}
187
188static inline void fgt_body( void *node, void *body ) {
189 itt_relation_add( ITT_DOMAIN_FLOW, body, FLOW_BODY, __itt_relation_is_child_of, node, FLOW_NODE );
190}
191
192template< int N, typename PortsTuple >
193static inline void fgt_multioutput_node(void* codeptr, string_index t, void *g, void *input_port, PortsTuple &ports ) {
194 itt_make_task_group( ITT_DOMAIN_FLOW, input_port, FLOW_NODE, g, FLOW_GRAPH, t );
195 fgt_internal_create_input_port( input_port, input_port, FLOW_INPUT_PORT_0 );
196 fgt_internal_output_helper<PortsTuple, N>::register_port(codeptr, input_port, ports );
197}
198
199template< int N, typename PortsTuple >
200static inline void fgt_multioutput_node_with_body( void* codeptr, string_index t, void *g, void *input_port, PortsTuple &ports, void *body ) {
201 itt_make_task_group( ITT_DOMAIN_FLOW, input_port, FLOW_NODE, g, FLOW_GRAPH, t );
202 fgt_internal_create_input_port( input_port, input_port, FLOW_INPUT_PORT_0 );
203 fgt_internal_output_helper<PortsTuple, N>::register_port( codeptr, input_port, ports );
204 fgt_body( input_port, body );
205}
206
207template< int N, typename PortsTuple >
208static inline void fgt_multiinput_node( void* codeptr, string_index t, void *g, PortsTuple &ports, void *output_port) {
209 itt_make_task_group( ITT_DOMAIN_FLOW, output_port, FLOW_NODE, g, FLOW_GRAPH, t );
210 fgt_internal_create_output_port( codeptr, output_port, output_port, FLOW_OUTPUT_PORT_0 );
211 fgt_internal_input_helper<PortsTuple, N>::register_port( output_port, ports );
212}
213
214static inline void fgt_multiinput_multioutput_node( void* codeptr, string_index t, void *n, void *g ) {
215 itt_make_task_group( ITT_DOMAIN_FLOW, n, FLOW_NODE, g, FLOW_GRAPH, t );
216 suppress_unused_warning( codeptr );
217#if TBB_PREVIEW_FLOW_GRAPH_TRACE
218 if (codeptr != NULL) {
219 register_node_addr(ITT_DOMAIN_FLOW, n, FLOW_NODE, CODE_ADDRESS, &codeptr);
220 }
221#endif
222}
223
224static inline void fgt_node( void* codeptr, string_index t, void *g, void *output_port ) {
225 itt_make_task_group( ITT_DOMAIN_FLOW, output_port, FLOW_NODE, g, FLOW_GRAPH, t );
226 fgt_internal_create_output_port( codeptr, output_port, output_port, FLOW_OUTPUT_PORT_0 );
227}
228
229static void fgt_node_with_body( void* codeptr, string_index t, void *g, void *output_port, void *body ) {
230 itt_make_task_group( ITT_DOMAIN_FLOW, output_port, FLOW_NODE, g, FLOW_GRAPH, t );
231 fgt_internal_create_output_port(codeptr, output_port, output_port, FLOW_OUTPUT_PORT_0 );
232 fgt_body( output_port, body );
233}
234
235static inline void fgt_node( void* codeptr, string_index t, void *g, void *input_port, void *output_port ) {
236 fgt_node( codeptr, t, g, output_port );
237 fgt_internal_create_input_port( output_port, input_port, FLOW_INPUT_PORT_0 );
238}
239
240static inline void fgt_node_with_body( void* codeptr, string_index t, void *g, void *input_port, void *output_port, void *body ) {
241 fgt_node_with_body( codeptr, t, g, output_port, body );
242 fgt_internal_create_input_port( output_port, input_port, FLOW_INPUT_PORT_0 );
243}
244
245
246static inline void fgt_node( void* codeptr, string_index t, void *g, void *input_port, void *decrement_port, void *output_port ) {
247 fgt_node( codeptr, t, g, input_port, output_port );
248 fgt_internal_create_input_port( output_port, decrement_port, FLOW_INPUT_PORT_1 );
249}
250
251static inline void fgt_make_edge( void *output_port, void *input_port ) {
253}
254
255static inline void fgt_remove_edge( void *output_port, void *input_port ) {
257}
258
259static inline void fgt_graph( void *g ) {
260 itt_make_task_group( ITT_DOMAIN_FLOW, g, FLOW_GRAPH, NULL, FLOW_NULL, FLOW_GRAPH );
261}
262
263static inline void fgt_begin_body( void *body ) {
264 itt_task_begin( ITT_DOMAIN_FLOW, body, FLOW_BODY, NULL, FLOW_NULL, FLOW_BODY );
265}
266
267static inline void fgt_end_body( void * ) {
269}
270
271static inline void fgt_async_try_put_begin( void *node, void *port ) {
272 itt_task_begin( ITT_DOMAIN_FLOW, port, FLOW_OUTPUT_PORT, node, FLOW_NODE, FLOW_OUTPUT_PORT );
273}
274
275static inline void fgt_async_try_put_end( void *, void * ) {
277}
278
279static inline void fgt_async_reserve( void *node, void *graph ) {
280 itt_region_begin( ITT_DOMAIN_FLOW, node, FLOW_NODE, graph, FLOW_GRAPH, FLOW_NULL );
281}
282
283static inline void fgt_async_commit( void *node, void * /*graph*/) {
284 itt_region_end( ITT_DOMAIN_FLOW, node, FLOW_NODE );
285}
286
287static inline void fgt_reserve_wait( void *graph ) {
288 itt_region_begin( ITT_DOMAIN_FLOW, graph, FLOW_GRAPH, NULL, FLOW_NULL, FLOW_NULL );
289}
290
291static inline void fgt_release_wait( void *graph ) {
292 itt_region_end( ITT_DOMAIN_FLOW, graph, FLOW_GRAPH );
293}
294
295#else // TBB_USE_THREADING_TOOLS
296
297#define CODEPTR() NULL
298
299static inline void fgt_alias_port(void * /*node*/, void * /*p*/, bool /*visible*/ ) { }
300
301static inline void fgt_composite ( void* /*codeptr*/, void * /*node*/, void * /*graph*/ ) { }
302
303static inline void fgt_graph( void * /*g*/ ) { }
304
305template< typename NodeType >
306static inline void fgt_multioutput_node_desc( const NodeType * /*node*/, const char * /*desc*/ ) { }
307
308template< typename NodeType >
309static inline void fgt_node_desc( const NodeType * /*node*/, const char * /*desc*/ ) { }
310
311static inline void fgt_graph_desc( void * /*g*/, const char * /*desc*/ ) { }
312
313static inline void fgt_body( void * /*node*/, void * /*body*/ ) { }
314
315template< int N, typename PortsTuple >
316static inline void fgt_multioutput_node( void* /*codeptr*/, string_index /*t*/, void * /*g*/, void * /*input_port*/, PortsTuple & /*ports*/ ) { }
317
318template< int N, typename PortsTuple >
319static inline void fgt_multioutput_node_with_body( void* /*codeptr*/, string_index /*t*/, void * /*g*/, void * /*input_port*/, PortsTuple & /*ports*/, void * /*body*/ ) { }
320
321template< int N, typename PortsTuple >
322static inline void fgt_multiinput_node( void* /*codeptr*/, string_index /*t*/, void * /*g*/, PortsTuple & /*ports*/, void * /*output_port*/ ) { }
323
324static inline void fgt_multiinput_multioutput_node( void* /*codeptr*/, string_index /*t*/, void * /*node*/, void * /*graph*/ ) { }
325
326static inline void fgt_node( void* /*codeptr*/, string_index /*t*/, void * /*g*/, void * /*output_port*/ ) { }
327static inline void fgt_node( void* /*codeptr*/, string_index /*t*/, void * /*g*/, void * /*input_port*/, void * /*output_port*/ ) { }
328static inline void fgt_node( void* /*codeptr*/, string_index /*t*/, void * /*g*/, void * /*input_port*/, void * /*decrement_port*/, void * /*output_port*/ ) { }
329
330static inline void fgt_node_with_body( void* /*codeptr*/, string_index /*t*/, void * /*g*/, void * /*output_port*/, void * /*body*/ ) { }
331static inline void fgt_node_with_body( void* /*codeptr*/, string_index /*t*/, void * /*g*/, void * /*input_port*/, void * /*output_port*/, void * /*body*/ ) { }
332
333static inline void fgt_make_edge( void * /*output_port*/, void * /*input_port*/ ) { }
334static inline void fgt_remove_edge( void * /*output_port*/, void * /*input_port*/ ) { }
335
336static inline void fgt_begin_body( void * /*body*/ ) { }
337static inline void fgt_end_body( void * /*body*/) { }
338
339static inline void fgt_async_try_put_begin( void * /*node*/, void * /*port*/ ) { }
340static inline void fgt_async_try_put_end( void * /*node*/ , void * /*port*/ ) { }
341static inline void fgt_async_reserve( void * /*node*/, void * /*graph*/ ) { }
342static inline void fgt_async_commit( void * /*node*/, void * /*graph*/ ) { }
343static inline void fgt_reserve_wait( void * /*graph*/ ) { }
344static inline void fgt_release_wait( void * /*graph*/ ) { }
345
346template< typename NodeType >
347void fgt_multiinput_multioutput_node_desc( const NodeType * /*node*/, const char * /*desc*/ ) { }
348
349template < typename PortsTuple, int N >
351 static void alias_port( void * /*node*/, PortsTuple & /*ports*/ ) { }
352};
353
354template < typename PortsTuple, int N >
356 static void alias_port( void * /*node*/, PortsTuple & /*ports*/ ) { }
357};
358
359#endif // TBB_USE_THREADING_TOOLS
360
361 } // namespace internal
362} // namespace tbb
363
364#endif
void * addr
void const char const char int ITT_FORMAT __itt_group_sync p
The graph class.
static void fgt_async_try_put_end(void *, void *)
void itt_task_end(itt_domain_enum)
void itt_task_begin(itt_domain_enum, void *, unsigned long long, void *, unsigned long long, string_index)
void register_node_addr(itt_domain_enum, void *, unsigned long long, string_index, void *)
static void fgt_async_reserve(void *, void *)
void itt_region_end(itt_domain_enum, void *, unsigned long long)
static void fgt_multioutput_node_desc(const NodeType *, const char *)
static void fgt_async_try_put_begin(void *, void *)
static void fgt_begin_body(void *)
@ __itt_relation_is_predecessor_to
Definition: tbb_profiling.h:43
@ __itt_relation_is_parent_of
Definition: tbb_profiling.h:39
@ __itt_relation_is_sibling_of
Definition: tbb_profiling.h:38
@ __itt_relation_is_child_of
Definition: tbb_profiling.h:41
static void fgt_body(void *, void *)
static void fgt_node(void *, string_index, void *, void *)
static void fgt_reserve_wait(void *)
void suppress_unused_warning(const T1 &)
Utility template function to prevent "unused" warnings by various compilers.
Definition: tbb_stddef.h:398
static void fgt_graph(void *)
void itt_metadata_str_add(itt_domain_enum, void *, unsigned long long, string_index, const char *)
static void fgt_node_with_body(void *, string_index, void *, void *, void *)
static void fgt_multiinput_node(void *, string_index, void *, PortsTuple &, void *)
static void fgt_release_wait(void *)
static void fgt_async_commit(void *, void *)
static void fgt_composite(void *, void *, void *)
static void fgt_multioutput_node_with_body(void *, string_index, void *, void *, PortsTuple &, void *)
static void fgt_alias_port(void *, void *, bool)
void itt_relation_add(itt_domain_enum, void *, unsigned long long, itt_relation, void *, unsigned long long)
void itt_make_task_group(itt_domain_enum, void *, unsigned long long, void *, unsigned long long, string_index)
void fgt_multiinput_multioutput_node_desc(const NodeType *, const char *)
static void fgt_multiinput_multioutput_node(void *, string_index, void *, void *)
static void fgt_remove_edge(void *, void *)
static void fgt_end_body(void *)
static void fgt_node_desc(const NodeType *, const char *)
static void fgt_multioutput_node(void *, string_index, void *, void *, PortsTuple &)
static void fgt_make_edge(void *, void *)
void itt_region_begin(itt_domain_enum, void *, unsigned long long, void *, unsigned long long, string_index)
static void fgt_graph_desc(void *, const char *)
tbb::flow::tuple_element< N, typenameJNT::input_ports_type >::type & input_port(JNT &jn)
templated function to refer to input ports of the join node
tbb::flow::tuple_element< N, typenameMOP::output_ports_type >::type & output_port(MOP &op)
Forward declaration section.
Definition: flow_graph.h:424
Pure virtual template class that defines a receiver of messages of type T.
Definition: flow_graph.h:461

Copyright © 2005-2020 Intel Corporation. All Rights Reserved.

Intel, Pentium, Intel Xeon, Itanium, Intel XScale and VTune are registered trademarks or trademarks of Intel Corporation or its subsidiaries in the United States and other countries.

* Other names and brands may be claimed as the property of others.