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-2019 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 
20 #ifndef __TBB_flow_graph_H
21 #error Do not #include this internal file directly; use public TBB headers instead.
22 #endif
23 
24 // included in namespace tbb::flow::interfaceX (in flow_graph.h)
25 
26 namespace internal {
27 
28 typedef tbb::internal::uint64_t tag_value;
29 
31 
32 #if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT
33 
34 template<typename ... Policies> struct Policy {};
35 
36 template<typename ... Policies> struct has_policy;
37 
38 template<typename ExpectedPolicy, typename FirstPolicy, typename ...Policies>
39 struct has_policy<ExpectedPolicy, FirstPolicy, Policies...> :
40  tbb::internal::bool_constant<has_policy<ExpectedPolicy, FirstPolicy>::value ||
41  has_policy<ExpectedPolicy, Policies...>::value> {};
42 
43 template<typename ExpectedPolicy, typename SinglePolicy>
44 struct has_policy<ExpectedPolicy, SinglePolicy> :
45  tbb::internal::bool_constant<tbb::internal::is_same_type<ExpectedPolicy, SinglePolicy>::value> {};
46 
47 template<typename ExpectedPolicy, typename ...Policies>
48 struct has_policy<ExpectedPolicy, Policy<Policies...> > : has_policy<ExpectedPolicy, Policies...> {};
49 
50 #else
51 
52 template<typename P1, typename P2 = void> struct Policy {};
53 
54 template<typename ExpectedPolicy, typename SinglePolicy>
55 struct has_policy : tbb::internal::bool_constant<tbb::internal::is_same_type<ExpectedPolicy, SinglePolicy>::value> {};
56 
57 template<typename ExpectedPolicy, typename P>
58 struct has_policy<ExpectedPolicy, Policy<P> > : has_policy<ExpectedPolicy, P> {};
59 
60 template<typename ExpectedPolicy, typename P1, typename P2>
61 struct has_policy<ExpectedPolicy, Policy<P1, P2> > :
62  tbb::internal::bool_constant<has_policy<ExpectedPolicy, P1>::value || has_policy<ExpectedPolicy, P2>::value> {};
63 
64 #endif
65 
66 namespace graph_policy_namespace {
67 
68  struct rejecting { };
69  struct reserving { };
70  struct queueing { };
71  struct lightweight { };
72 
73  // K == type of field used for key-matching. Each tag-matching port will be provided
74  // functor that, given an object accepted by the port, will return the
77  struct key_matching {
78  typedef K key_type;
79  typedef typename strip<K>::type base_key_type;
80  typedef KHash hash_compare_type;
81  };
82 
83  // old tag_matching join's new specifier
85 
86  // Aliases for Policy combinations
87  typedef interface11::internal::Policy<queueing, lightweight> queueing_lightweight;
88  typedef interface11::internal::Policy<rejecting, lightweight> rejecting_lightweight;
89 
90 } // namespace graph_policy_namespace
91 
92 // -------------- function_body containers ----------------------
93 
95 template< typename Output >
97 public:
98  virtual ~source_body() {}
99  virtual bool operator()(Output &output) = 0;
100  virtual source_body* clone() = 0;
101 };
102 
104 template< typename Output, typename Body>
105 class source_body_leaf : public source_body<Output> {
106 public:
107  source_body_leaf( const Body &_body ) : body(_body) { }
108  bool operator()(Output &output) __TBB_override { return body( output ); }
110  return new source_body_leaf< Output, Body >(body);
111  }
112  Body get_body() { return body; }
113 private:
114  Body body;
115 };
116 
118 template< typename Input, typename Output >
120 public:
121  virtual ~function_body() {}
122  virtual Output operator()(const Input &input) = 0;
123  virtual function_body* clone() = 0;
124 };
125 
127 template <typename Input, typename Output, typename B>
128 class function_body_leaf : public function_body< Input, Output > {
129 public:
130  function_body_leaf( const B &_body ) : body(_body) { }
131  Output operator()(const Input &i) __TBB_override { return body(i); }
132  B get_body() { return body; }
135  }
136 private:
137  B body;
138 };
139 
141 template <typename B>
142 class function_body_leaf< continue_msg, continue_msg, B> : public function_body< continue_msg, continue_msg > {
143 public:
144  function_body_leaf( const B &_body ) : body(_body) { }
145  continue_msg operator()( const continue_msg &i ) __TBB_override {
146  body(i);
147  return i;
148  }
149  B get_body() { return body; }
152  }
153 private:
154  B body;
155 };
156 
158 template <typename Input, typename B>
159 class function_body_leaf< Input, continue_msg, B> : public function_body< Input, continue_msg > {
160 public:
161  function_body_leaf( const B &_body ) : body(_body) { }
162  continue_msg operator()(const Input &i) __TBB_override {
163  body(i);
164  return continue_msg();
165  }
166  B get_body() { return body; }
169  }
170 private:
171  B body;
172 };
173 
175 template <typename Output, typename B>
176 class function_body_leaf< continue_msg, Output, B > : public function_body< continue_msg, Output > {
177 public:
178  function_body_leaf( const B &_body ) : body(_body) { }
179  Output operator()(const continue_msg &i) __TBB_override {
180  return body(i);
181  }
182  B get_body() { return body; }
185  }
186 private:
187  B body;
188 };
189 
191 template<typename Input, typename OutputSet>
193 public:
194  virtual ~multifunction_body () {}
195  virtual void operator()(const Input &/* input*/, OutputSet &/*oset*/) = 0;
196  virtual multifunction_body* clone() = 0;
197  virtual void* get_body_ptr() = 0;
198 };
199 
201 template<typename Input, typename OutputSet, typename B >
202 class multifunction_body_leaf : public multifunction_body<Input, OutputSet> {
203 public:
204  multifunction_body_leaf(const B &_body) : body(_body) { }
205  void operator()(const Input &input, OutputSet &oset) __TBB_override {
206  body(input, oset); // body may explicitly put() to one or more of oset.
207  }
208  void* get_body_ptr() __TBB_override { return &body; }
211  }
212 
213 private:
214  B body;
215 };
216 
217 // ------ function bodies for hash_buffers and key-matching joins.
218 
219 template<typename Input, typename Output>
221  public:
223  virtual Output operator()(const Input &input) = 0; // returns an Output
224  virtual type_to_key_function_body* clone() = 0;
225 };
226 
227 // specialization for ref output
228 template<typename Input, typename Output>
230  public:
232  virtual const Output & operator()(const Input &input) = 0; // returns a const Output&
233  virtual type_to_key_function_body* clone() = 0;
234 };
235 
236 template <typename Input, typename Output, typename B>
238 public:
239  type_to_key_function_body_leaf( const B &_body ) : body(_body) { }
240  Output operator()(const Input &i) __TBB_override { return body(i); }
241  B get_body() { return body; }
244  }
245 private:
246  B body;
247 };
248 
249 template <typename Input, typename Output, typename B>
251 public:
252  type_to_key_function_body_leaf( const B &_body ) : body(_body) { }
253  const Output& operator()(const Input &i) __TBB_override {
254  return body(i);
255  }
256  B get_body() { return body; }
259  }
260 private:
261  B body;
262 };
263 
264 // --------------------------- end of function_body containers ------------------------
265 
266 // --------------------------- node task bodies ---------------------------------------
267 
269 template< typename NodeType >
270 class forward_task_bypass : public graph_task {
271 
272  NodeType &my_node;
273 
274 public:
275 
276  forward_task_bypass( NodeType &n
278  , node_priority_t node_priority = no_priority
279  ) : graph_task(node_priority),
280 #else
281  ) :
282 #endif
283  my_node(n) {}
284 
286  task * new_task = my_node.forward_task();
287  if (new_task == SUCCESSFULLY_ENQUEUED) new_task = NULL;
288  return new_task;
289  }
290 };
291 
293 // return the task* unless it is SUCCESSFULLY_ENQUEUED, in which case return NULL
294 template< typename NodeType, typename Input >
295 class apply_body_task_bypass : public graph_task {
296 
297  NodeType &my_node;
298  Input my_input;
299 
300 public:
301 
302  apply_body_task_bypass( NodeType &n, const Input &i
304  , node_priority_t node_priority = no_priority
305  ) : graph_task(node_priority),
306 #else
307  ) :
308 #endif
309  my_node(n), my_input(i) {}
310 
312  task * next_task = my_node.apply_body_bypass( my_input );
313  if(next_task == SUCCESSFULLY_ENQUEUED) next_task = NULL;
314  return next_task;
315  }
316 };
317 
319 template< typename NodeType >
320 class source_task_bypass : public graph_task {
321 
322  NodeType &my_node;
323 
324 public:
325 
326  source_task_bypass( NodeType &n ) : my_node(n) {}
327 
329  task *new_task = my_node.apply_body_bypass( );
330  if(new_task == SUCCESSFULLY_ENQUEUED) return NULL;
331  return new_task;
332  }
333 };
334 
335 // ------------------------ end of node task bodies -----------------------------------
336 
338 template< typename Input, typename Output >
339 struct empty_body {
340  Output operator()( const Input & ) const { return Output(); }
341 };
342 
343 template<typename T, typename DecrementType, typename DummyType = void>
345 
346 template<typename T, typename DecrementType>
347 class decrementer<T, DecrementType,
348  typename tbb::internal::enable_if<
349  tbb::internal::is_integral<DecrementType>::value, void>::type
350  > : public receiver<DecrementType>, tbb::internal::no_copy {
352 protected:
353 
354  task* try_put_task( const DecrementType& value ) __TBB_override {
355  task* result = my_node->decrement_counter( value );
356  if( !result )
357  result = SUCCESSFULLY_ENQUEUED;
358  return result;
359  }
360 
362  return my_node->my_graph;
363  }
364 
365  template<typename U, typename V> friend class tbb::flow::interface11::limiter_node;
367 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
368  if (f & rf_clear_edges)
369  my_built_predecessors.clear();
370 #else
372 #endif
373  }
374 
375 public:
376  // Since decrementer does not make use of possibly unconstructed owner inside its
377  // constructor, my_node can be directly initialized with 'this' pointer passed from the
378  // owner, hence making method 'set_owner' needless.
379  decrementer() : my_node(NULL) {}
380  void set_owner( T *node ) { my_node = node; }
381 
382 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
383  spin_mutex my_mutex;
386 
387  typedef internal::edge_container<predecessor_type> built_predecessors_type;
388  typedef typename built_predecessors_type::edge_list_type predecessor_list_type;
389  built_predecessors_type &built_predecessors() __TBB_override { return my_built_predecessors; }
390 
391  void internal_add_built_predecessor( predecessor_type &s) __TBB_override {
392  spin_mutex::scoped_lock l(my_mutex);
393  my_built_predecessors.add_edge( s );
394  }
395 
396  void internal_delete_built_predecessor( predecessor_type &s) __TBB_override {
397  spin_mutex::scoped_lock l(my_mutex);
398  my_built_predecessors.delete_edge(s);
399  }
400 
401  void copy_predecessors( predecessor_list_type &v) __TBB_override {
402  spin_mutex::scoped_lock l(my_mutex);
403  my_built_predecessors.copy_edges(v);
404  }
405 
406  size_t predecessor_count() __TBB_override {
407  spin_mutex::scoped_lock l(my_mutex);
408  return my_built_predecessors.edge_count();
409  }
410 protected:
411  built_predecessors_type my_built_predecessors;
412 #endif /* TBB_DEPRECATED_FLOW_NODE_EXTRACTION */
413 };
414 
415 template<typename T>
416 class decrementer<T, continue_msg, void> : public continue_receiver, tbb::internal::no_copy {
417 
419 
421  return my_node->decrement_counter( 1 );
422  }
423 
424 protected:
425 
427  return my_node->my_graph;
428  }
429 
430 public:
431 
432  typedef continue_msg input_type;
433  typedef continue_msg output_type;
434  decrementer( int number_of_predecessors = 0 )
435  : continue_receiver(
436  __TBB_FLOW_GRAPH_PRIORITY_ARG1(number_of_predecessors, tbb::flow::internal::no_priority)
437  )
438  // Since decrementer does not make use of possibly unconstructed owner inside its
439  // constructor, my_node can be directly initialized with 'this' pointer passed from the
440  // owner, hence making method 'set_owner' needless.
441  , my_node(NULL)
442  {}
443  void set_owner( T *node ) { my_node = node; }
444 };
445 
446 } // namespace internal
447 
448 #endif // __TBB__flow_graph_body_impl_H
449 
type_to_key_function_body_leaf * clone() __TBB_override
static tbb::task *const SUCCESSFULLY_ENQUEUED
key_matching< tag_value > tag_matching
void const char const char int ITT_FORMAT __itt_group_sync s
Forwards messages only if the threshold has not been reached.
Definition: flow_graph.h:113
A task that calls a node&#39;s forward_task function.
The leaf for source_body.
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
#define __TBB_FLOW_GRAPH_PRIORITY_ARG1(arg1, priority)
Base class for types that should not be assigned.
Definition: tbb_stddef.h:322
friend class scoped_lock
Definition: spin_mutex.h:179
#define __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES
Definition: tbb_config.h:860
the leaf for function_body specialized for Input of continue_msg
A task that calls a node&#39;s apply_body_bypass function with no input.
void operator()(const Input &input, OutputSet &oset) __TBB_override
Output operator()(const Input &i) __TBB_override
void suppress_unused_warning(const T1 &)
Utility template function to prevent "unused" warnings by various compilers.
Definition: tbb_stddef.h:398
source_body_leaf * clone() __TBB_override
interface11::internal::Policy< rejecting, lightweight > rejecting_lightweight
Strips its template type argument from cv- and ref-qualifiers.
task * execute() __TBB_override
A task that calls a node&#39;s apply_body_bypass function, passing in an input of type Input...
untyped_sender predecessor_type
The predecessor type for this node.
Definition: flow_graph.h:362
the leaf for function_body
Output operator()(const Input &i) __TBB_override
A functor that takes no input and generates a value of type Output.
continue_msg operator()(const Input &i) __TBB_override
leaf for multifunction. OutputSet can be a std::tuple or a vector.
bool operator()(Output &output) __TBB_override
the leaf for function_body specialized for Output of continue_msg
A functor that takes an Input and generates an Output.
function_body_leaf * clone() __TBB_override
field of type K being used for matching.
Base class for types that should not be copied or assigned.
Definition: tbb_stddef.h:330
type_to_key_function_body_leaf * clone() __TBB_override
unsigned int node_priority_t
Output operator()(const Input &) const
#define __TBB_override
Definition: tbb_stddef.h:240
continue_msg operator()(const continue_msg &i) __TBB_override
function_body that takes an Input and a set of output ports
the leaf for function_body specialized for Input and output of continue_msg
task * try_put_task(const DecrementType &value) __TBB_override
Put item to successor; return task to run the successor if possible.
receiver< input_type >::predecessor_type predecessor_type
Definition: flow_graph.h:2602
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_id __itt_string_handle __itt_metadata_type type
Output operator()(const continue_msg &i) __TBB_override
interface11::internal::Policy< queueing, lightweight > queueing_lightweight
const Output & operator()(const Input &i) __TBB_override
tbb::internal::uint64_t tag_value
multifunction_body_leaf * clone() __TBB_override
apply_body_task_bypass(NodeType &n, const Input &i)
static const node_priority_t no_priority
An empty functor that takes an Input and returns a default constructed Output.
The graph class.
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

Copyright © 2005-2019 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.