Intel(R) Threading Building Blocks Doxygen Documentation  version 4.2.3
_flow_graph_indexer_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 
18 
19 */
20 
21 #ifndef __TBB__flow_graph_indexer_impl_H
22 #define __TBB__flow_graph_indexer_impl_H
23 
24 #ifndef __TBB_flow_graph_H
25 #error Do not #include this internal file directly; use public TBB headers instead.
26 #endif
27 
28 #include "_flow_graph_types_impl.h"
29 
30 namespace internal {
31 
32  // Output of the indexer_node is a tbb::flow::tagged_msg, and will be of
33  // the form tagged_msg<tag, result>
34  // where the value of tag will indicate which result was put to the
35  // successor.
36 
37  template<typename IndexerNodeBaseType, typename T, size_t K>
38  task* do_try_put(const T &v, void *p) {
39  typename IndexerNodeBaseType::output_type o(K, v);
40  return reinterpret_cast<IndexerNodeBaseType *>(p)->try_put_task(&o);
41  }
42 
43  template<typename TupleTypes,int N>
44  struct indexer_helper {
45  template<typename IndexerNodeBaseType, typename PortTuple>
46  static inline void set_indexer_node_pointer(PortTuple &my_input, IndexerNodeBaseType *p, graph& g) {
47  typedef typename tuple_element<N-1, TupleTypes>::type T;
48  task *(*indexer_node_put_task)(const T&, void *) = do_try_put<IndexerNodeBaseType, T, N-1>;
49  tbb::flow::get<N-1>(my_input).set_up(p, indexer_node_put_task, g);
50  indexer_helper<TupleTypes,N-1>::template set_indexer_node_pointer<IndexerNodeBaseType,PortTuple>(my_input, p, g);
51  }
52  template<typename InputTuple>
53  static inline void reset_inputs(InputTuple &my_input, reset_flags f) {
55  tbb::flow::get<N-1>(my_input).reset_receiver(f);
56  }
57 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
58  template<typename InputTuple>
59  static inline void extract(InputTuple &my_input) {
61  tbb::flow::get<N-1>(my_input).extract_receiver();
62  }
63 #endif
64  };
65 
66  template<typename TupleTypes>
67  struct indexer_helper<TupleTypes,1> {
68  template<typename IndexerNodeBaseType, typename PortTuple>
69  static inline void set_indexer_node_pointer(PortTuple &my_input, IndexerNodeBaseType *p, graph& g) {
70  typedef typename tuple_element<0, TupleTypes>::type T;
71  task *(*indexer_node_put_task)(const T&, void *) = do_try_put<IndexerNodeBaseType, T, 0>;
72  tbb::flow::get<0>(my_input).set_up(p, indexer_node_put_task, g);
73  }
74  template<typename InputTuple>
75  static inline void reset_inputs(InputTuple &my_input, reset_flags f) {
76  tbb::flow::get<0>(my_input).reset_receiver(f);
77  }
78 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
79  template<typename InputTuple>
80  static inline void extract(InputTuple &my_input) {
81  tbb::flow::get<0>(my_input).extract_receiver();
82  }
83 #endif
84  };
85 
86  template<typename T>
87  class indexer_input_port : public receiver<T> {
88  private:
90  typedef task* (* forward_function_ptr)(T const &, void* );
92 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
93  spin_mutex my_pred_mutex;
94  typedef typename receiver<T>::built_predecessors_type built_predecessors_type;
95  built_predecessors_type my_built_predecessors;
96 #endif /* TBB_DEPRECATED_FLOW_NODE_EXTRACTION */
97  graph* my_graph;
98  public:
99 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
100  indexer_input_port() : my_pred_mutex(), my_graph(NULL) {}
101  indexer_input_port( const indexer_input_port & other) : receiver<T>(), my_pred_mutex(), my_graph(other.my_graph) {
102  }
103 #endif /* TBB_DEPRECATED_FLOW_NODE_EXTRACTION */
104  void set_up(void* p, forward_function_ptr f, graph& g) {
105  my_indexer_ptr = p;
106  my_try_put_task = f;
107  my_graph = &g;
108  }
109 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
110  typedef typename receiver<T>::predecessor_list_type predecessor_list_type;
111  typedef typename receiver<T>::predecessor_type predecessor_type;
112 
113  built_predecessors_type &built_predecessors() __TBB_override { return my_built_predecessors; }
114 
115  size_t predecessor_count() __TBB_override {
116  spin_mutex::scoped_lock l(my_pred_mutex);
117  return my_built_predecessors.edge_count();
118  }
119  void internal_add_built_predecessor(predecessor_type &p) __TBB_override {
120  spin_mutex::scoped_lock l(my_pred_mutex);
121  my_built_predecessors.add_edge(p);
122  }
123  void internal_delete_built_predecessor(predecessor_type &p) __TBB_override {
124  spin_mutex::scoped_lock l(my_pred_mutex);
125  my_built_predecessors.delete_edge(p);
126  }
127  void copy_predecessors( predecessor_list_type &v) __TBB_override {
128  spin_mutex::scoped_lock l(my_pred_mutex);
129  my_built_predecessors.copy_edges(v);
130  }
131 #endif /* TBB_DEPRECATED_FLOW_NODE_EXTRACTION */
132  protected:
133  template< typename R, typename B > friend class run_and_put_task;
134  template<typename X, typename Y> friend class internal::broadcast_cache;
135  template<typename X, typename Y> friend class internal::round_robin_cache;
137  return my_try_put_task(v, my_indexer_ptr);
138  }
139 
141  return *my_graph;
142  }
143 
144  public:
145 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
146  void reset_receiver(reset_flags f) __TBB_override { if(f&rf_clear_edges) my_built_predecessors.clear(); }
147 #else
149 #endif
150 
151 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
152  void extract_receiver() { my_built_predecessors.receiver_extract(*this); }
153 #endif
154  };
155 
156  template<typename InputTuple, typename OutputType, typename StructTypes>
158  public:
160  typedef OutputType output_type;
161  typedef InputTuple input_type;
162 
163  // Some versions of Intel(R) C++ Compiler fail to generate an implicit constructor for the class which has std::tuple as a member.
165 
167  protected:
169  };
170 
172  template<typename InputTuple, typename OutputType, typename StructTypes>
173  class indexer_node_base : public graph_node, public indexer_node_FE<InputTuple, OutputType,StructTypes>,
174  public sender<OutputType> {
175  protected:
176  using graph_node::my_graph;
177  public:
179  typedef OutputType output_type;
180  typedef StructTypes tuple_types;
181  typedef typename sender<output_type>::successor_type successor_type;
183 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
184  typedef typename sender<output_type>::built_successors_type built_successors_type;
185  typedef typename sender<output_type>::successor_list_type successor_list_type;
186 #endif
187 
188  private:
189  // ----------- Aggregator ------------
191 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
192  , add_blt_succ, del_blt_succ,
193  blt_succ_cnt, blt_succ_cpy
194 #endif
195  };
197 
198  class indexer_node_base_operation : public aggregated_operation<indexer_node_base_operation> {
199  public:
200  char type;
201  union {
205 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
206  size_t cnt_val;
207  successor_list_type *succv;
208 #endif
209  };
211  type(char(t)), my_arg(e) {}
213  my_succ(const_cast<successor_type *>(&s)) {}
215  };
216 
217  typedef internal::aggregating_functor<class_type, indexer_node_base_operation> handler_type;
218  friend class internal::aggregating_functor<class_type, indexer_node_base_operation>;
219  aggregator<handler_type, indexer_node_base_operation> my_aggregator;
220 
223  while(op_list) {
224  current = op_list;
225  op_list = op_list->next;
226  switch(current->type) {
227 
228  case reg_succ:
230  __TBB_store_with_release(current->status, SUCCEEDED);
231  break;
232 
233  case rem_succ:
235  __TBB_store_with_release(current->status, SUCCEEDED);
236  break;
237  case try__put_task: {
238  current->bypass_t = my_successors.try_put_task(*(current->my_arg));
239  __TBB_store_with_release(current->status, SUCCEEDED); // return of try_put_task actual return value
240  }
241  break;
242 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
243  case add_blt_succ:
244  my_successors.internal_add_built_successor(*(current->my_succ));
245  __TBB_store_with_release(current->status, SUCCEEDED);
246  break;
247  case del_blt_succ:
248  my_successors.internal_delete_built_successor(*(current->my_succ));
249  __TBB_store_with_release(current->status, SUCCEEDED);
250  break;
251  case blt_succ_cnt:
252  current->cnt_val = my_successors.successor_count();
253  __TBB_store_with_release(current->status, SUCCEEDED);
254  break;
255  case blt_succ_cpy:
256  my_successors.copy_successors(*(current->succv));
257  __TBB_store_with_release(current->status, SUCCEEDED);
258  break;
259 #endif /* TBB_DEPRECATED_FLOW_NODE_EXTRACTION */
260  }
261  }
262  }
263  // ---------- end aggregator -----------
264  public:
265  indexer_node_base(graph& g) : graph_node(g), input_ports_type() {
267  my_successors.set_owner(this);
268  my_aggregator.initialize_handler(handler_type(this));
269  }
270 
271  indexer_node_base(const indexer_node_base& other) : graph_node(other.my_graph), input_ports_type(), sender<output_type>() {
273  my_successors.set_owner(this);
274  my_aggregator.initialize_handler(handler_type(this));
275  }
276 
279  my_aggregator.execute(&op_data);
280  return op_data.status == SUCCEEDED;
281  }
282 
285  my_aggregator.execute(&op_data);
286  return op_data.status == SUCCEEDED;
287  }
288 
289  task * try_put_task(output_type const *v) { // not a virtual method in this class
291  my_aggregator.execute(&op_data);
292  return op_data.bypass_t;
293  }
294 
295 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
296 
297  built_successors_type &built_successors() __TBB_override { return my_successors.built_successors(); }
298 
299  void internal_add_built_successor( successor_type &r) __TBB_override {
300  indexer_node_base_operation op_data(r, add_blt_succ);
301  my_aggregator.execute(&op_data);
302  }
303 
304  void internal_delete_built_successor( successor_type &r) __TBB_override {
305  indexer_node_base_operation op_data(r, del_blt_succ);
306  my_aggregator.execute(&op_data);
307  }
308 
309  size_t successor_count() __TBB_override {
310  indexer_node_base_operation op_data(blt_succ_cnt);
311  my_aggregator.execute(&op_data);
312  return op_data.cnt_val;
313  }
314 
315  void copy_successors( successor_list_type &v) __TBB_override {
316  indexer_node_base_operation op_data(blt_succ_cpy);
317  op_data.succv = &v;
318  my_aggregator.execute(&op_data);
319  }
320  void extract() __TBB_override {
321  my_successors.built_successors().sender_extract(*this);
322  indexer_helper<StructTypes,N>::extract(this->my_inputs);
323  }
324 #endif /* TBB_DEPRECATED_FLOW_NODE_EXTRACTION */
325  protected:
327  if(f & rf_clear_edges) {
330  }
331  }
332 
333  private:
335  }; //indexer_node_base
336 
337 
338  template<int N, typename InputTuple> struct input_types;
339 
340  template<typename InputTuple>
341  struct input_types<1, InputTuple> {
344  };
345 
346  template<typename InputTuple>
347  struct input_types<2, InputTuple> {
351  };
352 
353  template<typename InputTuple>
354  struct input_types<3, InputTuple> {
359  };
360 
361  template<typename InputTuple>
362  struct input_types<4, InputTuple> {
367  typedef typename internal::tagged_msg<size_t, first_type, second_type, third_type,
369  };
370 
371  template<typename InputTuple>
372  struct input_types<5, InputTuple> {
378  typedef typename internal::tagged_msg<size_t, first_type, second_type, third_type,
380  };
381 
382  template<typename InputTuple>
383  struct input_types<6, InputTuple> {
390  typedef typename internal::tagged_msg<size_t, first_type, second_type, third_type,
392  };
393 
394  template<typename InputTuple>
395  struct input_types<7, InputTuple> {
403  typedef typename internal::tagged_msg<size_t, first_type, second_type, third_type,
406  };
407 
408 
409  template<typename InputTuple>
410  struct input_types<8, InputTuple> {
419  typedef typename internal::tagged_msg<size_t, first_type, second_type, third_type,
422  };
423 
424 
425  template<typename InputTuple>
426  struct input_types<9, InputTuple> {
436  typedef typename internal::tagged_msg<size_t, first_type, second_type, third_type,
439  };
440 
441  template<typename InputTuple>
442  struct input_types<10, InputTuple> {
453  typedef typename internal::tagged_msg<size_t, first_type, second_type, third_type,
457  };
458 
459  // type generators
460  template<typename OutputTuple>
461  struct indexer_types : public input_types<tuple_size<OutputTuple>::value, OutputTuple> {
467  };
468 
469  template<class OutputTuple>
470  class unfolded_indexer_node : public indexer_types<OutputTuple>::indexer_base_type {
471  public:
473  typedef OutputTuple tuple_types;
475  private:
477  public:
480  };
481 
482 } /* namespace internal */
483 
484 #endif /* __TBB__flow_graph_indexer_impl_H */
tuple_element< 1, InputTuple >::type second_type
tuple_element< 8, InputTuple >::type nineth_type
tuple_element< 0, InputTuple >::type first_type
tuple_element< 0, InputTuple >::type first_type
wrap_tuple_elements< N, indexer_input_port, OutputTuple >::type input_ports_type
#define __TBB_override
Definition: tbb_stddef.h:244
static void reset_inputs(InputTuple &my_input, reset_flags f)
tuple_element< 1, InputTuple >::type second_type
tuple_element< 4, InputTuple >::type fifth_type
void reset_node(reset_flags f) __TBB_override
tuple_element< 3, InputTuple >::type fourth_type
tuple_element< 6, InputTuple >::type seventh_type
internal::tagged_msg< size_t, first_type, second_type, third_type, fourth_type, fifth_type, sixth_type, seventh_type, eighth_type, nineth_type, tenth_type > type
tuple_element< 1, InputTuple >::type second_type
indexer_node_FE< InputTuple, output_type, StructTypes > input_ports_type
tuple_element< 8, InputTuple >::type nineth_type
tuple_element< 1, InputTuple >::type second_type
tuple_element< 9, InputTuple >::type tenth_type
tuple_element< 4, InputTuple >::type fifth_type
void set_up(void *p, forward_function_ptr f, graph &g)
internal::aggregating_functor< class_type, indexer_node_base_operation > handler_type
tuple_element< 1, InputTuple >::type second_type
tuple_element< 5, InputTuple >::type sixth_type
task * try_put_task(output_type const *v)
A cache of successors that are put in a round-robin fashion.
internal::tagged_msg< size_t, first_type, second_type, third_type, fourth_type, fifth_type, sixth_type, seventh_type, eighth_type > type
tuple_element< 6, InputTuple >::type seventh_type
tuple_element< 4, InputTuple >::type fifth_type
tuple_element< 0, InputTuple >::type first_type
tuple_element< 4, InputTuple >::type fifth_type
tuple_element< 1, InputTuple >::type second_type
tuple_element< 0, InputTuple >::type first_type
graph & graph_reference() __TBB_override
indexer_node_base< InputTuple, output_type, StructTypes > class_type
internal::tagged_msg< size_t, first_type > type
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
internal::indexer_node_FE< input_ports_type, output_type, OutputTuple > indexer_FE_type
tuple_element< 0, InputTuple >::type first_type
bool remove_successor(successor_type &r) __TBB_override
Removes a successor from this node.
void register_successor(successor_type &r)
tuple_element< 0, InputTuple >::type first_type
tuple_element< 2, InputTuple >::type third_type
tuple_element< 4, InputTuple >::type fifth_type
tuple_element< 2, InputTuple >::type third_type
tuple_element< 5, InputTuple >::type sixth_type
aggregator< handler_type, indexer_node_base_operation > my_aggregator
void const char const char int ITT_FORMAT __itt_group_sync p
tuple_element< 2, InputTuple >::type third_type
void handle_operations(indexer_node_base_operation *op_list)
internal::tagged_msg< size_t, first_type, second_type, third_type, fourth_type, fifth_type > type
internal::tagged_msg< size_t, first_type, second_type, third_type, fourth_type, fifth_type, sixth_type, seventh_type, eighth_type, nineth_type > type
indexer_types< OutputTuple >::indexer_base_type base_type
tuple_element< 2, InputTuple >::type third_type
tuple_element< 1, InputTuple >::type second_type
tuple_element< 0, InputTuple >::type first_type
static void set_indexer_node_pointer(PortTuple &my_input, IndexerNodeBaseType *p, graph &g)
task *(* forward_function_ptr)(T const &, void *)
tuple_element< 1, InputTuple >::type second_type
tuple_element< 3, InputTuple >::type fourth_type
task * do_try_put(const T &v, void *p)
broadcast_cache< output_type, null_rw_mutex > my_successors
indexer_types< OutputTuple >::input_ports_type input_ports_type
internal::indexer_node_base< input_ports_type, output_type, OutputTuple > indexer_base_type
tuple_element< 1, InputTuple >::type second_type
tuple_element< 3, InputTuple >::type fourth_type
tuple_element< 4, InputTuple >::type fifth_type
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 set_owner(owner_type *owner)
tuple_element< 6, InputTuple >::type seventh_type
task * try_put_task(const T &v) __TBB_override
bool register_successor(successor_type &r) __TBB_override
Add a new successor to this node.
tuple_element< 2, InputTuple >::type third_type
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
indexer_types< OutputTuple >::output_type output_type
tuple_element< 5, InputTuple >::type sixth_type
tuple_element< 3, InputTuple >::type fourth_type
sender< output_type >::successor_type successor_type
internal::tagged_msg< size_t, first_type, second_type > type
tuple_element< 2, InputTuple >::type third_type
tuple_element< 0, InputTuple >::type first_type
internal::tagged_msg< size_t, first_type, second_type, third_type, fourth_type > type
void const char const char int ITT_FORMAT __itt_group_sync s
void remove_successor(successor_type &r)
tuple_element< 2, InputTuple >::type third_type
internal::tagged_msg< size_t, first_type, second_type, third_type, fourth_type, fifth_type, sixth_type > type
tuple_element< 7, InputTuple >::type eighth_type
tuple_element< 0, InputTuple >::type first_type
A cache of successors that are broadcast to.
tuple_element< 2, InputTuple >::type third_type
tuple_element< 0, InputTuple >::type first_type
tuple_element< 3, InputTuple >::type fourth_type
input_types< N, OutputTuple >::type output_type
tuple_element< 7, InputTuple >::type eighth_type
static void set_indexer_node_pointer(PortTuple &my_input, IndexerNodeBaseType *p, graph &g)
tuple_element< 3, InputTuple >::type fourth_type
internal::tagged_msg< size_t, first_type, second_type, third_type > type
void reset_receiver(reset_flags) __TBB_override
tuple_element< 6, InputTuple >::type seventh_type
tuple_element< 5, InputTuple >::type sixth_type
tuple_element< 7, InputTuple >::type eighth_type
void __TBB_store_with_release(volatile T &location, V value)
Definition: tbb_machine.h:717
indexer_node_base(const indexer_node_base &other)
tuple_element< 3, InputTuple >::type fourth_type
static void reset_inputs(InputTuple &my_input, reset_flags f)
task * try_put_task(const T &t) __TBB_override
tuple_element< 5, InputTuple >::type sixth_type
unfolded_indexer_node(const unfolded_indexer_node &other)
internal::tagged_msg< size_t, first_type, second_type, third_type, fourth_type, fifth_type, sixth_type, seventh_type > type

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.