21 #ifndef __TBB__flow_graph_indexer_impl_H 22 #define __TBB__flow_graph_indexer_impl_H 24 #ifndef __TBB_flow_graph_H 25 #error Do not #include this internal file directly; use public TBB headers instead. 28 #include "tbb/internal/_flow_graph_types_impl.h" 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);
43 template<
typename TupleTypes,
int N>
45 template<
typename IndexerNodeBaseType,
typename PortTuple>
46 static inline void set_indexer_node_pointer(PortTuple &my_input, IndexerNodeBaseType *p) {
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);
50 indexer_helper<TupleTypes,N-1>::template set_indexer_node_pointer<IndexerNodeBaseType,PortTuple>(my_input, p);
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);
57 #if TBB_PREVIEW_FLOW_GRAPH_FEATURES 58 template<
typename InputTuple>
59 static inline void extract(InputTuple &my_input) {
61 tbb::flow::get<N-1>(my_input).extract_receiver();
66 template<
typename TupleTypes>
68 template<
typename IndexerNodeBaseType,
typename PortTuple>
69 static inline void set_indexer_node_pointer(PortTuple &my_input, IndexerNodeBaseType *p) {
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);
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);
78 #if TBB_PREVIEW_FLOW_GRAPH_FEATURES 79 template<
typename InputTuple>
80 static inline void extract(InputTuple &my_input) {
81 tbb::flow::get<0>(my_input).extract_receiver();
90 typedef task* (* forward_function_ptr)(T
const &,
void* );
91 forward_function_ptr my_try_put_task;
92 #if TBB_PREVIEW_FLOW_GRAPH_FEATURES 93 spin_mutex my_pred_mutex;
94 typedef typename receiver<T>::built_predecessors_type built_predecessors_type;
95 built_predecessors_type my_built_predecessors;
98 #if TBB_PREVIEW_FLOW_GRAPH_FEATURES 103 void set_up(
void *p, forward_function_ptr f) {
107 #if TBB_PREVIEW_FLOW_GRAPH_FEATURES 108 typedef typename receiver<T>::predecessor_list_type predecessor_list_type;
109 typedef typename receiver<T>::predecessor_type predecessor_type;
111 built_predecessors_type &built_predecessors() {
return my_built_predecessors; }
113 size_t predecessor_count() {
114 spin_mutex::scoped_lock l(my_pred_mutex);
115 return my_built_predecessors.edge_count();
117 void internal_add_built_predecessor(predecessor_type &p) {
118 spin_mutex::scoped_lock l(my_pred_mutex);
119 my_built_predecessors.add_edge(p);
121 void internal_delete_built_predecessor(predecessor_type &p) {
122 spin_mutex::scoped_lock l(my_pred_mutex);
123 my_built_predecessors.delete_edge(p);
125 void copy_predecessors( predecessor_list_type &v) {
126 spin_mutex::scoped_lock l(my_pred_mutex);
127 return my_built_predecessors.copy_edges(v);
129 void clear_predecessors() {
130 spin_mutex::scoped_lock l(my_pred_mutex);
131 my_built_predecessors.clear();
135 template<
typename R,
typename B >
friend class run_and_put_task;
138 task *try_put_task(
const T &v) {
139 return my_try_put_task(v, my_indexer_ptr);
143 #if TBB_PREVIEW_FLOW_GRAPH_FEATURES 144 void reset_receiver(reset_flags f) {
if(f&rf_clear_edges) my_built_predecessors.clear(); }
146 void reset_receiver(reset_flags ) { }
149 #if TBB_PREVIEW_FLOW_GRAPH_FEATURES 150 void extract_receiver() { my_built_predecessors.receiver_extract(*
this); }
154 template<
typename InputTuple,
typename OutputType,
typename StructTypes>
157 static const int N = tbb::flow::tuple_size<InputTuple>::value;
158 typedef OutputType output_type;
159 typedef InputTuple input_type;
164 input_type &input_ports() {
return my_inputs; }
166 input_type my_inputs;
170 template<
typename InputTuple,
typename OutputType,
typename StructTypes>
172 public sender<OutputType> {
174 using graph_node::my_graph;
176 static const size_t N = tbb::flow::tuple_size<InputTuple>::value;
177 typedef OutputType output_type;
178 typedef StructTypes tuple_types;
179 typedef typename sender<output_type>::successor_type successor_type;
181 #if TBB_PREVIEW_FLOW_GRAPH_FEATURES 182 typedef typename sender<output_type>::built_successors_type built_successors_type;
183 typedef typename sender<output_type>::successor_list_type successor_list_type;
188 enum op_type { reg_succ, rem_succ, try__put_task
189 #if TBB_PREVIEW_FLOW_GRAPH_FEATURES 190 , add_blt_succ, del_blt_succ,
191 blt_succ_cnt, blt_succ_cpy
194 enum op_stat {WAIT=0, SUCCEEDED, FAILED};
197 class indexer_node_base_operation :
public aggregated_operation<indexer_node_base_operation> {
201 output_type
const *my_arg;
202 successor_type *my_succ;
204 #if TBB_PREVIEW_FLOW_GRAPH_FEATURES 206 successor_list_type *succv;
209 indexer_node_base_operation(
const output_type* e, op_type t) :
210 type(
char(t)), my_arg(e) {}
211 indexer_node_base_operation(
const successor_type &s, op_type t) : type(
char(t)),
212 my_succ(const_cast<successor_type *>(&s)) {}
213 indexer_node_base_operation(op_type t) : type(
char(t)) {}
216 typedef internal::aggregating_functor<class_type, indexer_node_base_operation> handler_type;
217 friend class internal::aggregating_functor<class_type, indexer_node_base_operation>;
218 aggregator<handler_type, indexer_node_base_operation> my_aggregator;
220 void handle_operations(indexer_node_base_operation* op_list) {
221 indexer_node_base_operation *current;
224 op_list = op_list->next;
225 switch(current->type) {
228 my_successors.register_successor(*(current->my_succ));
229 __TBB_store_with_release(current->status, SUCCEEDED);
233 my_successors.remove_successor(*(current->my_succ));
234 __TBB_store_with_release(current->status, SUCCEEDED);
236 case try__put_task: {
237 current->bypass_t = my_successors.try_put_task(*(current->my_arg));
238 __TBB_store_with_release(current->status, SUCCEEDED);
241 #if TBB_PREVIEW_FLOW_GRAPH_FEATURES 243 my_successors.internal_add_built_successor(*(current->my_succ));
244 __TBB_store_with_release(current->status, SUCCEEDED);
247 my_successors.internal_delete_built_successor(*(current->my_succ));
248 __TBB_store_with_release(current->status, SUCCEEDED);
251 current->cnt_val = my_successors.successor_count();
252 __TBB_store_with_release(current->status, SUCCEEDED);
255 my_successors.copy_successors(*(current->succv));
256 __TBB_store_with_release(current->status, SUCCEEDED);
266 my_successors.set_owner(
this);
267 my_aggregator.initialize_handler(handler_type(
this));
272 my_successors.set_owner(
this);
273 my_aggregator.initialize_handler(handler_type(
this));
276 bool register_successor(successor_type &r) {
277 indexer_node_base_operation op_data(r, reg_succ);
278 my_aggregator.execute(&op_data);
279 return op_data.status == SUCCEEDED;
282 bool remove_successor( successor_type &r) {
283 indexer_node_base_operation op_data(r, rem_succ);
284 my_aggregator.execute(&op_data);
285 return op_data.status == SUCCEEDED;
288 task * try_put_task(output_type
const *v) {
289 indexer_node_base_operation op_data(v, try__put_task);
290 my_aggregator.execute(&op_data);
291 return op_data.bypass_t;
294 #if TBB_PREVIEW_FLOW_GRAPH_FEATURES 296 built_successors_type &built_successors() {
return my_successors.built_successors(); }
298 void internal_add_built_successor( successor_type &r) {
299 indexer_node_base_operation op_data(r, add_blt_succ);
300 my_aggregator.execute(&op_data);
303 void internal_delete_built_successor( successor_type &r) {
304 indexer_node_base_operation op_data(r, del_blt_succ);
305 my_aggregator.execute(&op_data);
308 size_t successor_count() {
309 indexer_node_base_operation op_data(blt_succ_cnt);
310 my_aggregator.execute(&op_data);
311 return op_data.cnt_val;
314 void copy_successors( successor_list_type &v) {
315 indexer_node_base_operation op_data(blt_succ_cpy);
317 my_aggregator.execute(&op_data);
320 my_successors.built_successors().sender_extract(*
this);
325 void reset_node(reset_flags f) {
326 if(f & rf_clear_edges) {
327 my_successors.clear();
339 template<
typename InputTuple>
341 typedef typename tuple_element<0, InputTuple>::type first_type;
345 template<
typename InputTuple>
347 typedef typename tuple_element<0, InputTuple>::type first_type;
348 typedef typename tuple_element<1, InputTuple>::type second_type;
352 template<
typename InputTuple>
354 typedef typename tuple_element<0, InputTuple>::type first_type;
355 typedef typename tuple_element<1, InputTuple>::type second_type;
356 typedef typename tuple_element<2, InputTuple>::type third_type;
360 template<
typename InputTuple>
362 typedef typename tuple_element<0, InputTuple>::type first_type;
363 typedef typename tuple_element<1, InputTuple>::type second_type;
364 typedef typename tuple_element<2, InputTuple>::type third_type;
365 typedef typename tuple_element<3, InputTuple>::type fourth_type;
370 template<
typename InputTuple>
372 typedef typename tuple_element<0, InputTuple>::type first_type;
373 typedef typename tuple_element<1, InputTuple>::type second_type;
374 typedef typename tuple_element<2, InputTuple>::type third_type;
375 typedef typename tuple_element<3, InputTuple>::type fourth_type;
376 typedef typename tuple_element<4, InputTuple>::type fifth_type;
378 fourth_type, fifth_type>
type;
381 template<
typename InputTuple>
383 typedef typename tuple_element<0, InputTuple>::type first_type;
384 typedef typename tuple_element<1, InputTuple>::type second_type;
385 typedef typename tuple_element<2, InputTuple>::type third_type;
386 typedef typename tuple_element<3, InputTuple>::type fourth_type;
387 typedef typename tuple_element<4, InputTuple>::type fifth_type;
388 typedef typename tuple_element<5, InputTuple>::type sixth_type;
390 fourth_type, fifth_type, sixth_type>
type;
393 template<
typename InputTuple>
395 typedef typename tuple_element<0, InputTuple>::type first_type;
396 typedef typename tuple_element<1, InputTuple>::type second_type;
397 typedef typename tuple_element<2, InputTuple>::type third_type;
398 typedef typename tuple_element<3, InputTuple>::type fourth_type;
399 typedef typename tuple_element<4, InputTuple>::type fifth_type;
400 typedef typename tuple_element<5, InputTuple>::type sixth_type;
401 typedef typename tuple_element<6, InputTuple>::type seventh_type;
403 fourth_type, fifth_type, sixth_type,
408 template<
typename InputTuple>
410 typedef typename tuple_element<0, InputTuple>::type first_type;
411 typedef typename tuple_element<1, InputTuple>::type second_type;
412 typedef typename tuple_element<2, InputTuple>::type third_type;
413 typedef typename tuple_element<3, InputTuple>::type fourth_type;
414 typedef typename tuple_element<4, InputTuple>::type fifth_type;
415 typedef typename tuple_element<5, InputTuple>::type sixth_type;
416 typedef typename tuple_element<6, InputTuple>::type seventh_type;
417 typedef typename tuple_element<7, InputTuple>::type eighth_type;
419 fourth_type, fifth_type, sixth_type,
420 seventh_type, eighth_type>
type;
424 template<
typename InputTuple>
426 typedef typename tuple_element<0, InputTuple>::type first_type;
427 typedef typename tuple_element<1, InputTuple>::type second_type;
428 typedef typename tuple_element<2, InputTuple>::type third_type;
429 typedef typename tuple_element<3, InputTuple>::type fourth_type;
430 typedef typename tuple_element<4, InputTuple>::type fifth_type;
431 typedef typename tuple_element<5, InputTuple>::type sixth_type;
432 typedef typename tuple_element<6, InputTuple>::type seventh_type;
433 typedef typename tuple_element<7, InputTuple>::type eighth_type;
434 typedef typename tuple_element<8, InputTuple>::type nineth_type;
436 fourth_type, fifth_type, sixth_type,
437 seventh_type, eighth_type, nineth_type>
type;
440 template<
typename InputTuple>
442 typedef typename tuple_element<0, InputTuple>::type first_type;
443 typedef typename tuple_element<1, InputTuple>::type second_type;
444 typedef typename tuple_element<2, InputTuple>::type third_type;
445 typedef typename tuple_element<3, InputTuple>::type fourth_type;
446 typedef typename tuple_element<4, InputTuple>::type fifth_type;
447 typedef typename tuple_element<5, InputTuple>::type sixth_type;
448 typedef typename tuple_element<6, InputTuple>::type seventh_type;
449 typedef typename tuple_element<7, InputTuple>::type eighth_type;
450 typedef typename tuple_element<8, InputTuple>::type nineth_type;
451 typedef typename tuple_element<9, InputTuple>::type tenth_type;
453 fourth_type, fifth_type, sixth_type,
454 seventh_type, eighth_type, nineth_type,
459 template<
typename OutputTuple>
461 static const int N = tbb::flow::tuple_size<OutputTuple>::value;
468 template<
class OutputTuple>
471 typedef typename indexer_types<OutputTuple>::input_ports_type
input_ports_type;
472 typedef OutputTuple tuple_types;
473 typedef typename indexer_types<OutputTuple>::output_type output_type;
Definition: _flow_graph_indexer_impl.h:44
A cache of successors that are put in a round-robin fashion.
Definition: _flow_graph_impl.h:796
A cache of successors that are broadcast to.
Definition: _flow_graph_impl.h:751
Definition: _flow_graph_indexer_impl.h:469
Definition: _flow_graph_types_impl.h:602
Definition: _flow_graph_async_msg_impl.h:32
Definition: _flow_graph_indexer_impl.h:155
Definition: _flow_graph_indexer_impl.h:460
Definition: _flow_graph_types_impl.h:53
indexer_node_base
Definition: _flow_graph_indexer_impl.h:171