Intel(R) Threading Building Blocks Doxygen Documentation version 4.2.3
Loading...
Searching...
No Matches
_flow_graph_body_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 __TBB__flow_graph_body_impl_H
18#define __TBB__flow_graph_body_impl_H
19
21
22#ifndef __TBB_flow_graph_H
23#error Do not #include this internal file directly; use public TBB headers instead.
24#endif
25
26// included in namespace tbb::flow::interfaceX (in flow_graph.h)
27
28namespace internal {
29
30typedef tbb::internal::uint64_t tag_value;
31
33
34#if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT
35
36template<typename ... Policies> struct Policy {};
37
38template<typename ... Policies> struct has_policy;
39
40template<typename ExpectedPolicy, typename FirstPolicy, typename ...Policies>
41struct has_policy<ExpectedPolicy, FirstPolicy, Policies...> :
42 tbb::internal::bool_constant<has_policy<ExpectedPolicy, FirstPolicy>::value ||
43 has_policy<ExpectedPolicy, Policies...>::value> {};
44
45template<typename ExpectedPolicy, typename SinglePolicy>
46struct has_policy<ExpectedPolicy, SinglePolicy> :
47 tbb::internal::bool_constant<tbb::internal::is_same_type<ExpectedPolicy, SinglePolicy>::value> {};
48
49template<typename ExpectedPolicy, typename ...Policies>
50struct has_policy<ExpectedPolicy, Policy<Policies...> > : has_policy<ExpectedPolicy, Policies...> {};
51
52#else
53
54template<typename P1, typename P2 = void> struct Policy {};
55
56template<typename ExpectedPolicy, typename SinglePolicy>
57struct has_policy : tbb::internal::bool_constant<tbb::internal::is_same_type<ExpectedPolicy, SinglePolicy>::value> {};
58
59template<typename ExpectedPolicy, typename P>
60struct has_policy<ExpectedPolicy, Policy<P> > : has_policy<ExpectedPolicy, P> {};
61
62template<typename ExpectedPolicy, typename P1, typename P2>
63struct has_policy<ExpectedPolicy, Policy<P1, P2> > :
64 tbb::internal::bool_constant<has_policy<ExpectedPolicy, P1>::value || has_policy<ExpectedPolicy, P2>::value> {};
65
66#endif
67
68namespace graph_policy_namespace {
69
70 struct rejecting { };
71 struct reserving { };
72 struct queueing { };
73 struct lightweight { };
74
75 // K == type of field used for key-matching. Each tag-matching port will be provided
76 // functor that, given an object accepted by the port, will return the
78 template<typename K, typename KHash=tbb_hash_compare<typename strip<K>::type > >
79 struct key_matching {
80 typedef K key_type;
81 typedef typename strip<K>::type base_key_type;
82 typedef KHash hash_compare_type;
83 };
84
85 // old tag_matching join's new specifier
87
88 // Aliases for Policy combinations
89 typedef interface11::internal::Policy<queueing, lightweight> queueing_lightweight;
90 typedef interface11::internal::Policy<rejecting, lightweight> rejecting_lightweight;
91
92} // namespace graph_policy_namespace
93
94// -------------- function_body containers ----------------------
96template< typename Output >
98public:
99 virtual ~input_body() {}
100
101#if TBB_DEPRECATED_INPUT_NODE_BODY
102 virtual bool operator()(Output &output) = 0;
103#else
104 virtual Output operator()(flow_control& fc) = 0;
105#endif
106 virtual input_body* clone() = 0;
107};
108
109template <typename Body>
112 "TBB Warning: input_node body requirements have been changed."
113 "To temporarily enforce deprecated API specify TBB_DEPRECATED_INPUT_NODE_BODY.");
114}
115
116template <typename Body>
118 check_input_node_body_input_type_impl(&Body::operator());
119}
120
121template <typename ReturnType, typename T>
122void check_input_node_body_input_type(ReturnType(*)(T)) {
124 "TBB Warning: input_node body requirements have been changed."
125 "To temporarily enforce deprecated API specify TBB_DEPRECATED_INPUT_NODE_BODY.");
126}
127
129template< typename Output, typename Body>
130class input_body_leaf : public input_body<Output> {
131public:
132 input_body_leaf( const Body &_body ) : body(_body) { }
133
134#if TBB_DEPRECATED_INPUT_NODE_BODY
135 bool operator()(Output &output) __TBB_override { return body( output ); }
136#else
137 Output operator()(flow_control& fc) __TBB_override {
139 return body(fc);
140 }
141#endif
144 }
145 Body get_body() { return body; }
146private:
147 Body body;
148};
149
150template< typename Output >
152public:
153 virtual ~source_body() {}
154 virtual bool operator()(Output &output) = 0;
155 virtual source_body* clone() = 0;
156};
157
159template< typename Output, typename Body>
160class source_body_leaf : public source_body<Output> {
161public:
162 source_body_leaf( const Body &_body ) : body(_body) { }
163
164 bool operator()(Output &output) __TBB_override { return body( output ); }
165
168 }
169
170 Body get_body() { return body; }
171private:
172 Body body;
173};
174
176template< typename Input, typename Output >
178public:
179 virtual ~function_body() {}
180 virtual Output operator()(const Input &input) = 0;
181 virtual function_body* clone() = 0;
182};
183
185template <typename Input, typename Output, typename B>
186class function_body_leaf : public function_body< Input, Output > {
187public:
188 function_body_leaf( const B &_body ) : body(_body) { }
189 Output operator()(const Input &i) __TBB_override { return body(i); }
190 B get_body() { return body; }
193 }
194private:
196};
197
199template <typename B>
200class function_body_leaf< continue_msg, continue_msg, B> : public function_body< continue_msg, continue_msg > {
201public:
202 function_body_leaf( const B &_body ) : body(_body) { }
203 continue_msg operator()( const continue_msg &i ) __TBB_override {
204 body(i);
205 return i;
206 }
207 B get_body() { return body; }
210 }
211private:
213};
214
216template <typename Input, typename B>
217class function_body_leaf< Input, continue_msg, B> : public function_body< Input, continue_msg > {
218public:
219 function_body_leaf( const B &_body ) : body(_body) { }
220 continue_msg operator()(const Input &i) __TBB_override {
221 body(i);
222 return continue_msg();
223 }
224 B get_body() { return body; }
227 }
228private:
230};
231
233template <typename Output, typename B>
234class function_body_leaf< continue_msg, Output, B > : public function_body< continue_msg, Output > {
235public:
236 function_body_leaf( const B &_body ) : body(_body) { }
237 Output operator()(const continue_msg &i) __TBB_override {
238 return body(i);
239 }
240 B get_body() { return body; }
243 }
244private:
246};
247
249template<typename Input, typename OutputSet>
251public:
253 virtual void operator()(const Input &/* input*/, OutputSet &/*oset*/) = 0;
254 virtual multifunction_body* clone() = 0;
255 virtual void* get_body_ptr() = 0;
256};
257
259template<typename Input, typename OutputSet, typename B >
260class multifunction_body_leaf : public multifunction_body<Input, OutputSet> {
261public:
262 multifunction_body_leaf(const B &_body) : body(_body) { }
263 void operator()(const Input &input, OutputSet &oset) __TBB_override {
264 body(input, oset); // body may explicitly put() to one or more of oset.
265 }
266 void* get_body_ptr() __TBB_override { return &body; }
269 }
270
271private:
273};
274
275// ------ function bodies for hash_buffers and key-matching joins.
276
277template<typename Input, typename Output>
279 public:
281 virtual Output operator()(const Input &input) = 0; // returns an Output
283};
284
285// specialization for ref output
286template<typename Input, typename Output>
288 public:
290 virtual const Output & operator()(const Input &input) = 0; // returns a const Output&
292};
293
294template <typename Input, typename Output, typename B>
296public:
297 type_to_key_function_body_leaf( const B &_body ) : body(_body) { }
298 Output operator()(const Input &i) __TBB_override { return body(i); }
299 B get_body() { return body; }
302 }
303private:
305};
306
307template <typename Input, typename Output, typename B>
309public:
310 type_to_key_function_body_leaf( const B &_body ) : body(_body) { }
311 const Output& operator()(const Input &i) __TBB_override {
312 return body(i);
313 }
314 B get_body() { return body; }
317 }
318private:
320};
321
322// --------------------------- end of function_body containers ------------------------
323
324// --------------------------- node task bodies ---------------------------------------
325
327template< typename NodeType >
328class forward_task_bypass : public graph_task {
329
330 NodeType &my_node;
331
332public:
333
336 , node_priority_t node_priority = no_priority
337 ) : graph_task(node_priority),
338#else
339 ) :
340#endif
341 my_node(n) {}
342
344 task * new_task = my_node.forward_task();
345 if (new_task == SUCCESSFULLY_ENQUEUED) new_task = NULL;
346 return new_task;
347 }
348};
349
351// return the task* unless it is SUCCESSFULLY_ENQUEUED, in which case return NULL
352template< typename NodeType, typename Input >
353class apply_body_task_bypass : public graph_task {
354
355 NodeType &my_node;
356 Input my_input;
357
358public:
359
360 apply_body_task_bypass( NodeType &n, const Input &i
362 , node_priority_t node_priority = no_priority
363 ) : graph_task(node_priority),
364#else
365 ) :
366#endif
367 my_node(n), my_input(i) {}
368
370 task * next_task = my_node.apply_body_bypass( my_input );
371 if(next_task == SUCCESSFULLY_ENQUEUED) next_task = NULL;
372 return next_task;
373 }
374};
375
377template< typename NodeType >
378class source_task_bypass : public graph_task {
379
380 NodeType &my_node;
381
382public:
383
384 source_task_bypass( NodeType &n ) : my_node(n) {}
385
387 task *new_task = my_node.apply_body_bypass( );
388 if(new_task == SUCCESSFULLY_ENQUEUED) return NULL;
389 return new_task;
390 }
391};
392
393// ------------------------ end of node task bodies -----------------------------------
394
396template< typename Input, typename Output >
398 Output operator()( const Input & ) const { return Output(); }
399};
400
401template<typename T, typename DecrementType, typename DummyType = void>
403
404template<typename T, typename DecrementType>
405class decrementer<T, DecrementType,
406 typename tbb::internal::enable_if<
407 tbb::internal::is_integral<DecrementType>::value, void>::type
408 > : public receiver<DecrementType>, tbb::internal::no_copy {
410protected:
411
412 task* try_put_task( const DecrementType& value ) __TBB_override {
413 task* result = my_node->decrement_counter( value );
414 if( !result )
415 result = SUCCESSFULLY_ENQUEUED;
416 return result;
417 }
418
420 return my_node->my_graph;
421 }
422
423 template<typename U, typename V> friend class tbb::flow::interface11::limiter_node;
424 void reset_receiver( reset_flags f ) __TBB_override {
425#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
426 if (f & rf_clear_edges)
427 my_built_predecessors.clear();
428#else
430#endif
431 }
432
433public:
434 // Since decrementer does not make use of possibly unconstructed owner inside its
435 // constructor, my_node can be directly initialized with 'this' pointer passed from the
436 // owner, hence making method 'set_owner' needless.
437 decrementer() : my_node(NULL) {}
438 void set_owner( T *node ) { my_node = node; }
439
440#if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
441 spin_mutex my_mutex;
443 typedef typename receiver<DecrementType>::predecessor_type predecessor_type;
444
445 typedef internal::edge_container<predecessor_type> built_predecessors_type;
446 typedef typename built_predecessors_type::edge_list_type predecessor_list_type;
447 built_predecessors_type &built_predecessors() __TBB_override { return my_built_predecessors; }
448
449 void internal_add_built_predecessor( predecessor_type &s) __TBB_override {
450 spin_mutex::scoped_lock l(my_mutex);
451 my_built_predecessors.add_edge( s );
452 }
453
454 void internal_delete_built_predecessor( predecessor_type &s) __TBB_override {
455 spin_mutex::scoped_lock l(my_mutex);
456 my_built_predecessors.delete_edge(s);
457 }
458
459 void copy_predecessors( predecessor_list_type &v) __TBB_override {
460 spin_mutex::scoped_lock l(my_mutex);
461 my_built_predecessors.copy_edges(v);
462 }
463
464 size_t predecessor_count() __TBB_override {
465 spin_mutex::scoped_lock l(my_mutex);
466 return my_built_predecessors.edge_count();
467 }
468protected:
469 built_predecessors_type my_built_predecessors;
470#endif /* TBB_DEPRECATED_FLOW_NODE_EXTRACTION */
471};
472
473template<typename T>
474class decrementer<T, continue_msg, void> : public continue_receiver, tbb::internal::no_copy {
475
477
479 return my_node->decrement_counter( 1 );
480 }
481
482protected:
483
485 return my_node->my_graph;
486 }
487
488public:
489
490 typedef continue_msg input_type;
491 typedef continue_msg output_type;
492 decrementer( int number_of_predecessors = 0 )
493 : continue_receiver(
494 __TBB_FLOW_GRAPH_PRIORITY_ARG1(number_of_predecessors, tbb::flow::internal::no_priority)
495 )
496 // Since decrementer does not make use of possibly unconstructed owner inside its
497 // constructor, my_node can be directly initialized with 'this' pointer passed from the
498 // owner, hence making method 'set_owner' needless.
499 , my_node(NULL)
500 {}
501 void set_owner( T *node ) { my_node = node; }
502};
503
504} // namespace internal
505
506#endif // __TBB__flow_graph_body_impl_H
507
#define __TBB_override
Definition tbb_stddef.h:240
#define __TBB_STATIC_ASSERT(condition, msg)
Definition tbb_stddef.h:553
#define __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES
Definition tbb_config.h:857
#define __TBB_FLOW_GRAPH_PRIORITY_ARG1(arg1, priority)
void const char const char int ITT_FORMAT __itt_group_sync s
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task * task
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function void size_t int ITT_FORMAT d __itt_heap_function void ITT_FORMAT p __itt_heap_function void void size_t int ITT_FORMAT d no args no args unsigned int ITT_FORMAT u const __itt_domain __itt_id ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain __itt_id ITT_FORMAT p const __itt_domain __itt_id __itt_timestamp __itt_timestamp ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain ITT_FORMAT p const __itt_domain __itt_string_handle unsigned long long value
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function void size_t int ITT_FORMAT d __itt_heap_function void ITT_FORMAT p __itt_heap_function void void size_t int ITT_FORMAT d no args no args unsigned int ITT_FORMAT u const __itt_domain __itt_id ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain __itt_id ITT_FORMAT p const __itt_domain __itt_id __itt_timestamp __itt_timestamp ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain ITT_FORMAT p const __itt_domain __itt_string_handle unsigned long long ITT_FORMAT lu const __itt_domain __itt_string_handle unsigned long long ITT_FORMAT lu const __itt_domain __itt_id __itt_string_handle __itt_metadata_type type
The graph class.
void suppress_unused_warning(const T1 &)
Utility template function to prevent "unused" warnings by various compilers.
Definition tbb_stddef.h:398
void check_input_node_body_input_type(Body)
void check_input_node_body_input_type_impl(Body)
tbb::internal::uint64_t tag_value
key_matching< tag_value > tag_matching
interface11::internal::Policy< rejecting, lightweight > rejecting_lightweight
interface11::internal::Policy< queueing, lightweight > queueing_lightweight
Forwards messages only if the threshold has not been reached.
field of type K being used for matching.
A functor that takes no input and generates a value of type Output.
virtual Output operator()(flow_control &fc)=0
virtual input_body * clone()=0
The leaf for input_body.
input_body_leaf * clone() __TBB_override
Output operator()(flow_control &fc) __TBB_override
virtual source_body * clone()=0
virtual bool operator()(Output &output)=0
The leaf for source_body.
bool operator()(Output &output) __TBB_override
source_body_leaf * clone() __TBB_override
A functor that takes an Input and generates an Output.
virtual function_body * clone()=0
virtual Output operator()(const Input &input)=0
the leaf for function_body
Output operator()(const Input &i) __TBB_override
function_body_leaf * clone() __TBB_override
the leaf for function_body specialized for Input and output of continue_msg
continue_msg operator()(const continue_msg &i) __TBB_override
the leaf for function_body specialized for Output of continue_msg
continue_msg operator()(const Input &i) __TBB_override
the leaf for function_body specialized for Input of continue_msg
Output operator()(const continue_msg &i) __TBB_override
function_body that takes an Input and a set of output ports
virtual void * get_body_ptr()=0
virtual multifunction_body * clone()=0
virtual void operator()(const Input &, OutputSet &)=0
leaf for multifunction. OutputSet can be a std::tuple or a vector.
void operator()(const Input &input, OutputSet &oset) __TBB_override
multifunction_body_leaf * clone() __TBB_override
virtual type_to_key_function_body * clone()=0
virtual Output operator()(const Input &input)=0
virtual type_to_key_function_body * clone()=0
virtual const Output & operator()(const Input &input)=0
Output operator()(const Input &i) __TBB_override
type_to_key_function_body_leaf * clone() __TBB_override
type_to_key_function_body_leaf * clone() __TBB_override
A task that calls a node's forward_task function.
A task that calls a node's apply_body_bypass function, passing in an input of type Input.
apply_body_task_bypass(NodeType &n, const Input &i)
A task that calls a node's apply_body_bypass function with no input.
An empty functor that takes an Input and returns a default constructed Output.
Output operator()(const Input &) const
Strips its template type argument from cv- and ref-qualifiers.
Detects whether two given types are the same.
Base class for types that should not be assigned.
Definition tbb_stddef.h:322
Base class for types that should not be copied or assigned.
Definition tbb_stddef.h:330

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.