File indexing completed on 2025-01-18 10:12:47
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #ifndef __TBB__flow_graph_indexer_impl_H
0018 #define __TBB__flow_graph_indexer_impl_H
0019
0020 #ifndef __TBB_flow_graph_H
0021 #error Do not #include this internal file directly; use public TBB headers instead.
0022 #endif
0023
0024 #include "_flow_graph_types_impl.h"
0025
0026 namespace internal {
0027
0028
0029
0030
0031
0032
0033 template<typename IndexerNodeBaseType, typename T, size_t K>
0034 task* do_try_put(const T &v, void *p) {
0035 typename IndexerNodeBaseType::output_type o(K, v);
0036 return reinterpret_cast<IndexerNodeBaseType *>(p)->try_put_task(&o);
0037 }
0038
0039 template<typename TupleTypes,int N>
0040 struct indexer_helper {
0041 template<typename IndexerNodeBaseType, typename PortTuple>
0042 static inline void set_indexer_node_pointer(PortTuple &my_input, IndexerNodeBaseType *p, graph& g) {
0043 typedef typename tuple_element<N-1, TupleTypes>::type T;
0044 task *(*indexer_node_put_task)(const T&, void *) = do_try_put<IndexerNodeBaseType, T, N-1>;
0045 tbb::flow::get<N-1>(my_input).set_up(p, indexer_node_put_task, g);
0046 indexer_helper<TupleTypes,N-1>::template set_indexer_node_pointer<IndexerNodeBaseType,PortTuple>(my_input, p, g);
0047 }
0048 template<typename InputTuple>
0049 static inline void reset_inputs(InputTuple &my_input, reset_flags f) {
0050 indexer_helper<TupleTypes,N-1>::reset_inputs(my_input, f);
0051 tbb::flow::get<N-1>(my_input).reset_receiver(f);
0052 }
0053 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
0054 template<typename InputTuple>
0055 static inline void extract(InputTuple &my_input) {
0056 indexer_helper<TupleTypes,N-1>::extract(my_input);
0057 tbb::flow::get<N-1>(my_input).extract_receiver();
0058 }
0059 #endif
0060 };
0061
0062 template<typename TupleTypes>
0063 struct indexer_helper<TupleTypes,1> {
0064 template<typename IndexerNodeBaseType, typename PortTuple>
0065 static inline void set_indexer_node_pointer(PortTuple &my_input, IndexerNodeBaseType *p, graph& g) {
0066 typedef typename tuple_element<0, TupleTypes>::type T;
0067 task *(*indexer_node_put_task)(const T&, void *) = do_try_put<IndexerNodeBaseType, T, 0>;
0068 tbb::flow::get<0>(my_input).set_up(p, indexer_node_put_task, g);
0069 }
0070 template<typename InputTuple>
0071 static inline void reset_inputs(InputTuple &my_input, reset_flags f) {
0072 tbb::flow::get<0>(my_input).reset_receiver(f);
0073 }
0074 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
0075 template<typename InputTuple>
0076 static inline void extract(InputTuple &my_input) {
0077 tbb::flow::get<0>(my_input).extract_receiver();
0078 }
0079 #endif
0080 };
0081
0082 template<typename T>
0083 class indexer_input_port : public receiver<T> {
0084 private:
0085 void* my_indexer_ptr;
0086 typedef task* (* forward_function_ptr)(T const &, void* );
0087 forward_function_ptr my_try_put_task;
0088 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
0089 spin_mutex my_pred_mutex;
0090 typedef typename receiver<T>::built_predecessors_type built_predecessors_type;
0091 built_predecessors_type my_built_predecessors;
0092 #endif
0093 graph* my_graph;
0094 public:
0095 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
0096 indexer_input_port() : my_pred_mutex(), my_graph(NULL) {}
0097 indexer_input_port( const indexer_input_port & other) : receiver<T>(), my_pred_mutex(), my_graph(other.my_graph) {
0098 }
0099 #endif
0100 void set_up(void* p, forward_function_ptr f, graph& g) {
0101 my_indexer_ptr = p;
0102 my_try_put_task = f;
0103 my_graph = &g;
0104 }
0105 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
0106 typedef typename receiver<T>::predecessor_list_type predecessor_list_type;
0107 typedef typename receiver<T>::predecessor_type predecessor_type;
0108
0109 built_predecessors_type &built_predecessors() __TBB_override { return my_built_predecessors; }
0110
0111 size_t predecessor_count() __TBB_override {
0112 spin_mutex::scoped_lock l(my_pred_mutex);
0113 return my_built_predecessors.edge_count();
0114 }
0115 void internal_add_built_predecessor(predecessor_type &p) __TBB_override {
0116 spin_mutex::scoped_lock l(my_pred_mutex);
0117 my_built_predecessors.add_edge(p);
0118 }
0119 void internal_delete_built_predecessor(predecessor_type &p) __TBB_override {
0120 spin_mutex::scoped_lock l(my_pred_mutex);
0121 my_built_predecessors.delete_edge(p);
0122 }
0123 void copy_predecessors( predecessor_list_type &v) __TBB_override {
0124 spin_mutex::scoped_lock l(my_pred_mutex);
0125 my_built_predecessors.copy_edges(v);
0126 }
0127 #endif
0128 protected:
0129 template< typename R, typename B > friend class run_and_put_task;
0130 template<typename X, typename Y> friend class internal::broadcast_cache;
0131 template<typename X, typename Y> friend class internal::round_robin_cache;
0132 task *try_put_task(const T &v) __TBB_override {
0133 return my_try_put_task(v, my_indexer_ptr);
0134 }
0135
0136 graph& graph_reference() const __TBB_override {
0137 return *my_graph;
0138 }
0139
0140 public:
0141 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
0142 void reset_receiver(reset_flags f) __TBB_override { if(f&rf_clear_edges) my_built_predecessors.clear(); }
0143 #else
0144 void reset_receiver(reset_flags ) __TBB_override { }
0145 #endif
0146
0147 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
0148 void extract_receiver() { my_built_predecessors.receiver_extract(*this); }
0149 #endif
0150 };
0151
0152 template<typename InputTuple, typename OutputType, typename StructTypes>
0153 class indexer_node_FE {
0154 public:
0155 static const int N = tbb::flow::tuple_size<InputTuple>::value;
0156 typedef OutputType output_type;
0157 typedef InputTuple input_type;
0158
0159
0160 indexer_node_FE() : my_inputs() {}
0161
0162 input_type &input_ports() { return my_inputs; }
0163 protected:
0164 input_type my_inputs;
0165 };
0166
0167
0168 template<typename InputTuple, typename OutputType, typename StructTypes>
0169 class indexer_node_base : public graph_node, public indexer_node_FE<InputTuple, OutputType,StructTypes>,
0170 public sender<OutputType> {
0171 protected:
0172 using graph_node::my_graph;
0173 public:
0174 static const size_t N = tbb::flow::tuple_size<InputTuple>::value;
0175 typedef OutputType output_type;
0176 typedef StructTypes tuple_types;
0177 typedef typename sender<output_type>::successor_type successor_type;
0178 typedef indexer_node_FE<InputTuple, output_type,StructTypes> input_ports_type;
0179 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
0180 typedef typename sender<output_type>::built_successors_type built_successors_type;
0181 typedef typename sender<output_type>::successor_list_type successor_list_type;
0182 #endif
0183
0184 private:
0185
0186 enum op_type { reg_succ, rem_succ, try__put_task
0187 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
0188 , add_blt_succ, del_blt_succ,
0189 blt_succ_cnt, blt_succ_cpy
0190 #endif
0191 };
0192 typedef indexer_node_base<InputTuple,output_type,StructTypes> class_type;
0193
0194 class indexer_node_base_operation : public aggregated_operation<indexer_node_base_operation> {
0195 public:
0196 char type;
0197 union {
0198 output_type const *my_arg;
0199 successor_type *my_succ;
0200 task *bypass_t;
0201 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
0202 size_t cnt_val;
0203 successor_list_type *succv;
0204 #endif
0205 };
0206 indexer_node_base_operation(const output_type* e, op_type t) :
0207 type(char(t)), my_arg(e) {}
0208 indexer_node_base_operation(const successor_type &s, op_type t) : type(char(t)),
0209 my_succ(const_cast<successor_type *>(&s)) {}
0210 indexer_node_base_operation(op_type t) : type(char(t)) {}
0211 };
0212
0213 typedef internal::aggregating_functor<class_type, indexer_node_base_operation> handler_type;
0214 friend class internal::aggregating_functor<class_type, indexer_node_base_operation>;
0215 aggregator<handler_type, indexer_node_base_operation> my_aggregator;
0216
0217 void handle_operations(indexer_node_base_operation* op_list) {
0218 indexer_node_base_operation *current;
0219 while(op_list) {
0220 current = op_list;
0221 op_list = op_list->next;
0222 switch(current->type) {
0223
0224 case reg_succ:
0225 my_successors.register_successor(*(current->my_succ));
0226 __TBB_store_with_release(current->status, SUCCEEDED);
0227 break;
0228
0229 case rem_succ:
0230 my_successors.remove_successor(*(current->my_succ));
0231 __TBB_store_with_release(current->status, SUCCEEDED);
0232 break;
0233 case try__put_task: {
0234 current->bypass_t = my_successors.try_put_task(*(current->my_arg));
0235 __TBB_store_with_release(current->status, SUCCEEDED);
0236 }
0237 break;
0238 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
0239 case add_blt_succ:
0240 my_successors.internal_add_built_successor(*(current->my_succ));
0241 __TBB_store_with_release(current->status, SUCCEEDED);
0242 break;
0243 case del_blt_succ:
0244 my_successors.internal_delete_built_successor(*(current->my_succ));
0245 __TBB_store_with_release(current->status, SUCCEEDED);
0246 break;
0247 case blt_succ_cnt:
0248 current->cnt_val = my_successors.successor_count();
0249 __TBB_store_with_release(current->status, SUCCEEDED);
0250 break;
0251 case blt_succ_cpy:
0252 my_successors.copy_successors(*(current->succv));
0253 __TBB_store_with_release(current->status, SUCCEEDED);
0254 break;
0255 #endif
0256 }
0257 }
0258 }
0259
0260 public:
0261 indexer_node_base(graph& g) : graph_node(g), input_ports_type() {
0262 indexer_helper<StructTypes,N>::set_indexer_node_pointer(this->my_inputs, this, g);
0263 my_successors.set_owner(this);
0264 my_aggregator.initialize_handler(handler_type(this));
0265 }
0266
0267 indexer_node_base(const indexer_node_base& other) : graph_node(other.my_graph), input_ports_type(), sender<output_type>() {
0268 indexer_helper<StructTypes,N>::set_indexer_node_pointer(this->my_inputs, this, other.my_graph);
0269 my_successors.set_owner(this);
0270 my_aggregator.initialize_handler(handler_type(this));
0271 }
0272
0273 bool register_successor(successor_type &r) __TBB_override {
0274 indexer_node_base_operation op_data(r, reg_succ);
0275 my_aggregator.execute(&op_data);
0276 return op_data.status == SUCCEEDED;
0277 }
0278
0279 bool remove_successor( successor_type &r) __TBB_override {
0280 indexer_node_base_operation op_data(r, rem_succ);
0281 my_aggregator.execute(&op_data);
0282 return op_data.status == SUCCEEDED;
0283 }
0284
0285 task * try_put_task(output_type const *v) {
0286 indexer_node_base_operation op_data(v, try__put_task);
0287 my_aggregator.execute(&op_data);
0288 return op_data.bypass_t;
0289 }
0290
0291 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
0292
0293 built_successors_type &built_successors() __TBB_override { return my_successors.built_successors(); }
0294
0295 void internal_add_built_successor( successor_type &r) __TBB_override {
0296 indexer_node_base_operation op_data(r, add_blt_succ);
0297 my_aggregator.execute(&op_data);
0298 }
0299
0300 void internal_delete_built_successor( successor_type &r) __TBB_override {
0301 indexer_node_base_operation op_data(r, del_blt_succ);
0302 my_aggregator.execute(&op_data);
0303 }
0304
0305 size_t successor_count() __TBB_override {
0306 indexer_node_base_operation op_data(blt_succ_cnt);
0307 my_aggregator.execute(&op_data);
0308 return op_data.cnt_val;
0309 }
0310
0311 void copy_successors( successor_list_type &v) __TBB_override {
0312 indexer_node_base_operation op_data(blt_succ_cpy);
0313 op_data.succv = &v;
0314 my_aggregator.execute(&op_data);
0315 }
0316 void extract() __TBB_override {
0317 my_successors.built_successors().sender_extract(*this);
0318 indexer_helper<StructTypes,N>::extract(this->my_inputs);
0319 }
0320 #endif
0321 protected:
0322 void reset_node(reset_flags f) __TBB_override {
0323 if(f & rf_clear_edges) {
0324 my_successors.clear();
0325 indexer_helper<StructTypes,N>::reset_inputs(this->my_inputs,f);
0326 }
0327 }
0328
0329 private:
0330 broadcast_cache<output_type, null_rw_mutex> my_successors;
0331 };
0332
0333
0334 template<int N, typename InputTuple> struct input_types;
0335
0336 template<typename InputTuple>
0337 struct input_types<1, InputTuple> {
0338 typedef typename tuple_element<0, InputTuple>::type first_type;
0339 typedef typename internal::tagged_msg<size_t, first_type > type;
0340 };
0341
0342 template<typename InputTuple>
0343 struct input_types<2, InputTuple> {
0344 typedef typename tuple_element<0, InputTuple>::type first_type;
0345 typedef typename tuple_element<1, InputTuple>::type second_type;
0346 typedef typename internal::tagged_msg<size_t, first_type, second_type> type;
0347 };
0348
0349 template<typename InputTuple>
0350 struct input_types<3, InputTuple> {
0351 typedef typename tuple_element<0, InputTuple>::type first_type;
0352 typedef typename tuple_element<1, InputTuple>::type second_type;
0353 typedef typename tuple_element<2, InputTuple>::type third_type;
0354 typedef typename internal::tagged_msg<size_t, first_type, second_type, third_type> type;
0355 };
0356
0357 template<typename InputTuple>
0358 struct input_types<4, InputTuple> {
0359 typedef typename tuple_element<0, InputTuple>::type first_type;
0360 typedef typename tuple_element<1, InputTuple>::type second_type;
0361 typedef typename tuple_element<2, InputTuple>::type third_type;
0362 typedef typename tuple_element<3, InputTuple>::type fourth_type;
0363 typedef typename internal::tagged_msg<size_t, first_type, second_type, third_type,
0364 fourth_type> type;
0365 };
0366
0367 template<typename InputTuple>
0368 struct input_types<5, InputTuple> {
0369 typedef typename tuple_element<0, InputTuple>::type first_type;
0370 typedef typename tuple_element<1, InputTuple>::type second_type;
0371 typedef typename tuple_element<2, InputTuple>::type third_type;
0372 typedef typename tuple_element<3, InputTuple>::type fourth_type;
0373 typedef typename tuple_element<4, InputTuple>::type fifth_type;
0374 typedef typename internal::tagged_msg<size_t, first_type, second_type, third_type,
0375 fourth_type, fifth_type> type;
0376 };
0377
0378 template<typename InputTuple>
0379 struct input_types<6, InputTuple> {
0380 typedef typename tuple_element<0, InputTuple>::type first_type;
0381 typedef typename tuple_element<1, InputTuple>::type second_type;
0382 typedef typename tuple_element<2, InputTuple>::type third_type;
0383 typedef typename tuple_element<3, InputTuple>::type fourth_type;
0384 typedef typename tuple_element<4, InputTuple>::type fifth_type;
0385 typedef typename tuple_element<5, InputTuple>::type sixth_type;
0386 typedef typename internal::tagged_msg<size_t, first_type, second_type, third_type,
0387 fourth_type, fifth_type, sixth_type> type;
0388 };
0389
0390 template<typename InputTuple>
0391 struct input_types<7, InputTuple> {
0392 typedef typename tuple_element<0, InputTuple>::type first_type;
0393 typedef typename tuple_element<1, InputTuple>::type second_type;
0394 typedef typename tuple_element<2, InputTuple>::type third_type;
0395 typedef typename tuple_element<3, InputTuple>::type fourth_type;
0396 typedef typename tuple_element<4, InputTuple>::type fifth_type;
0397 typedef typename tuple_element<5, InputTuple>::type sixth_type;
0398 typedef typename tuple_element<6, InputTuple>::type seventh_type;
0399 typedef typename internal::tagged_msg<size_t, first_type, second_type, third_type,
0400 fourth_type, fifth_type, sixth_type,
0401 seventh_type> type;
0402 };
0403
0404
0405 template<typename InputTuple>
0406 struct input_types<8, InputTuple> {
0407 typedef typename tuple_element<0, InputTuple>::type first_type;
0408 typedef typename tuple_element<1, InputTuple>::type second_type;
0409 typedef typename tuple_element<2, InputTuple>::type third_type;
0410 typedef typename tuple_element<3, InputTuple>::type fourth_type;
0411 typedef typename tuple_element<4, InputTuple>::type fifth_type;
0412 typedef typename tuple_element<5, InputTuple>::type sixth_type;
0413 typedef typename tuple_element<6, InputTuple>::type seventh_type;
0414 typedef typename tuple_element<7, InputTuple>::type eighth_type;
0415 typedef typename internal::tagged_msg<size_t, first_type, second_type, third_type,
0416 fourth_type, fifth_type, sixth_type,
0417 seventh_type, eighth_type> type;
0418 };
0419
0420
0421 template<typename InputTuple>
0422 struct input_types<9, InputTuple> {
0423 typedef typename tuple_element<0, InputTuple>::type first_type;
0424 typedef typename tuple_element<1, InputTuple>::type second_type;
0425 typedef typename tuple_element<2, InputTuple>::type third_type;
0426 typedef typename tuple_element<3, InputTuple>::type fourth_type;
0427 typedef typename tuple_element<4, InputTuple>::type fifth_type;
0428 typedef typename tuple_element<5, InputTuple>::type sixth_type;
0429 typedef typename tuple_element<6, InputTuple>::type seventh_type;
0430 typedef typename tuple_element<7, InputTuple>::type eighth_type;
0431 typedef typename tuple_element<8, InputTuple>::type nineth_type;
0432 typedef typename internal::tagged_msg<size_t, first_type, second_type, third_type,
0433 fourth_type, fifth_type, sixth_type,
0434 seventh_type, eighth_type, nineth_type> type;
0435 };
0436
0437 template<typename InputTuple>
0438 struct input_types<10, InputTuple> {
0439 typedef typename tuple_element<0, InputTuple>::type first_type;
0440 typedef typename tuple_element<1, InputTuple>::type second_type;
0441 typedef typename tuple_element<2, InputTuple>::type third_type;
0442 typedef typename tuple_element<3, InputTuple>::type fourth_type;
0443 typedef typename tuple_element<4, InputTuple>::type fifth_type;
0444 typedef typename tuple_element<5, InputTuple>::type sixth_type;
0445 typedef typename tuple_element<6, InputTuple>::type seventh_type;
0446 typedef typename tuple_element<7, InputTuple>::type eighth_type;
0447 typedef typename tuple_element<8, InputTuple>::type nineth_type;
0448 typedef typename tuple_element<9, InputTuple>::type tenth_type;
0449 typedef typename internal::tagged_msg<size_t, first_type, second_type, third_type,
0450 fourth_type, fifth_type, sixth_type,
0451 seventh_type, eighth_type, nineth_type,
0452 tenth_type> type;
0453 };
0454
0455
0456 template<typename OutputTuple>
0457 struct indexer_types : public input_types<tuple_size<OutputTuple>::value, OutputTuple> {
0458 static const int N = tbb::flow::tuple_size<OutputTuple>::value;
0459 typedef typename input_types<N, OutputTuple>::type output_type;
0460 typedef typename wrap_tuple_elements<N,indexer_input_port,OutputTuple>::type input_ports_type;
0461 typedef internal::indexer_node_FE<input_ports_type,output_type,OutputTuple> indexer_FE_type;
0462 typedef internal::indexer_node_base<input_ports_type, output_type, OutputTuple> indexer_base_type;
0463 };
0464
0465 template<class OutputTuple>
0466 class unfolded_indexer_node : public indexer_types<OutputTuple>::indexer_base_type {
0467 public:
0468 typedef typename indexer_types<OutputTuple>::input_ports_type input_ports_type;
0469 typedef OutputTuple tuple_types;
0470 typedef typename indexer_types<OutputTuple>::output_type output_type;
0471 private:
0472 typedef typename indexer_types<OutputTuple>::indexer_base_type base_type;
0473 public:
0474 unfolded_indexer_node(graph& g) : base_type(g) {}
0475 unfolded_indexer_node(const unfolded_indexer_node &other) : base_type(other) {}
0476 };
0477
0478 }
0479
0480 #endif