Intel(R) Threading Building Blocks Doxygen Documentation  version 4.2.3
_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 
28 namespace internal {
29 
30 typedef tbb::internal::uint64_t tag_value;
31 
33 
34 #if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT
35 
36 template<typename ... Policies> struct Policy {};
37 
38 template<typename ... Policies> struct has_policy;
39 
40 template<typename ExpectedPolicy, typename FirstPolicy, typename ...Policies>
41 struct has_policy<ExpectedPolicy, FirstPolicy, Policies...> :
42  tbb::internal::bool_constant<has_policy<ExpectedPolicy, FirstPolicy>::value ||
43  has_policy<ExpectedPolicy, Policies...>::value> {};
44 
45 template<typename ExpectedPolicy, typename SinglePolicy>
46 struct has_policy<ExpectedPolicy, SinglePolicy> :
47  tbb::internal::bool_constant<tbb::internal::is_same_type<ExpectedPolicy, SinglePolicy>::value> {};
48 
49 template<typename ExpectedPolicy, typename ...Policies>
50 struct has_policy<ExpectedPolicy, Policy<Policies...> > : has_policy<ExpectedPolicy, Policies...> {};
51 
52 #else
53 
54 template<typename P1, typename P2 = void> struct Policy {};
55 
56 template<typename ExpectedPolicy, typename SinglePolicy>
57 struct has_policy : tbb::internal::bool_constant<tbb::internal::is_same_type<ExpectedPolicy, SinglePolicy>::value> {};
58 
59 template<typename ExpectedPolicy, typename P>
60 struct has_policy<ExpectedPolicy, Policy<P> > : has_policy<ExpectedPolicy, P> {};
61 
62 template<typename ExpectedPolicy, typename P1, typename P2>
63 struct 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 
68 namespace 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
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 ----------------------
96 template< typename Output >
98 public:
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 
109 template <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 
116 template <typename Body>
118  check_input_node_body_input_type_impl(&Body::operator());
119 }
120 
121 template <typename ReturnType, typename T>
122 void 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 
129 template< typename Output, typename Body>
130 class input_body_leaf : public input_body<Output> {
131 public:
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; }
146 private:
147  Body body;
148 };
149 
150 template< typename Output >
152 public:
153  virtual ~source_body() {}
154  virtual bool operator()(Output &output) = 0;
155  virtual source_body* clone() = 0;
156 };
157 
159 template< typename Output, typename Body>
160 class source_body_leaf : public source_body<Output> {
161 public:
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; }
171 private:
172  Body body;
173 };
174 
176 template< typename Input, typename Output >
178 public:
179  virtual ~function_body() {}
180  virtual Output operator()(const Input &input) = 0;
181  virtual function_body* clone() = 0;
182 };
183 
185 template <typename Input, typename Output, typename B>
186 class function_body_leaf : public function_body< Input, Output > {
187 public:
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  }
194 private:
195  B body;
196 };
197 
199 template <typename B>
200 class function_body_leaf< continue_msg, continue_msg, B> : public function_body< continue_msg, continue_msg > {
201 public:
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  }
211 private:
212  B body;
213 };
214 
216 template <typename Input, typename B>
217 class function_body_leaf< Input, continue_msg, B> : public function_body< Input, continue_msg > {
218 public:
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  }
228 private:
229  B body;
230 };
231 
233 template <typename Output, typename B>
234 class function_body_leaf< continue_msg, Output, B > : public function_body< continue_msg, Output > {
235 public:
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  }
244 private:
245  B body;
246 };
247 
249 template<typename Input, typename OutputSet>
251 public:
252  virtual ~multifunction_body () {}
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 
259 template<typename Input, typename OutputSet, typename B >
260 class multifunction_body_leaf : public multifunction_body<Input, OutputSet> {
261 public:
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 
271 private:
272  B body;
273 };
274 
275 // ------ function bodies for hash_buffers and key-matching joins.
276 
277 template<typename Input, typename Output>
279  public:
281  virtual Output operator()(const Input &input) = 0; // returns an Output
283 };
284 
285 // specialization for ref output
286 template<typename Input, typename Output>
288  public:
290  virtual const Output & operator()(const Input &input) = 0; // returns a const Output&
292 };
293 
294 template <typename Input, typename Output, typename B>
296 public:
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  }
303 private:
304  B body;
305 };
306 
307 template <typename Input, typename Output, typename B>
309 public:
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  }
318 private:
319  B body;
320 };
321 
322 // --------------------------- end of function_body containers ------------------------
323 
324 // --------------------------- node task bodies ---------------------------------------
325 
327 template< typename NodeType >
328 class forward_task_bypass : public graph_task {
329 
330  NodeType &my_node;
331 
332 public:
333 
334  forward_task_bypass( NodeType &n
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
352 template< typename NodeType, typename Input >
353 class apply_body_task_bypass : public graph_task {
354 
355  NodeType &my_node;
356  Input my_input;
357 
358 public:
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 
377 template< typename NodeType >
378 class source_task_bypass : public graph_task {
379 
380  NodeType &my_node;
381 
382 public:
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 
396 template< typename Input, typename Output >
397 struct empty_body {
398  Output operator()( const Input & ) const { return Output(); }
399 };
400 
401 template<typename T, typename DecrementType, typename DummyType = void>
403 
404 template<typename T, typename DecrementType>
405 class 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 {
410 protected:
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;
425 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
426  if (f & rf_clear_edges)
427  my_built_predecessors.clear();
428 #else
430 #endif
431  }
432 
433 public:
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;
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 {
451  my_built_predecessors.add_edge( s );
452  }
453 
454  void internal_delete_built_predecessor( predecessor_type &s) __TBB_override {
456  my_built_predecessors.delete_edge(s);
457  }
458 
459  void copy_predecessors( predecessor_list_type &v) __TBB_override {
461  my_built_predecessors.copy_edges(v);
462  }
463 
464  size_t predecessor_count() __TBB_override {
466  return my_built_predecessors.edge_count();
467  }
468 protected:
469  built_predecessors_type my_built_predecessors;
470 #endif /* TBB_DEPRECATED_FLOW_NODE_EXTRACTION */
471 };
472 
473 template<typename T>
474 class decrementer<T, continue_msg, void> : public continue_receiver, tbb::internal::no_copy {
475 
477 
479  return my_node->decrement_counter( 1 );
480  }
481 
482 protected:
483 
485  return my_node->my_graph;
486  }
487 
488 public:
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_FLOW_GRAPH_PRIORITY_ARG1(arg1, priority)
#define __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES
Definition: tbb_config.h:857
#define __TBB_override
Definition: tbb_stddef.h:240
#define __TBB_STATIC_ASSERT(condition, msg)
Definition: tbb_stddef.h:553
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
static const node_priority_t no_priority
unsigned int node_priority_t
static tbb::task *const SUCCESSFULLY_ENQUEUED
Forwards messages only if the threshold has not been reached.
Definition: flow_graph.h:2985
receiver< input_type >::predecessor_type predecessor_type
Definition: flow_graph.h:2989
untyped_sender predecessor_type
The predecessor type for this node.
Definition: flow_graph.h:370
field of type K being used for matching.
A functor that takes no input and generates a value of type Output.
virtual input_body * clone()=0
virtual Output operator()(flow_control &fc)=0
The leaf for input_body.
input_body_leaf * clone() __TBB_override
input_body_leaf(const Body &_body)
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 void operator()(const Input &, OutputSet &)=0
virtual multifunction_body * clone()=0
leaf for multifunction. OutputSet can be a std::tuple or a vector.
multifunction_body_leaf * clone() __TBB_override
void operator()(const Input &input, OutputSet &oset) __TBB_override
virtual type_to_key_function_body * clone()=0
virtual Output operator()(const Input &input)=0
virtual const Output & operator()(const Input &input)=0
virtual type_to_key_function_body * clone()=0
Output operator()(const Input &i) __TBB_override
type_to_key_function_body_leaf * clone() __TBB_override
const Output & operator()(const Input &i) __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.
task * execute() __TBB_override
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.
friend class scoped_lock
Definition: spin_mutex.h:179
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.