17 #ifndef __TBB_flow_graph_H 18 #define __TBB_flow_graph_H 20 #define __TBB_flow_graph_H_include_area 37 #if TBB_USE_THREADING_TOOLS && TBB_PREVIEW_FLOW_GRAPH_TRACE && ( __linux__ || __APPLE__ ) 40 #pragma warning (push) 41 #pragma warning( disable: 2196 ) 43 #define __TBB_NOINLINE_SYM __attribute__((noinline)) 45 #define __TBB_NOINLINE_SYM 48 #if __TBB_PREVIEW_ASYNC_MSG 53 #if __TBB_PREVIEW_STREAMING_NODE 56 #include <unordered_map> 57 #include <type_traits> 58 #endif // __TBB_PREVIEW_STREAMING_NODE 60 #if TBB_DEPRECATED_FLOW_ENQUEUE 61 #define FLOW_SPAWN(a) tbb::task::enqueue((a)) 63 #define FLOW_SPAWN(a) tbb::task::spawn((a)) 67 #if __TBB_CPP11_TUPLE_PRESENT 72 using std::tuple_size;
73 using std::tuple_element;
78 #include "compat/tuple" 100 namespace interface11 {
123 template<
typename T,
typename M>
class reservable_predecessor_cache;
125 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET 130 template<
typename Order,
typename... Args>
struct node_set;
133 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION 137 class edge_container {
140 typedef std::list<C *, tbb::tbb_allocator<C *> > edge_list_type;
142 void add_edge(C &
s) {
143 built_edges.push_back(&s);
146 void delete_edge(C &s) {
147 for (
typename edge_list_type::iterator i = built_edges.begin(); i != built_edges.end(); ++i) {
155 void copy_edges(edge_list_type &v) {
159 size_t edge_count() {
160 return (
size_t)(built_edges.size());
169 template<
typename S >
void sender_extract(
S &s);
170 template<
typename R >
void receiver_extract(R &r);
173 edge_list_type built_edges;
188 namespace interface11 {
193 if (right == NULL)
return left;
195 if (left == NULL)
return right;
206 #if __TBB_PREVIEW_ASYNC_MSG 214 template<
typename T,
typename =
void >
217 typedef T filtered_type;
219 static const bool is_async_type =
false;
222 return static_cast<const void*
>(&t);
226 return static_cast<void*
>(&t);
229 static const T& from_void_ptr(
const void*
p) {
230 return *
static_cast<const T*
>(
p);
234 return *
static_cast<T*
>(
p);
237 static task* try_put_task_wrapper_impl(
receiver<T>*
const this_recv,
const void *
p,
bool is_async) {
255 template<
typename T >
257 typedef T async_type;
260 static const bool is_async_type =
true;
312 virtual bool register_successor( successor_type &r ) = 0;
315 virtual bool remove_successor( successor_type &r ) = 0;
323 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION 324 typedef internal::edge_container<successor_type> built_successors_type;
326 typedef built_successors_type::edge_list_type successor_list_type;
327 virtual built_successors_type &built_successors() = 0;
328 virtual void internal_add_built_successor( successor_type & ) = 0;
329 virtual void internal_delete_built_successor( successor_type & ) = 0;
330 virtual void copy_successors( successor_list_type &) = 0;
331 virtual size_t successor_count() = 0;
335 template<
typename X >
341 template<
typename X >
346 virtual bool try_get_wrapper(
void* p,
bool is_async ) = 0;
347 virtual bool try_reserve_wrapper(
void* p,
bool is_async ) = 0;
357 #if __TBB_PREVIEW_OPENCL_NODE 358 template<
typename,
typename >
friend class proxy_dependency_receiver;
371 if (!res)
return false;
381 virtual bool register_predecessor( predecessor_type & ) {
return false; }
386 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION 387 typedef internal::edge_container<predecessor_type> built_predecessors_type;
388 typedef built_predecessors_type::edge_list_type predecessor_list_type;
389 virtual built_predecessors_type &built_predecessors() = 0;
390 virtual void internal_add_built_predecessor( predecessor_type & ) = 0;
391 virtual void internal_delete_built_predecessor( predecessor_type & ) = 0;
392 virtual void copy_predecessors( predecessor_list_type & ) = 0;
393 virtual size_t predecessor_count() = 0;
401 virtual task* try_put_task_wrapper(
const void* p,
bool is_async ) = 0;
403 virtual graph& graph_reference()
const = 0;
410 virtual bool is_continue_receiver() {
return false; }
416 template<
typename T >
437 __TBB_ASSERT(
false,
"async_msg interface does not support 'pull' protocol in try_get()");
447 __TBB_ASSERT(
false,
"async_msg interface does not support 'pull' protocol in try_reserve()");
453 template<
typename T >
465 return internal::untyped_receiver::try_put(t);
469 return internal::untyped_receiver::try_put(t);
478 virtual task *try_put_task(
const T& t) = 0;
482 #else // __TBB_PREVIEW_ASYNC_MSG 485 template<
typename T >
505 virtual bool try_get( T & ) {
return false; }
508 virtual bool try_reserve( T & ) {
return false; }
511 virtual bool try_release( ) {
return false; }
514 virtual bool try_consume( ) {
return false; }
516 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION 517 __TBB_DEPRECATED typedef typename internal::edge_container<successor_type> built_successors_type;
519 __TBB_DEPRECATED typedef typename built_successors_type::edge_list_type successor_list_type;
529 template<
typename T >
542 bool try_put(
const T& t ) {
543 task *res = try_put_task(t);
544 if (!res)
return false;
555 virtual graph& graph_reference()
const = 0;
565 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION 566 __TBB_DEPRECATED typedef typename internal::edge_container<predecessor_type> built_predecessors_type;
567 __TBB_DEPRECATED typedef typename built_predecessors_type::edge_list_type predecessor_list_type;
570 __TBB_DEPRECATED virtual void internal_delete_built_predecessor( predecessor_type & ) = 0;
580 virtual bool is_continue_receiver() {
return false; }
582 #if __TBB_PREVIEW_OPENCL_NODE 583 template<
typename,
typename >
friend class proxy_dependency_receiver;
587 #endif // __TBB_PREVIEW_ASYNC_MSG 603 my_predecessor_count = my_initial_predecessor_count = number_of_predecessors;
604 my_current_count = 0;
611 my_current_count = 0;
618 ++my_predecessor_count;
628 --my_predecessor_count;
632 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION 633 __TBB_DEPRECATED typedef internal::edge_container<predecessor_type> built_predecessors_type;
635 built_predecessors_type &built_predecessors()
__TBB_override {
return my_built_predecessors; }
639 my_built_predecessors.add_edge( s );
644 my_built_predecessors.delete_edge(s);
649 my_built_predecessors.copy_edges(v);
654 return my_built_predecessors.edge_count();
667 if ( ++my_current_count < my_predecessor_count )
670 my_current_count = 0;
676 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION 679 built_predecessors_type my_built_predecessors;
691 my_current_count = 0;
693 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION 694 my_built_predecessors.clear();
696 my_predecessor_count = my_initial_predecessor_count;
703 virtual task * execute() = 0;
711 #if __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING 712 template <
typename K,
typename T>
729 namespace interface11 {
734 #if __TBB_PREVIEW_ASYNC_MSG 739 template <
typename C,
typename N>
742 if (begin) current_node = my_graph->my_nodes;
746 template <
typename C,
typename N>
749 return *operator->();
752 template <
typename C,
typename N>
757 template <
typename C,
typename N>
759 if (current_node) current_node = current_node->next;
764 namespace interface10 {
766 inline graph::graph() : my_nodes(NULL), my_nodes_last(NULL), my_task_arena(NULL) {
868 #if TBB_PREVIEW_FLOW_GRAPH_TRACE 869 inline void graph::set_name(
const char *
name) {
876 namespace interface11 {
879 my_graph.register_node(
this);
883 my_graph.remove_node(
this);
888 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET 889 using internal::node_set;
893 template <
typename Output >
905 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION 911 template<
typename Body >
913 :
graph_node(g), my_active(is_active), init_my_active(is_active),
916 my_reserved(false), my_has_cached_item(false)
923 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET 924 template <
typename Body,
typename... Successors>
925 source_node(
const node_set<internal::order::preceding, Successors...>&
successors, Body body,
bool is_active =
true )
927 make_edges(*
this, successors);
934 my_active(src.init_my_active),
935 init_my_active(src.init_my_active), my_body( src.my_init_body->clone() ), my_init_body(src.my_init_body->clone() ),
936 my_reserved(false), my_has_cached_item(false)
946 #if TBB_PREVIEW_FLOW_GRAPH_TRACE 968 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION 972 void internal_add_built_successor( successor_type &r)
__TBB_override {
977 void internal_delete_built_successor( successor_type &r)
__TBB_override {
999 if ( my_has_cached_item ) {
1001 my_has_cached_item =
false;
1013 if ( my_reserved ) {
1017 if ( my_has_cached_item ) {
1030 __TBB_ASSERT( my_reserved && my_has_cached_item,
"releasing non-existent reservation" );
1031 my_reserved =
false;
1040 __TBB_ASSERT( my_reserved && my_has_cached_item,
"consuming non-existent reservation" );
1041 my_reserved =
false;
1042 my_has_cached_item =
false;
1057 template<
typename Body>
1063 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION 1066 my_active = init_my_active;
1067 my_reserved =
false;
1068 if(my_has_cached_item) my_has_cached_item =
false;
1076 my_active = init_my_active;
1078 if(my_has_cached_item) {
1079 my_has_cached_item =
false;
1105 if ( my_reserved ) {
1108 if ( !my_has_cached_item ) {
1110 bool r = (*my_body)(my_cached_item);
1113 my_has_cached_item =
true;
1116 if ( my_has_cached_item ) {
1130 return (
new ( task::allocate_additional_child_of( *(this->my_graph.root_task()) ) )
1145 if ( !try_reserve_apply_body(v) )
1158 template <
typename Input,
typename Output = continue_msg,
typename Policy = queueing,
typename Allocator=cache_aligned_allocator<Input> >
1168 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION 1169 typedef typename input_impl_type::predecessor_list_type predecessor_list_type;
1170 typedef typename fOutput_type::successor_list_type successor_list_type;
1172 using input_impl_type::my_predecessors;
1178 template<
typename Body >
1191 #if __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES && __TBB_CPP11_PRESENT 1192 template <
typename Body>
1195 #endif // __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES && __TBB_CPP11_PRESENT 1197 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET 1198 template <
typename Body,
typename... Args>
1199 function_node(
const node_set<Args...>& nodes,
size_t concurrency, Body body,
1202 make_edges_in_order(nodes, *
this);
1205 #if __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES 1206 template <
typename Body,
typename... Args>
1208 : function_node(nodes, concurrency, body,
Policy(), priority) {}
1209 #endif // __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES 1210 #endif // __TBB_PREVIEW_FLOW_GRAPH_NODE_SET 1215 input_impl_type(src),
1216 fOutput_type(src.my_graph) {
1221 #if TBB_PREVIEW_FLOW_GRAPH_TRACE 1227 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION 1229 my_predecessors.built_predecessors().receiver_extract(*
this);
1230 successors().built_successors().sender_extract(*
this);
1238 using input_impl_type::try_put_task;
1243 input_impl_type::reset_function_input(f);
1245 if(f & rf_clear_edges) {
1247 my_predecessors.clear();
1250 __TBB_ASSERT(this->my_predecessors.empty(),
"function_node predecessors not empty");
1257 template <
typename Input,
typename Output,
typename Policy = queueing,
typename Allocator=cache_aligned_allocator<Input> >
1263 typename internal::wrap_tuple_elements<
1264 tbb::flow::tuple_size<Output>::value,
1265 internal::multifunction_output,
1281 using input_impl_type::my_predecessors;
1283 template<
typename Body>
1285 graph &g,
size_t concurrency,
1292 tbb::internal::fgt_multioutput_node_with_body<N>(
1293 CODEPTR(), tbb::internal::FLOW_MULTIFUNCTION_NODE,
1295 this->output_ports(), this->my_body
1299 #if __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES && __TBB_CPP11_PRESENT 1300 template <
typename Body>
1302 : multifunction_node(g, concurrency, body,
Policy(), priority) {}
1303 #endif // TBB_PREVIEW_FLOW_GRAPH_PRIORITIES && __TBB_CPP11_PRESENT 1305 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET 1306 template <
typename Body,
typename... Args>
1310 make_edges_in_order(nodes, *
this);
1313 #if __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES 1314 template <
typename Body,
typename... Args>
1316 : multifunction_node(nodes, concurrency, body,
Policy(), priority) {}
1317 #endif // __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES 1318 #endif // __TBB_PREVIEW_FLOW_GRAPH_NODE_SET 1321 graph_node(other.my_graph), base_type(other) {
1322 tbb::internal::fgt_multioutput_node_with_body<N>(
CODEPTR(), tbb::internal::FLOW_MULTIFUNCTION_NODE,
1324 this->output_ports(), this->my_body );
1327 #if TBB_PREVIEW_FLOW_GRAPH_TRACE 1333 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION 1335 my_predecessors.built_predecessors().receiver_extract(*
this);
1336 base_type::extract();
1346 template<
typename TupleType,
typename Allocator=cache_aligned_allocator<TupleType> >
1353 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION 1355 typedef typename base_type::predecessor_list_type predecessor_list_type;
1357 typedef typename predecessor_cache_type::built_predecessors_type built_predecessors_type;
1368 my_output_ports(
internal::init_output_ports<output_ports_type>::
call(g, my_output_ports))
1370 tbb::internal::fgt_multioutput_node<N>(
CODEPTR(), tbb::internal::FLOW_SPLIT_NODE, &this->my_graph,
1374 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET 1375 template <
typename... Args>
1377 make_edges_in_order(nodes, *
this);
1382 :
graph_node(other.my_graph), base_type(other),
1383 my_output_ports(
internal::init_output_ports<output_ports_type>::
call(other.my_graph, my_output_ports))
1385 tbb::internal::fgt_multioutput_node<N>(
CODEPTR(), tbb::internal::FLOW_SPLIT_NODE, &this->my_graph,
1389 #if TBB_PREVIEW_FLOW_GRAPH_TRACE 1404 if (f & rf_clear_edges)
1413 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION 1418 void internal_add_built_predecessor(predecessor_type&)
__TBB_override {}
1421 void internal_delete_built_predecessor(predecessor_type&)
__TBB_override {}
1427 built_predecessors_type &built_predecessors()
__TBB_override {
return my_predessors; }
1430 built_predecessors_type my_predessors;
1438 template <
typename Output,
typename Policy =
internal::Policy<
void> >
1450 template <
typename Body >
1466 #if __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES && __TBB_CPP11_PRESENT 1467 template <
typename Body>
1472 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET 1473 template <
typename Body,
typename... Args>
1477 make_edges_in_order(nodes, *
this);
1479 #if __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES 1480 template <
typename Body,
typename... Args>
1482 : continue_node(nodes, body,
Policy(), priority) {}
1483 #endif // __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES 1484 #endif // __TBB_PREVIEW_FLOW_GRAPH_NODE_SET 1487 template <
typename Body >
1503 #if __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES && __TBB_CPP11_PRESENT 1504 template <
typename Body>
1509 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET 1510 template <
typename Body,
typename... Args>
1514 make_edges_in_order(nodes, *
this);
1517 #if __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES 1518 template <
typename Body,
typename... Args>
1519 continue_node(
const node_set<Args...>& nodes,
int number_of_predecessors,
1527 graph_node(src.my_graph), input_impl_type(src),
1534 #if TBB_PREVIEW_FLOW_GRAPH_TRACE 1540 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION 1542 input_impl_type::my_built_predecessors.receiver_extract(*
this);
1551 using input_impl_type::try_put_task;
1555 input_impl_type::reset_receiver(f);
1562 template <
typename T>
1569 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION 1575 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION 1576 internal::edge_container<predecessor_type> my_built_predecessors;
1587 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET 1588 template <
typename... Args>
1589 broadcast_node(
const node_set<Args...>& nodes) : broadcast_node(nodes.
graph_reference()) {
1590 make_edges_in_order(nodes, *
this);
1603 #if TBB_PREVIEW_FLOW_GRAPH_TRACE 1621 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION 1624 built_successors_type &built_successors()
__TBB_override {
return my_successors.built_successors(); }
1626 void internal_add_built_successor(successor_type &r)
__TBB_override {
1627 my_successors.internal_add_built_successor(r);
1630 void internal_delete_built_successor(successor_type &r)
__TBB_override {
1631 my_successors.internal_delete_built_successor(r);
1635 return my_successors.successor_count();
1639 my_successors.copy_successors(v);
1644 built_predecessors_type &built_predecessors()
__TBB_override {
return my_built_predecessors; }
1646 void internal_add_built_predecessor( predecessor_type &p)
__TBB_override {
1648 my_built_predecessors.add_edge(p);
1653 my_built_predecessors.delete_edge(p);
1658 return my_built_predecessors.edge_count();
1661 void copy_predecessors(predecessor_list_type &v)
__TBB_override {
1663 my_built_predecessors.copy_edges(v);
1667 my_built_predecessors.receiver_extract(*
this);
1668 my_successors.built_successors().sender_extract(*
this);
1690 if (f&rf_clear_edges) {
1691 my_successors.
clear();
1692 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION 1693 my_built_predecessors.clear();
1696 __TBB_ASSERT(!(f & rf_clear_edges) || my_successors.
empty(),
"Error resetting broadcast_node");
1701 template <
typename T,
typename A=cache_aligned_allocator<T> >
1704 typedef T input_type;
1709 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION 1717 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION 1718 internal::edge_container<predecessor_type> my_built_predecessors;
1723 enum op_type {reg_succ, rem_succ, req_item, res_item, rel_res, con_res, put_item, try_fwd_task
1724 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION 1725 , add_blt_succ, del_blt_succ,
1726 add_blt_pred, del_blt_pred,
1727 blt_succ_cnt, blt_pred_cnt,
1728 blt_succ_cpy, blt_pred_cpy
1736 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION 1741 predecessor_type *
p;
1743 successor_list_type *svec;
1744 predecessor_list_type *pvec;
1751 buffer_operation(
const T& e,
op_type t) : type(char(t))
1753 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
1754 , ltask(NULL), elem(const_cast<T*>(&e))
1756 , elem(const_cast<T*>(&e)) , ltask(NULL)
1759 buffer_operation(
op_type t) : type(char(t)), ltask(NULL) {}
1763 typedef internal::aggregating_functor<class_type, buffer_operation>
handler_type;
1768 handle_operations_impl(op_list,
this);
1771 template<
typename derived_type>
1772 void handle_operations_impl(buffer_operation *op_list, derived_type* derived) {
1773 __TBB_ASSERT(static_cast<class_type*>(derived) ==
this,
"'this' is not a base class for derived");
1775 buffer_operation *tmp = NULL;
1776 bool try_forwarding =
false;
1779 op_list = op_list->next;
1780 switch (tmp->type) {
1781 case reg_succ: internal_reg_succ(tmp); try_forwarding =
true;
break;
1782 case rem_succ: internal_rem_succ(tmp);
break;
1783 case req_item: internal_pop(tmp);
break;
1784 case res_item: internal_reserve(tmp);
break;
1785 case rel_res: internal_release(tmp); try_forwarding =
true;
break;
1786 case con_res: internal_consume(tmp); try_forwarding =
true;
break;
1787 case put_item: try_forwarding = internal_push(tmp);
break;
1788 case try_fwd_task: internal_forward_task(tmp);
break;
1789 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION 1791 case add_blt_succ: internal_add_built_succ(tmp);
break;
1792 case del_blt_succ: internal_del_built_succ(tmp);
break;
1793 case add_blt_pred: internal_add_built_pred(tmp);
break;
1794 case del_blt_pred: internal_del_built_pred(tmp);
break;
1795 case blt_succ_cnt: internal_succ_cnt(tmp);
break;
1796 case blt_pred_cnt: internal_pred_cnt(tmp);
break;
1797 case blt_succ_cpy: internal_copy_succs(tmp);
break;
1798 case blt_pred_cpy: internal_copy_preds(tmp);
break;
1805 if (try_forwarding && !forwarder_busy) {
1807 forwarder_busy =
true;
1808 task *new_task =
new(task::allocate_additional_child_of(*(this->my_graph.root_task())))
internal::
1825 inline bool enqueue_forwarding_task(buffer_operation &op_data) {
1826 task *ft = grab_forwarding_task(op_data);
1837 task *last_task = NULL;
1840 op_data.
ltask = NULL;
1841 my_aggregator.
execute(&op_data);
1858 virtual void internal_rem_succ(buffer_operation *op) {
1863 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION 1866 built_successors_type &built_successors()
__TBB_override {
return my_successors.built_successors(); }
1868 virtual void internal_add_built_succ(buffer_operation *op) {
1869 my_successors.internal_add_built_successor(*(op->r));
1873 virtual void internal_del_built_succ(buffer_operation *op) {
1874 my_successors.internal_delete_built_successor(*(op->r));
1880 built_predecessors_type &built_predecessors()
__TBB_override {
return my_built_predecessors; }
1882 virtual void internal_add_built_pred(buffer_operation *op) {
1883 my_built_predecessors.add_edge(*(op->p));
1887 virtual void internal_del_built_pred(buffer_operation *op) {
1888 my_built_predecessors.delete_edge(*(op->p));
1892 virtual void internal_succ_cnt(buffer_operation *op) {
1893 op->cnt_val = my_successors.successor_count();
1897 virtual void internal_pred_cnt(buffer_operation *op) {
1898 op->cnt_val = my_built_predecessors.edge_count();
1902 virtual void internal_copy_succs(buffer_operation *op) {
1903 my_successors.copy_successors(*(op->svec));
1907 virtual void internal_copy_preds(buffer_operation *op) {
1908 my_built_predecessors.copy_edges(*(op->pvec));
1918 return this->my_item_valid(this->my_tail - 1);
1925 graph& g = this->my_graph;
1927 this->destroy_back();
1933 virtual void internal_forward_task(buffer_operation *op) {
1934 internal_forward_task_impl(op,
this);
1937 template<
typename derived_type>
1938 void internal_forward_task_impl(buffer_operation *op, derived_type* derived) {
1939 __TBB_ASSERT(static_cast<class_type*>(derived) ==
this,
"'this' is not a base class for derived");
1941 if (this->my_reserved || !derived->is_item_valid()) {
1943 this->forwarder_busy =
false;
1948 size_type counter = my_successors.
size();
1949 for (; counter > 0 && derived->is_item_valid(); --counter)
1950 derived->try_put_and_add_task(last_task);
1952 op->ltask = last_task;
1953 if (last_task && !counter) {
1958 forwarder_busy =
false;
1963 this->push_back(*(op->
elem));
1969 if(this->pop_back(*(op->
elem))) {
1978 if(this->reserve_front(*(op->
elem))) {
1987 this->consume_front();
1992 this->release_front();
1999 forwarder_busy(false) {
2001 my_aggregator.initialize_handler(handler_type(
this));
2006 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET 2007 template <
typename... Args>
2008 buffer_node(
const node_set<Args...>& nodes) : buffer_node(nodes.graph_reference()) {
2009 make_edges_in_order(nodes, *
this);
2016 forwarder_busy =
false;
2018 my_aggregator.initialize_handler(handler_type(
this));
2023 #if TBB_PREVIEW_FLOW_GRAPH_TRACE 2038 my_aggregator.execute(&op_data);
2039 (
void)enqueue_forwarding_task(op_data);
2043 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION 2044 void internal_add_built_successor( successor_type &r)
__TBB_override {
2047 my_aggregator.execute(&op_data);
2050 void internal_delete_built_successor( successor_type &r)
__TBB_override {
2053 my_aggregator.execute(&op_data);
2056 void internal_add_built_predecessor( predecessor_type &p)
__TBB_override {
2059 my_aggregator.execute(&op_data);
2062 void internal_delete_built_predecessor( predecessor_type &p)
__TBB_override {
2065 my_aggregator.execute(&op_data);
2070 my_aggregator.execute(&op_data);
2071 return op_data.cnt_val;
2076 my_aggregator.execute(&op_data);
2077 return op_data.cnt_val;
2080 void copy_predecessors( predecessor_list_type &v )
__TBB_override {
2083 my_aggregator.execute(&op_data);
2089 my_aggregator.execute(&op_data);
2101 my_aggregator.execute(&op_data);
2105 (
void)enqueue_forwarding_task(op_data);
2115 my_aggregator.execute(&op_data);
2116 (
void)enqueue_forwarding_task(op_data);
2126 my_aggregator.execute(&op_data);
2127 (
void)enqueue_forwarding_task(op_data);
2135 my_aggregator.execute(&op_data);
2136 (
void)enqueue_forwarding_task(op_data);
2144 my_aggregator.execute(&op_data);
2145 (
void)enqueue_forwarding_task(op_data);
2157 my_aggregator.execute(&op_data);
2158 task *ft = grab_forwarding_task(op_data);
2180 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION 2183 my_built_predecessors.receiver_extract(*
this);
2184 my_successors.built_successors().sender_extract(*
this);
2192 if (f&rf_clear_edges) {
2193 my_successors.
clear();
2194 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION 2195 my_built_predecessors.clear();
2198 forwarder_busy =
false;
2203 template <
typename T,
typename A=cache_aligned_allocator<T> >
2215 return this->my_item_valid(this->my_head);
2224 this->destroy_front();
2230 this->internal_forward_task_impl(op,
this);
2234 if ( this->my_reserved || !this->my_item_valid(this->my_head)){
2238 this->pop_front(*(op->elem));
2243 if (this->my_reserved || !this->my_item_valid(this->my_head)) {
2247 this->reserve_front(*(op->elem));
2252 this->consume_front();
2269 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET 2270 template <
typename... Args>
2271 queue_node(
const node_set<Args...>& nodes) : queue_node(nodes.graph_reference()) {
2272 make_edges_in_order(nodes, *
this);
2283 #if TBB_PREVIEW_FLOW_GRAPH_TRACE 2291 base_type::reset_node(f);
2296 template<
typename T,
typename A=cache_aligned_allocator<T> >
2308 template<
typename Sequencer >
2310 my_sequencer(new
internal::function_body_leaf< T, size_t, Sequencer>(s) ) {
2316 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET 2317 template <
typename Sequencer,
typename... Args>
2318 sequencer_node(
const node_set<Args...>& nodes,
const Sequencer& s)
2319 : sequencer_node(nodes.graph_reference(),
s) {
2320 make_edges_in_order(nodes, *
this);
2326 my_sequencer( src.my_sequencer->clone() ) {
2335 #if TBB_PREVIEW_FLOW_GRAPH_TRACE 2347 size_type tag = (*my_sequencer)(*(op->elem));
2348 #if !TBB_DEPRECATED_SEQUENCER_DUPLICATES 2349 if (tag < this->my_head) {
2356 size_t new_tail = (tag+1 > this->my_tail) ? tag+1 : this->my_tail;
2358 if (this->
size(new_tail) > this->capacity()) {
2359 this->grow_my_array(this->
size(new_tail));
2361 this->my_tail = new_tail;
2370 template<
typename T,
typename Compare = std::less<T>,
typename A=cache_aligned_allocator<T> >
2388 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET 2389 template <
typename... Args>
2391 : priority_queue_node(nodes.graph_reference(), comp) {
2392 make_edges_in_order(nodes, *
this);
2403 #if TBB_PREVIEW_FLOW_GRAPH_TRACE 2413 base_type::reset_node(f);
2422 this->internal_forward_task_impl(op,
this);
2426 this->handle_operations_impl(op_list,
this);
2430 prio_push(*(op->elem));
2437 if ( this->my_reserved ==
true || this->my_tail == 0 ) {
2442 *(op->elem) = prio();
2450 if (this->my_reserved ==
true || this->my_tail == 0) {
2454 this->my_reserved =
true;
2455 *(op->elem) = prio();
2456 reserved_item = *(op->elem);
2463 this->my_reserved =
false;
2464 reserved_item = input_type();
2469 prio_push(reserved_item);
2470 this->my_reserved =
false;
2471 reserved_item = input_type();
2478 if (mark < this->my_tail) heapify();
2479 __TBB_ASSERT(mark == this->my_tail,
"mark unequal after heapify");
2483 return this->my_tail > 0;
2504 __TBB_ASSERT(mark <= this->my_tail,
"mark outside bounds before test");
2505 return mark < this->my_tail && compare(this->get_my_item(0), this->get_my_item(this->my_tail - 1));
2510 if ( this->my_tail >= this->my_array_size )
2511 this->grow_my_array( this->my_tail + 1 );
2512 (
void) this->place_item(this->my_tail, src);
2514 __TBB_ASSERT(mark < this->my_tail,
"mark outside bounds after push");
2521 if (prio_use_tail()) {
2524 this->destroy_item(this->my_tail-1);
2526 __TBB_ASSERT(mark <= this->my_tail,
"mark outside bounds after pop");
2529 this->destroy_item(0);
2530 if(this->my_tail > 1) {
2532 __TBB_ASSERT(this->my_item_valid(this->my_tail - 1), NULL);
2533 this->move_item(0,this->my_tail - 1);
2536 if(mark > this->my_tail) --mark;
2537 if (this->my_tail > 1)
2539 __TBB_ASSERT(mark <= this->my_tail,
"mark outside bounds after pop");
2543 return this->get_my_item(prio_use_tail() ? this->my_tail-1 : 0);
2548 if(this->my_tail == 0) {
2552 if (!mark) mark = 1;
2553 for (; mark<this->my_tail; ++mark) {
2554 size_type cur_pos = mark;
2555 input_type to_place;
2556 this->fetch_item(mark,to_place);
2558 size_type
parent = (cur_pos-1)>>1;
2559 if (!compare(this->get_my_item(parent), to_place))
2561 this->move_item(cur_pos, parent);
2564 (
void) this->place_item(cur_pos, to_place);
2570 size_type cur_pos=0, child=1;
2571 while (child < mark) {
2572 size_type target = child;
2574 compare(this->get_my_item(child),
2575 this->get_my_item(child+1)))
2578 if (compare(this->get_my_item(target),
2579 this->get_my_item(cur_pos)))
2582 this->swap_items(cur_pos, target);
2584 child = (cur_pos<<1)+1;
2591 namespace interface11 {
2597 template<
typename T,
typename DecrementType=continue_msg >
2604 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION 2627 return ( my_count + my_tries < my_threshold && !my_predecessors.
empty() && !my_successors.
empty() );
2634 bool reserved =
false;
2637 if ( check_conditions() )
2654 if ( check_conditions() ) {
2656 task *rtask =
new ( task::allocate_additional_child_of( *(this->my_graph.root_task()) ) )
2672 if ( check_conditions() ) {
2674 task *rtask =
new ( task::allocate_additional_child_of( *(this->my_graph.root_task()) ) )
2692 if( delta > 0 &&
size_t(delta) > my_count )
2694 else if( delta < 0 &&
size_t(delta) > my_threshold - my_count )
2695 my_count = my_threshold;
2697 my_count -= size_t(delta);
2699 return forward_task();
2705 decrement.set_owner(
this);
2707 CODEPTR(), tbb::internal::FLOW_LIMITER_NODE, &this->my_graph,
2716 #if TBB_DEPRECATED_LIMITER_NODE_CONSTRUCTOR 2718 "Deprecated interface of the limiter node can be used only in conjunction " 2719 "with continue_msg as the type of DecrementType template parameter." );
2720 #endif // Check for incompatible interface 2725 :
graph_node(g), my_threshold(threshold), my_count(0),
2727 my_tries(0), decrement(),
2728 init_decrement_predecessors(num_decrement_predecessors),
2729 decrement(num_decrement_predecessors)) {
2733 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET 2734 template <
typename... Args>
2735 limiter_node(
const node_set<Args...>& nodes,
size_t threshold)
2736 : limiter_node(nodes.graph_reference(), threshold) {
2737 make_edges_in_order(nodes, *
this);
2744 my_threshold(src.my_threshold), my_count(0),
2746 my_tries(0), decrement(),
2747 init_decrement_predecessors(src.init_decrement_predecessors),
2748 decrement(src.init_decrement_predecessors)) {
2752 #if TBB_PREVIEW_FLOW_GRAPH_TRACE 2761 bool was_empty = my_successors.
empty();
2764 if ( was_empty && !my_predecessors.
empty() && my_count + my_tries < my_threshold ) {
2766 task*
task =
new ( task::allocate_additional_child_of( *(this->my_graph.root_task()) ) )
2777 r.remove_predecessor(*
this);
2782 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION 2783 built_successors_type &built_successors()
__TBB_override {
return my_successors.built_successors(); }
2784 built_predecessors_type &built_predecessors()
__TBB_override {
return my_predecessors.built_predecessors(); }
2786 void internal_add_built_successor(successor_type &src)
__TBB_override {
2787 my_successors.internal_add_built_successor(src);
2790 void internal_delete_built_successor(successor_type &src)
__TBB_override {
2791 my_successors.internal_delete_built_successor(src);
2794 size_t successor_count()
__TBB_override {
return my_successors.successor_count(); }
2797 my_successors.copy_successors(v);
2800 void internal_add_built_predecessor(predecessor_type &src)
__TBB_override {
2801 my_predecessors.internal_add_built_predecessor(src);
2804 void internal_delete_built_predecessor(predecessor_type &src)
__TBB_override {
2805 my_predecessors.internal_delete_built_predecessor(src);
2808 size_t predecessor_count()
__TBB_override {
return my_predecessors.predecessor_count(); }
2810 void copy_predecessors(predecessor_list_type &v)
__TBB_override {
2811 my_predecessors.copy_predecessors(v);
2816 my_successors.built_successors().sender_extract(*
this);
2817 my_predecessors.built_predecessors().receiver_extract(*
this);
2818 decrement.built_predecessors().receiver_extract(decrement);
2825 my_predecessors.
add( src );
2827 task*
task =
new ( task::allocate_additional_child_of( *(this->my_graph.root_task()) ) )
2836 my_predecessors.
remove( src );
2849 if ( my_count + my_tries >= my_threshold )
2861 rtask =
new ( task::allocate_additional_child_of( *(this->my_graph.root_task()) ) )
2881 if(f & rf_clear_edges) {
2882 my_predecessors.
clear();
2883 my_successors.
clear();
2887 my_predecessors.
reset( );
2889 decrement.reset_receiver(f);
2901 template<
typename OutputTuple,
typename JP=queueing>
class join_node;
2903 template<
typename OutputTuple>
2912 tbb::internal::fgt_multiinput_node<N>(
CODEPTR(), tbb::internal::FLOW_JOIN_NODE_RESERVING, &this->my_graph,
2916 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET 2917 template <
typename... Args>
2919 make_edges_in_order(nodes, *
this);
2924 tbb::internal::fgt_multiinput_node<N>(
CODEPTR(), tbb::internal::FLOW_JOIN_NODE_RESERVING, &this->my_graph,
2928 #if TBB_PREVIEW_FLOW_GRAPH_TRACE 2936 template<
typename OutputTuple>
2945 tbb::internal::fgt_multiinput_node<N>(
CODEPTR(), tbb::internal::FLOW_JOIN_NODE_QUEUEING, &this->my_graph,
2949 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET 2950 template <
typename... Args>
2952 make_edges_in_order(nodes, *
this);
2957 tbb::internal::fgt_multiinput_node<N>(
CODEPTR(), tbb::internal::FLOW_JOIN_NODE_QUEUEING, &this->my_graph,
2961 #if TBB_PREVIEW_FLOW_GRAPH_TRACE 2971 template<
typename OutputTuple,
typename K,
typename KHash>
2973 key_matching_port, OutputTuple, key_matching<K,KHash> > {
2981 #if __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING 2984 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET 2985 template <
typename... Args>
2987 : join_node(nodes.graph_reference()) {
2988 make_edges_in_order(nodes, *
this);
2994 template<
typename __TBB_B0,
typename __TBB_B1>
2996 tbb::internal::fgt_multiinput_node<N>(
CODEPTR(), tbb::internal::FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph,
2999 template<
typename __TBB_B0,
typename __TBB_B1,
typename __TBB_B2>
3001 tbb::internal::fgt_multiinput_node<N>(
CODEPTR(), tbb::internal::FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph,
3004 template<
typename __TBB_B0,
typename __TBB_B1,
typename __TBB_B2,
typename __TBB_B3>
3006 tbb::internal::fgt_multiinput_node<N>(
CODEPTR(), tbb::internal::FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph,
3009 template<
typename __TBB_B0,
typename __TBB_B1,
typename __TBB_B2,
typename __TBB_B3,
typename __TBB_B4>
3011 unfolded_type(g, b0, b1, b2, b3, b4) {
3012 tbb::internal::fgt_multiinput_node<N>(
CODEPTR(), tbb::internal::FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph,
3015 #if __TBB_VARIADIC_MAX >= 6 3016 template<
typename __TBB_B0,
typename __TBB_B1,
typename __TBB_B2,
typename __TBB_B3,
typename __TBB_B4,
3019 unfolded_type(g, b0, b1, b2, b3, b4, b5) {
3020 tbb::internal::fgt_multiinput_node<N>(
CODEPTR(), tbb::internal::FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph,
3024 #if __TBB_VARIADIC_MAX >= 7 3025 template<
typename __TBB_B0,
typename __TBB_B1,
typename __TBB_B2,
typename __TBB_B3,
typename __TBB_B4,
3026 typename __TBB_B5,
typename __TBB_B6>
3028 unfolded_type(g, b0, b1, b2, b3, b4, b5, b6) {
3029 tbb::internal::fgt_multiinput_node<N>(
CODEPTR(), tbb::internal::FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph,
3033 #if __TBB_VARIADIC_MAX >= 8 3034 template<
typename __TBB_B0,
typename __TBB_B1,
typename __TBB_B2,
typename __TBB_B3,
typename __TBB_B4,
3035 typename __TBB_B5,
typename __TBB_B6,
typename __TBB_B7>
3037 __TBB_B7 b7) : unfolded_type(g, b0, b1, b2, b3, b4, b5, b6, b7) {
3038 tbb::internal::fgt_multiinput_node<N>(
CODEPTR(), tbb::internal::FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph,
3042 #if __TBB_VARIADIC_MAX >= 9 3043 template<
typename __TBB_B0,
typename __TBB_B1,
typename __TBB_B2,
typename __TBB_B3,
typename __TBB_B4,
3044 typename __TBB_B5,
typename __TBB_B6,
typename __TBB_B7,
typename __TBB_B8>
3046 __TBB_B7 b7, __TBB_B8 b8) : unfolded_type(g, b0, b1, b2, b3, b4, b5, b6, b7, b8) {
3047 tbb::internal::fgt_multiinput_node<N>(
CODEPTR(), tbb::internal::FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph,
3051 #if __TBB_VARIADIC_MAX >= 10 3052 template<
typename __TBB_B0,
typename __TBB_B1,
typename __TBB_B2,
typename __TBB_B3,
typename __TBB_B4,
3053 typename __TBB_B5,
typename __TBB_B6,
typename __TBB_B7,
typename __TBB_B8,
typename __TBB_B9>
3055 __TBB_B7 b7, __TBB_B8 b8, __TBB_B9 b9) : unfolded_type(g, b0, b1, b2, b3, b4, b5, b6, b7, b8, b9) {
3056 tbb::internal::fgt_multiinput_node<N>(
CODEPTR(), tbb::internal::FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph,
3061 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET 3062 template <
typename... Args,
typename... Bodies>
3064 : join_node(nodes.graph_reference(), bodies...) {
3065 make_edges_in_order(nodes, *
this);
3070 tbb::internal::fgt_multiinput_node<N>(
CODEPTR(), tbb::internal::FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph,
3074 #if TBB_PREVIEW_FLOW_GRAPH_TRACE 3091 template<
typename T0>
3094 static const int N = 1;
3100 tbb::internal::fgt_multiinput_node<N>(
CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
3104 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET 3105 template <
typename... Args>
3106 indexer_node(
const node_set<Args...>& nodes) : indexer_node(nodes.graph_reference()) {
3107 make_edges_in_order(nodes, *
this);
3113 tbb::internal::fgt_multiinput_node<N>(
CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
3117 #if TBB_PREVIEW_FLOW_GRAPH_TRACE 3124 template<
typename T0,
typename T1>
3127 static const int N = 2;
3133 tbb::internal::fgt_multiinput_node<N>(
CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
3137 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET 3138 template <
typename... Args>
3139 indexer_node(
const node_set<Args...>& nodes) : indexer_node(nodes.graph_reference()) {
3140 make_edges_in_order(nodes, *
this);
3146 tbb::internal::fgt_multiinput_node<N>(
CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
3150 #if TBB_PREVIEW_FLOW_GRAPH_TRACE 3157 template<
typename T0,
typename T1,
typename T2>
3160 static const int N = 3;
3166 tbb::internal::fgt_multiinput_node<N>(
CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
3170 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET 3171 template <
typename... Args>
3172 indexer_node(
const node_set<Args...>& nodes) : indexer_node(nodes.graph_reference()) {
3173 make_edges_in_order(nodes, *
this);
3179 tbb::internal::fgt_multiinput_node<N>(
CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
3183 #if TBB_PREVIEW_FLOW_GRAPH_TRACE 3190 template<
typename T0,
typename T1,
typename T2,
typename T3>
3193 static const int N = 4;
3199 tbb::internal::fgt_multiinput_node<N>(
CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
3203 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET 3204 template <
typename... Args>
3205 indexer_node(
const node_set<Args...>& nodes) : indexer_node(nodes.graph_reference()) {
3206 make_edges_in_order(nodes, *
this);
3212 tbb::internal::fgt_multiinput_node<N>(
CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
3216 #if TBB_PREVIEW_FLOW_GRAPH_TRACE 3223 template<
typename T0,
typename T1,
typename T2,
typename T3,
typename T4>
3226 static const int N = 5;
3232 tbb::internal::fgt_multiinput_node<N>(
CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
3236 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET 3237 template <
typename... Args>
3238 indexer_node(
const node_set<Args...>& nodes) : indexer_node(nodes.graph_reference()) {
3239 make_edges_in_order(nodes, *
this);
3245 tbb::internal::fgt_multiinput_node<N>(
CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
3249 #if TBB_PREVIEW_FLOW_GRAPH_TRACE 3256 #if __TBB_VARIADIC_MAX >= 6 3257 template<
typename T0,
typename T1,
typename T2,
typename T3,
typename T4,
typename T5>
3258 class indexer_node<T0, T1, T2, T3, T4, T5> :
public internal::unfolded_indexer_node<tuple<T0, T1, T2, T3, T4, T5> > {
3260 static const int N = 6;
3266 tbb::internal::fgt_multiinput_node<N>(
CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
3270 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET 3271 template <
typename... Args>
3272 indexer_node(
const node_set<Args...>& nodes) : indexer_node(nodes.graph_reference()) {
3273 make_edges_in_order(nodes, *
this);
3279 tbb::internal::fgt_multiinput_node<N>(
CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
3283 #if TBB_PREVIEW_FLOW_GRAPH_TRACE 3289 #endif //variadic max 6 3291 #if __TBB_VARIADIC_MAX >= 7 3292 template<
typename T0,
typename T1,
typename T2,
typename T3,
typename T4,
typename T5,
3294 class indexer_node<T0, T1, T2, T3, T4, T5, T6> :
public internal::unfolded_indexer_node<tuple<T0, T1, T2, T3, T4, T5, T6> > {
3296 static const int N = 7;
3302 tbb::internal::fgt_multiinput_node<N>(
CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
3306 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET 3307 template <
typename... Args>
3308 indexer_node(
const node_set<Args...>& nodes) : indexer_node(nodes.graph_reference()) {
3309 make_edges_in_order(nodes, *
this);
3315 tbb::internal::fgt_multiinput_node<N>(
CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
3319 #if TBB_PREVIEW_FLOW_GRAPH_TRACE 3325 #endif //variadic max 7 3327 #if __TBB_VARIADIC_MAX >= 8 3328 template<
typename T0,
typename T1,
typename T2,
typename T3,
typename T4,
typename T5,
3329 typename T6,
typename T7>
3330 class indexer_node<T0, T1, T2, T3, T4, T5, T6, T7> :
public internal::unfolded_indexer_node<tuple<T0, T1, T2, T3, T4, T5, T6, T7> > {
3332 static const int N = 8;
3338 tbb::internal::fgt_multiinput_node<N>(
CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
3342 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET 3343 template <
typename... Args>
3344 indexer_node(
const node_set<Args...>& nodes) : indexer_node(nodes.graph_reference()) {
3345 make_edges_in_order(nodes, *
this);
3351 tbb::internal::fgt_multiinput_node<N>(
CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
3355 #if TBB_PREVIEW_FLOW_GRAPH_TRACE 3361 #endif //variadic max 8 3363 #if __TBB_VARIADIC_MAX >= 9 3364 template<
typename T0,
typename T1,
typename T2,
typename T3,
typename T4,
typename T5,
3365 typename T6,
typename T7,
typename T8>
3366 class indexer_node<T0, T1, T2, T3, T4, T5, T6, T7, T8> :
public internal::unfolded_indexer_node<tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8> > {
3368 static const int N = 9;
3374 tbb::internal::fgt_multiinput_node<N>(
CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
3378 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET 3379 template <
typename... Args>
3380 indexer_node(
const node_set<Args...>& nodes) : indexer_node(nodes.graph_reference()) {
3381 make_edges_in_order(nodes, *
this);
3387 tbb::internal::fgt_multiinput_node<N>(
CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
3391 #if TBB_PREVIEW_FLOW_GRAPH_TRACE 3397 #endif //variadic max 9 3399 #if __TBB_VARIADIC_MAX >= 10 3400 template<
typename T0,
typename T1,
typename T2,
typename T3,
typename T4,
typename T5,
3401 typename T6,
typename T7,
typename T8,
typename T9>
3404 static const int N = 10;
3406 typedef tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>
InputTuple;
3407 typedef typename internal::tagged_msg<size_t, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> output_type;
3410 tbb::internal::fgt_multiinput_node<N>(
CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
3414 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET 3415 template <
typename... Args>
3416 indexer_node(
const node_set<Args...>& nodes) : indexer_node(nodes.graph_reference()) {
3417 make_edges_in_order(nodes, *
this);
3423 tbb::internal::fgt_multiinput_node<N>(
CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
3427 #if TBB_PREVIEW_FLOW_GRAPH_TRACE 3433 #endif //variadic max 10 3435 #if __TBB_PREVIEW_ASYNC_MSG 3438 template<
typename T >
3441 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION 3442 s.internal_add_built_predecessor(p);
3443 p.internal_add_built_successor(s);
3450 template<
typename T >
3455 #if __TBB_PREVIEW_ASYNC_MSG 3456 template<
typename TS,
typename TR,
3463 template<
typename T >
3468 template<
typename T >
3473 #endif // __TBB_PREVIEW_ASYNC_MSG 3475 #if __TBB_FLOW_GRAPH_CPP11_FEATURES 3477 template<
typename T,
typename V,
3478 typename =
typename T::output_ports_type,
typename =
typename V::input_ports_type >
3480 make_edge(get<0>(output.output_ports()), get<0>(input.input_ports()));
3484 template<
typename T,
typename R,
3485 typename =
typename T::output_ports_type >
3487 make_edge(get<0>(output.output_ports()), input);
3491 template<
typename S,
typename V,
3492 typename =
typename V::input_ports_type >
3494 make_edge(output, get<0>(input.input_ports()));
3498 #if __TBB_PREVIEW_ASYNC_MSG 3501 template<
typename T >
3505 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION 3507 p.internal_delete_built_successor(s);
3508 s.internal_delete_built_predecessor(p);
3514 template<
typename T >
3519 #if __TBB_PREVIEW_ASYNC_MSG 3520 template<
typename TS,
typename TR,
3527 template<
typename T >
3532 template<
typename T >
3536 #endif // __TBB_PREVIEW_ASYNC_MSG 3538 #if __TBB_FLOW_GRAPH_CPP11_FEATURES 3540 template<
typename T,
typename V,
3541 typename =
typename T::output_ports_type,
typename =
typename V::input_ports_type >
3543 remove_edge(get<0>(output.output_ports()), get<0>(input.input_ports()));
3547 template<
typename T,
typename R,
3548 typename =
typename T::output_ports_type >
3550 remove_edge(get<0>(output.output_ports()), input);
3553 template<
typename S,
typename V,
3554 typename =
typename V::input_ports_type >
3560 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION 3561 template<
typename C >
3562 template<
typename S >
3563 void internal::edge_container<C>::sender_extract(
S &s ) {
3564 edge_list_type e = built_edges;
3565 for (
typename edge_list_type::iterator i = e.begin(); i != e.end(); ++i ) {
3570 template<
typename C >
3571 template<
typename R >
3572 void internal::edge_container<C>::receiver_extract( R &r ) {
3573 edge_list_type e = built_edges;
3574 for (
typename edge_list_type::iterator i = e.begin(); i != e.end(); ++i ) {
3581 template<
typename Body,
typename Node >
3583 return n.template copy_function_object<Body>();
3586 #if __TBB_FLOW_GRAPH_CPP11_FEATURES 3591 template<
typename... InputTypes,
typename... OutputTypes>
3602 static const size_t NUM_INPUTS =
sizeof...(InputTypes);
3603 static const size_t NUM_OUTPUTS =
sizeof...(OutputTypes);
3609 #if TBB_PREVIEW_FLOW_GRAPH_TRACE 3620 template<
typename T1,
typename T2>
3624 my_input_ports = tbb::internal::make_unique<input_ports_type>(std::forward<T1>(input_ports_tuple));
3625 my_output_ports = tbb::internal::make_unique<output_ports_type>(std::forward<T2>(output_ports_tuple));
3631 template<
typename... NodeTypes >
3634 template<
typename... NodeTypes >
3637 #if TBB_PREVIEW_FLOW_GRAPH_TRACE 3644 __TBB_ASSERT(my_input_ports,
"input ports not set, call set_external_ports to set input ports");
3645 return *my_input_ports;
3649 __TBB_ASSERT(my_output_ports,
"output ports not set, call set_external_ports to set output ports");
3650 return *my_output_ports;
3653 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION 3655 __TBB_ASSERT(
false,
"Current composite_node implementation does not support extract");
3661 template<
typename... InputTypes>
3668 static const size_t NUM_INPUTS =
sizeof...(InputTypes);
3674 #if TBB_PREVIEW_FLOW_GRAPH_TRACE 3685 template<
typename T>
3689 my_input_ports = tbb::internal::make_unique<input_ports_type>(std::forward<T>(input_ports_tuple));
3694 template<
typename... NodeTypes >
3697 template<
typename... NodeTypes >
3700 #if TBB_PREVIEW_FLOW_GRAPH_TRACE 3707 __TBB_ASSERT(my_input_ports,
"input ports not set, call set_external_ports to set input ports");
3708 return *my_input_ports;
3711 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION 3713 __TBB_ASSERT(
false,
"Current composite_node implementation does not support extract");
3720 template<
typename... OutputTypes>
3727 static const size_t NUM_OUTPUTS =
sizeof...(OutputTypes);
3733 #if TBB_PREVIEW_FLOW_GRAPH_TRACE 3744 template<
typename T>
3748 my_output_ports = tbb::internal::make_unique<output_ports_type>(std::forward<T>(output_ports_tuple));
3753 template<
typename... NodeTypes >
3756 template<
typename... NodeTypes >
3759 #if TBB_PREVIEW_FLOW_GRAPH_TRACE 3766 __TBB_ASSERT(my_output_ports,
"output ports not set, call set_external_ports to set output ports");
3767 return *my_output_ports;
3770 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION 3772 __TBB_ASSERT(
false,
"Current composite_node implementation does not support extract");
3778 #endif // __TBB_FLOW_GRAPH_CPP11_FEATURES 3782 template<
typename Gateway>
3789 my_gateway = gateway;
3796 template<
typename Input,
typename Ports,
typename Gateway,
typename Body>
3803 : base_type(gateway), my_body(body) { }
3806 my_body(v, *this->my_gateway);
3818 namespace interface11 {
3821 template <
typename Input,
typename Output,
3824 class async_node :
public multifunction_node< Input, tuple< Output >, Policy, Allocator >,
public sender< Output > {
3845 try_put_functor(output_port_type &p,
const Output &v) : port(&p), value(&v), result(false) { }
3847 result = port->
try_put(*value);
3856 my_node->my_graph.reserve_wait();
3860 my_node->my_graph.release_wait();
3866 return my_node->try_put_impl(i);
3884 "Return status is inconsistent with the method operation." );
3886 while( !tasks.
empty() ) {
3890 return is_at_least_one_put_successful;
3894 template<
typename Body>
3896 graph &g,
size_t concurrency,
3904 internal::async_body<Input, typename base_type::output_ports_type, gateway_type, Body>
3906 tbb::internal::fgt_multioutput_node_with_body<1>(
3907 CODEPTR(), tbb::internal::FLOW_ASYNC_NODE,
3909 this->output_ports(), this->my_body
3913 #if __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES && __TBB_CPP11_PRESENT 3914 template <
typename Body,
typename... Args>
3916 : async_node(g, concurrency, body, Policy(), priority) {}
3917 #endif // __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES 3919 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET 3920 template <
typename Body,
typename... Args>
3922 const node_set<Args...>& nodes,
size_t concurrency, Body body,
3925 make_edges_in_order(nodes, *
this);
3928 #if __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES 3929 template <
typename Body,
typename... Args>
3931 : async_node(nodes, concurrency, body, Policy(), priority) {}
3932 #endif // __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES 3933 #endif // __TBB_PREVIEW_FLOW_GRAPH_NODE_SET 3936 static_cast<async_body_base_type*
>(this->my_body->get_body_ptr())->set_gateway(&my_gateway);
3937 static_cast<async_body_base_type*
>(this->my_init_body->get_body_ptr())->set_gateway(&my_gateway);
3939 tbb::internal::fgt_multioutput_node_with_body<1>(
CODEPTR(), tbb::internal::FLOW_ASYNC_NODE,
3941 this->output_ports(), this->my_body );
3948 #if TBB_PREVIEW_FLOW_GRAPH_TRACE 3958 return internal::output_port<0>(*this).register_successor(r);
3963 return internal::output_port<0>(*this).remove_successor(r);
3966 template<
typename Body>
3970 mfn_body_type &body_ref = *this->my_body;
3975 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION 3976 typedef typename internal::edge_container<successor_type> built_successors_type;
3978 typedef typename built_successors_type::edge_list_type successor_list_type;
3980 return internal::output_port<0>(*this).built_successors();
3983 void internal_add_built_successor( successor_type &r )
__TBB_override {
3984 internal::output_port<0>(*this).internal_add_built_successor(r);
3987 void internal_delete_built_successor( successor_type &r )
__TBB_override {
3988 internal::output_port<0>(*this).internal_delete_built_successor(r);
3992 internal::output_port<0>(*this).copy_successors(l);
3996 return internal::output_port<0>(*this).successor_count();
4003 base_type::reset_node(f);
4007 #if __TBB_PREVIEW_STREAMING_NODE 4009 #endif // __TBB_PREVIEW_STREAMING_NODE 4013 template<
typename T >
4020 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION 4033 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET 4034 template <
typename... Args>
4035 overwrite_node(
const node_set<Args...>& nodes) : overwrite_node(nodes.graph_reference()) {
4036 make_edges_in_order(nodes, *
this);
4051 #if TBB_PREVIEW_FLOW_GRAPH_TRACE 4061 bool ret = s.
try_put( my_buffer );
4070 task *rtask =
new ( task::allocate_additional_child_of( *( my_graph.root_task() ) ) )
4087 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION 4088 built_predecessors_type &built_predecessors()
__TBB_override {
return my_built_predecessors; }
4089 built_successors_type &built_successors()
__TBB_override {
return my_successors.built_successors(); }
4091 void internal_add_built_successor( successor_type &s)
__TBB_override {
4093 my_successors.internal_add_built_successor(s);
4096 void internal_delete_built_successor( successor_type &s)
__TBB_override {
4098 my_successors.internal_delete_built_successor(s);
4103 return my_successors.successor_count();
4108 my_successors.copy_successors(v);
4111 void internal_add_built_predecessor( predecessor_type &p)
__TBB_override {
4113 my_built_predecessors.add_edge(p);
4116 void internal_delete_built_predecessor( predecessor_type &p)
__TBB_override {
4118 my_built_predecessors.delete_edge(p);
4123 return my_built_predecessors.edge_count();
4126 void copy_predecessors( predecessor_list_type &v )
__TBB_override {
4128 my_built_predecessors.copy_edges(v);
4132 my_buffer_is_valid =
false;
4133 built_successors().sender_extract(*
this);
4134 built_predecessors().receiver_extract(*
this);
4141 if ( my_buffer_is_valid ) {
4161 return my_buffer_is_valid;
4166 my_buffer_is_valid =
false;
4176 return try_put_task_impl(v);
4181 my_buffer_is_valid =
true;
4195 o(owner), s(succ) {};
4199 o.register_successor(s);
4204 predecessor_type&
o;
4210 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION 4211 internal::edge_container<predecessor_type> my_built_predecessors;
4218 my_buffer_is_valid =
false;
4219 if (f&rf_clear_edges) {
4220 my_successors.
clear();
4225 template<
typename T >
4241 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET 4242 template <
typename... Args>
4243 write_once_node(
const node_set<Args...>& nodes) : write_once_node(nodes.graph_reference()) {
4244 make_edges_in_order(nodes, *
this);
4255 #if TBB_PREVIEW_FLOW_GRAPH_TRACE 4267 return this->my_buffer_is_valid ? NULL : this->try_put_task_impl(v);
4300 using namespace interface11::internal::graph_policy_namespace;
4307 #if __TBB_FLOW_GRAPH_CPP11_FEATURES 4311 #if __TBB_PREVIEW_ASYNC_MSG 4314 #if __TBB_PREVIEW_STREAMING_NODE 4317 #endif // __TBB_PREVIEW_STREAMING_NODE 4318 #if __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES 4323 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET 4324 using interface11::internal::follows;
4325 using interface11::internal::precedes;
4326 using interface11::internal::make_node_set;
4327 using interface11::internal::make_edges;
4336 #undef __TBB_PFG_RESET_ARG 4340 #undef __TBB_flow_graph_H_include_area 4342 #if TBB_USE_THREADING_TOOLS && TBB_PREVIEW_FLOW_GRAPH_TRACE && ( __linux__ || __APPLE__ ) 4343 #undef __TBB_NOINLINE_SYM 4346 #endif // __TBB_flow_graph_H __TBB_NOINLINE_SYM indexer_node(const indexer_node &other)
static void alias_port(void *, PortsTuple &)
tuple< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9 > InputTuple
__TBB_NOINLINE_SYM join_node(const join_node &other)
__TBB_NOINLINE_SYM join_node(graph &g, __TBB_B0 b0, __TBB_B1 b1, __TBB_B2 b2, __TBB_B3 b3, __TBB_B4 b4)
void internal_consume(prio_operation *op) __TBB_override
virtual task * try_put_task(const T &t)=0
Put item to successor; return task to run the successor if possible.
virtual bool try_get(T &)
Request an item from the sender.
void reset_node(reset_flags f) __TBB_override
void prepare_task_arena(bool reinit=false)
__TBB_NOINLINE_SYM split_node(graph &g)
virtual source_body * clone()=0
sender< output_type >::successor_type successor_type
GraphNodeType & reference
internal::unfolded_join_node< N, reserving_port, OutputTuple, reserving > unfolded_type
virtual void internal_pop(buffer_operation *op)
__TBB_NOINLINE_SYM join_node(graph &g, __TBB_B0 b0, __TBB_B1 b1, __TBB_B2 b2, __TBB_B3 b3, __TBB_B4 b4, __TBB_B5 b5)
sender< output_type >::successor_type successor_type
void spawn_put()
Spawns a task that applies the body.
task * try_put_task(const X &t)
task_list_type my_reset_task_list
__TBB_NOINLINE_SYM broadcast_node(const broadcast_node &src)
__TBB_NOINLINE_SYM join_node(graph &g, __TBB_B0 b0, __TBB_B1 b1, __TBB_B2 b2, __TBB_B3 b3, __TBB_B4 b4, __TBB_B5 b5, __TBB_B6 b6)
internal::unfolded_indexer_node< InputTuple > unfolded_type
limiter_node(graph &g, __TBB_DEPRECATED_LIMITER_ARG2(size_t threshold, int num_decrement_predecessors=0))
Constructor.
async_body_base(gateway_type *gateway)
tbb::flow::tuple< sender< OutputTypes > &... > output_ports_type
__TBB_NOINLINE_SYM indexer_node(const indexer_node &other)
bool try_put(const typename internal::async_helpers< T >::filtered_type &t)
Put an item to the receiver.
task * try_put_task(const T &v) __TBB_override
Put item to successor; return task to run the successor if possible.
virtual void handle_operations(buffer_operation *op_list)
task * try_put_task_impl(const input_type &v)
tbb::flow::interface11::graph_iterator< const graph, const tbb::flow::interface11::graph_node > const_iterator
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 * lock
__TBB_NOINLINE_SYM indexer_node(graph &g)
task & pop_front()
Pop the front task from the list.
static void fgt_node(void *, string_index, void *, void *)
__TBB_NOINLINE_SYM join_node(const join_node &other)
receiver< input_type >::predecessor_type predecessor_type
internal::tagged_msg< size_t, T0, T1, T2, T3, T4, T5, T6, T7, T8 > output_type
static tbb::task *const SUCCESSFULLY_ENQUEUED
__TBB_NOINLINE_SYM indexer_node(graph &g)
Base class for user-defined tasks.
pointer operator->() const
Dereference.
internal::unfolded_indexer_node< InputTuple > unfolded_type
internal::unfolded_indexer_node< InputTuple > unfolded_type
#define __TBB_NOINLINE_SYM
sender< output_type >::successor_type successor_type
__TBB_NOINLINE_SYM join_node(graph &g, __TBB_B0 b0, __TBB_B1 b1)
Represents acquisition of a mutex.
void const char const char int ITT_FORMAT __itt_group_sync s
static task * try_put_task_wrapper_impl(receiver< T > *const this_recv, const void *p, bool is_async)
void reset_node(reset_flags f) __TBB_override
#define __TBB_STATIC_ASSERT(condition, msg)
static T & from_void_ptr(void *p)
A cache of successors that are broadcast to.
void enqueue_in_graph_arena(tbb::flow::interface10::graph &g, tbb::task &arena_task)
Enqueues a task inside graph arena.
void increment_ref_count()
Atomically increment reference count.
__TBB_NOINLINE_SYM multifunction_node(const multifunction_node &other)
virtual ~untyped_receiver()
Destructor.
void operator()(const Input &v, Ports &)
Forwards messages of type T to all successors.
virtual void internal_consume(buffer_operation *op)
bool try_get(input_type &v) __TBB_override
Request an item from the sender.
static void fgt_graph(void *)
The leaf for source_body.
Forwards messages only if the threshold has not been reached.
tbb::flow::tuple< receiver< InputTypes > &... > input_ports_type
tuple< T0, T1, T2 > InputTuple
base_type::size_type size_type
void add_task_to_graph_reset_list(tbb::flow::interface10::graph &g, tbb::task *tp)
implements a function node that supports Input -> (set of outputs)
void __TBB_EXPORTED_METHOD reset()
Forcefully reinitializes the context after the task tree it was associated with is completed...
const_iterator cbegin() const
start const iterator
internal::broadcast_cache< input_type > my_successors
Body copy_body(Node &n)
Returns a copy of the body from a function or continue node.
task * try_put_task(const X &t)
bool register_predecessor(predecessor_type &src) __TBB_override
Adds src to the list of cached predecessors.
internal::tagged_msg< size_t, T0, T1, T2, T3, T4, T5, T6 > output_type
static void * to_void_ptr(T &t)
buffer_node< T, A >::size_type size_type
sender< output_type >::successor_type successor_type
base_type::output_ports_type output_ports_type
tbb::flow::interface11::graph_node * my_nodes
__TBB_NOINLINE_SYM join_node(graph &g, __TBB_B0 b0, __TBB_B1 b1, __TBB_B2 b2, __TBB_B3 b3, __TBB_B4 b4, __TBB_B5 b5, __TBB_B6 b6, __TBB_B7 b7)
#define __TBB_FLOW_GRAPH_PRIORITY_EXPR(expr)
input_impl_type::predecessor_type predecessor_type
__TBB_NOINLINE_SYM join_node(graph &g, __TBB_B0 b0, __TBB_B1 b1, __TBB_B2 b2, __TBB_B3 b3, __TBB_B4 b4, __TBB_B5 b5, __TBB_B6 b6, __TBB_B7 b7, __TBB_B8 b8, __TBB_B9 b9)
void __TBB_store_with_release(volatile T &location, V value)
__TBB_DEPRECATED typedef continue_msg input_type
The input type.
void release_wait() __TBB_override
Inform a graph that a previous call to reserve_wait is no longer in effect.
__TBB_NOINLINE_SYM indexer_node(graph &g)
internal::tagged_msg< size_t, T0, T1 > output_type
bool try_consume() __TBB_override
Consumes a reserved item.
__TBB_NOINLINE_SYM indexer_node(graph &g)
#define __TBB_FLOW_GRAPH_PRIORITY_ARG1(arg1, priority)
void reset_receiver(reset_flags) __TBB_override
put receiver back in initial state
bool empty() const
True if list is empty; false otherwise.
Base class for types that should not be assigned.
void set_external_ports(T &&output_ports_tuple)
tuple< T0, T1, T2, T3, T4 > InputTuple
bool try_put(const Output &i) __TBB_override
Implements gateway_type::try_put for an external activity to submit a message to FG.
bool is_graph_active(tbb::flow::interface10::graph &g)
void set_ref_count(int count)
Set reference count.
__TBB_NOINLINE_SYM sequencer_node(graph &g, const Sequencer &s)
Constructor.
internal::tagged_msg< size_t, T0 > output_type
static void fgt_graph_desc(void *, const char *)
void try_put_and_add_task(task *&last_task)
static void fgt_end_body(void *)
untyped_receiver successor_type
The successor type for this node.
multifunction_node< Input, tuple< Output >, Policy, Allocator > base_type
#define __TBB_FLOW_GRAPH_PRIORITY_ARG0(priority)
item_buffer with reservable front-end. NOTE: if reserving, do not
try_put_functor(output_port_type &p, const Output &v)
bool remove_successor(successor_type &r) __TBB_override
Removes a successor from this node.
internal::round_robin_cache< T, null_rw_mutex > my_successors
concurrency
An enumeration the provides the two most common concurrency levels: unlimited and serial...
Forwards messages in priority order.
Implements methods for both executable and function nodes that puts Output to its successors...
#define __TBB_DEPRECATED_LIMITER_ARG2(arg1, arg2)
input_ports_type & input_ports()
const V & cast_to(T const &t)
internal::tagged_msg< size_t, T0, T1, T2, T3 > output_type
void set_external_ports(T &&input_ports_tuple)
bool register_successor(successor_type &r) __TBB_override
Adds a successor.
receiver< input_type >::predecessor_type predecessor_type
internal::broadcast_cache< T > my_successors
void call(F &&f, Pack &&p)
Calls the given function with arguments taken from a stored_pack.
bool try_release() __TBB_override
Release a reserved item.
int decrement_ref_count()
Atomically decrement reference count and returns its new value.
void register_node(tbb::flow::interface11::graph_node *n)
A cache of predecessors that only supports try_get.
__TBB_NOINLINE_SYM indexer_node(const indexer_node &other)
K key_from_message(const T &t)
A lock that occupies a single byte.
bool internal_push(sequencer_operation *op) __TBB_override
An abstract cache of successors.
static internal::allocate_root_proxy allocate_root()
Returns proxy for overloaded new that allocates a root task.
virtual void internal_reserve(buffer_operation *op)
Enables one or the other code branches.
internal::unfolded_indexer_node< InputTuple > unfolded_type
Implements an executable node that supports continue_msg -> Output.
Body copy_function_object()
__TBB_NOINLINE_SYM function_node(graph &g, size_t concurrency, __TBB_FLOW_GRAPH_PRIORITY_ARG1(Body body, node_priority_t priority=tbb::flow::internal::no_priority))
Constructor.
internal::continue_input< Output, Policy > input_impl_type
#define __TBB_DEPRECATED_LIMITER_ARG4(arg1, arg2, arg3, arg4)
void release_wait() __TBB_override
Deregisters an external entity that may have interacted with the graph.
__TBB_NOINLINE_SYM indexer_node(graph &g)
Pure virtual template class that defines a receiver of messages of type T.
__TBB_NOINLINE_SYM join_node(graph &g, __TBB_B0 b0, __TBB_B1 b1, __TBB_B2 b2, __TBB_B3 b3, __TBB_B4 b4, __TBB_B5 b5, __TBB_B6 b6, __TBB_B7 b7, __TBB_B8 b8)
limiter_node(const limiter_node &src)
Copy constructor.
void add_visible_nodes(const NodeTypes &... n)
Implements a function node that supports Input -> Output.
__TBB_NOINLINE_SYM queue_node(const queue_node &src)
Copy constructor.
static const void * to_void_ptr(const T &t)
bool try_reserve(T &v) __TBB_override
Reserves an item.
task * try_put_task(const T &t) __TBB_override
build a task to run the successor if possible. Default is old behavior.
internal::source_body< output_type > * my_init_body
bool try_reserve(T &v) __TBB_override
Reserves an item.
void internal_consume(queue_operation *op) __TBB_override
Detects whether two given types are the same.
graph & graph_reference() const
Implements methods for a function node that takes a type Input as input and sends.
virtual bool try_reserve_wrapper(void *p, bool is_async) __TBB_override
Base class for receivers of completion messages.
void try_put_and_add_task(task *&last_task)
output_ports_type my_output_ports
fOutput_type::successor_type successor_type
void internal_make_edge(internal::untyped_sender &p, internal::untyped_receiver &s)
unfolded_type::input_ports_type input_ports_type
static void fgt_release_wait(void *)
internal::function_output< output_type > fOutput_type
output_ports_type & output_ports()
__TBB_NOINLINE_SYM indexer_node(graph &g)
__TBB_NOINLINE_SYM async_node(const async_node &other)
receiver< TupleType > base_type
bool gather_successful_try_puts(const X &t, task_list &tasks)
receiver_gateway_impl(async_node *node)
virtual ~untyped_sender()
unfolded_join_node : passes input_ports_type to join_node_base. We build the input port type ...
void make_edge(sender< T > &p, receiver< T > &s)
Makes an edge between a single predecessor and a single successor.
internal::async_body_base< gateway_type > async_body_base_type
__TBB_NOINLINE_SYM continue_node(graph &g,)
Constructor for executable node with continue_msg -> Output.
void reset_node(reset_flags f) __TBB_override
leaf for multifunction. OutputSet can be a std::tuple or a vector.
static void fgt_remove_edge(void *, void *)
unfolded_type::input_ports_type input_ports_type
task * try_put_task(const X &t)
internal::aggregator< handler_type, buffer_operation > my_aggregator
void try_put_and_add_task(task *&last_task)
Forwards messages in sequence order.
void internal_reserve(queue_operation *op) __TBB_override
bool remove_successor(successor_type &r) __TBB_override
Removes a successor from this node.
input_ports_type & input_ports()
bool try_reserve(output_type &v) __TBB_override
Reserves an item.
static void fgt_composite(void *, void *, void *)
A cache of successors that are put in a round-robin fashion.
void reset_node(reset_flags) __TBB_override
#define __TBB_DEPRECATED_LIMITER_EXPR(expr)
graph & graph_reference() const __TBB_override
output_type my_cached_item
base_type::buffer_operation queue_operation
graph & graph_reference() const __TBB_override
Forwards messages in arbitrary order.
__TBB_NOINLINE_SYM indexer_node(graph &g)
bool is_continue_receiver() __TBB_override
task * try_put_task(const input_type &) __TBB_override
tuple< T0, T1, T2, T3, T4, T5 > InputTuple
Breaks an infinite loop between the node reservation and register_successor call. ...
void reset_node(reset_flags f) __TBB_override
virtual bool try_consume()
Consumes the reserved item.
tbb::flow::interface11::graph_node * my_nodes_last
void reset(tbb::flow::interface11::reset_flags f=tbb::flow::interface11::rf_reset_protocol)
untyped_sender predecessor_type
The predecessor type for this node.
internal::broadcast_cache< output_type > & successors() __TBB_override
receiver_type::predecessor_type predecessor_type
internal::broadcast_cache< output_type > & successors() __TBB_override
__TBB_NOINLINE_SYM continue_node(graph &g, int number_of_predecessors,)
Constructor for executable node with continue_msg -> Output.
static void fgt_node_with_body(void *, string_index, void *, void *, void *)
static void fgt_async_commit(void *, void *)
internal::function_body< T, size_t > * my_sequencer
static const T & from_void_ptr(const void *p)
__TBB_DEPRECATED continue_receiver(const continue_receiver &src)
Copy constructor.
__TBB_DEPRECATED typedef receiver< input_type >::predecessor_type predecessor_type
The predecessor type for this node.
Meets "allocator" requirements of ISO C++ Standard, Section 20.1.5.
bool remove_successor(successor_type &r) __TBB_override
Removes a successor.
A task that calls a node's forward_task function.
static void fgt_async_try_put_end(void *, void *)
task * apply_body_bypass()
Applies the body. Returning SUCCESSFULLY_ENQUEUED okay; forward_task_bypass will handle it...
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 size
buffer_node< T, A >::buffer_operation sequencer_operation
static void fgt_async_try_put_begin(void *, void *)
void reset_receiver(reset_flags f) __TBB_override
put receiver back in initial state
static task * emit_this(graph &g, const T &t, P &p)
virtual bool register_predecessor(predecessor_type &)
Add a predecessor to the node.
virtual bool remove_predecessor(predecessor_type &)
Remove a predecessor from the node.
graph & graph_reference() const __TBB_override
void remove_edge(sender< T > &p, receiver< T > &s)
Removes an edge between a single predecessor and a single successor.
void reserve_wait() __TBB_override
Used to register that an external entity may still interact with the graph.
buffer_node< T, A >::item_type item_type
task * try_put_task(const T &t) __TBB_override
__TBB_NOINLINE_SYM priority_queue_node(graph &g, const Compare &comp=Compare())
Constructor.
bool register_successor(successor_type &s) __TBB_override
Add a new successor to this node.
internal::unfolded_indexer_node< InputTuple > unfolded_type
bool register_successor(successor_type &r) __TBB_override
Adds a new successor.
bool register_successor(successor_type &r) __TBB_override
Add a new successor to this node.
__TBB_NOINLINE_SYM write_once_node(const write_once_node &src)
Copy constructor: call base class copy constructor.
__TBB_NOINLINE_SYM write_once_node(graph &g)
Constructor.
T::async_msg_data_type filtered_type
void activate_graph(tbb::flow::interface10::graph &g)
__TBB_NOINLINE_SYM composite_node(graph &g)
broadcast_cache_type my_successors
Forward declaration section.
__TBB_NOINLINE_SYM join_node(graph &g, __TBB_B0 b0, __TBB_B1 b1, __TBB_B2 b2, __TBB_B3 b3)
sender< output_type >::successor_type successor_type
An executable node that acts as a source, i.e. it has no predecessors.
buffer_node< T, A >::buffer_operation prio_operation
field of type K being used for matching.
static tbb::task * combine_tasks(graph &g, tbb::task *left, tbb::task *right)
task * decrement_counter(long long delta)
void set_external_ports(T1 &&input_ports_tuple, T2 &&output_ports_tuple)
internal::function_input_queue< input_type, Allocator > input_queue_type
void set_owner(owner_type *owner)
task that does nothing. Useful for synchronization.
void fgt_multiinput_multioutput_node_desc(const NodeType *, const char *)
internal::unfolded_indexer_node< InputTuple > unfolded_type
register_predecessor_task(predecessor_type &owner, successor_type &succ)
Implements methods for an executable node that takes continue_msg as input.
__TBB_NOINLINE_SYM async_node(graph &g, size_t concurrency,)
void handle_operations(prio_operation *op_list) __TBB_override
Used to form groups of tasks.
receiver< input_type >::predecessor_type predecessor_type
function_output(graph &g)
void internal_release(prio_operation *op) __TBB_override
internal::function_input_queue< input_type, Allocator > input_queue_type
__TBB_NOINLINE_SYM broadcast_node(graph &g)
void add_nodes(const NodeTypes &... n)
Implements methods for a function node that takes a type Input as input.
internal::tagged_msg< size_t, T0, T1, T2 > output_type
sender< output_type >::successor_type successor_type
__TBB_NOINLINE_SYM join_node(graph &g, __TBB_B0 b0, __TBB_B1 b1, __TBB_B2 b2)
virtual task * execute()=0
Should be overridden by derived classes.
void reset_receiver(reset_flags) __TBB_override
put receiver back in initial state
virtual bool try_reserve(T &)
Reserves an item in the sender.
reference operator*() const
Dereference.
const_iterator cend() const
end const iterator
virtual task * forward_task()
This is executed by an enqueued task, the "forwarder".
output_ports_type & output_ports()
void reset_node(reset_flags f) __TBB_override
virtual graph & graph_reference() const =0
__TBB_NOINLINE_SYM indexer_node(const indexer_node &other)
__TBB_NOINLINE_SYM join_node(graph &g)
A task that calls a node's apply_body_bypass function with no input.
internal::source_body< output_type > * my_body
Base class for tasks generated by graph nodes.
tbb::task_group_context * my_context
bool try_reserve(output_type &v)
static void fgt_async_reserve(void *, void *)
void wait_for_all()
Wait until graph is idle and decrement_wait_count calls equals increment_wait_count calls...
internal::unfolded_indexer_node< InputTuple > unfolded_type
void internal_forward_task(prio_operation *op) __TBB_override
Tries to forward valid items to successors.
tuple< T0, T1, T2, T3, T4, T5, T6, T7, T8 > InputTuple
static void * to_void_ptr(T &t)
__TBB_NOINLINE_SYM sequencer_node(const sequencer_node &src)
Copy constructor.
sender< output_type >::successor_type successor_type
receiver< input_type >::predecessor_type predecessor_type
void internal_pop(prio_operation *op) __TBB_override
bool try_reserve_apply_body(output_type &v)
__TBB_NOINLINE_SYM overwrite_node(const overwrite_node &src)
Copy constructor; doesn't take anything from src; default won't work.
internal::wrap_tuple_elements< N, internal::multifunction_output, Output >::type output_ports_type
tuple< T0, T1, T2, T3 > InputTuple
bool remove_successor(successor_type &s) __TBB_override
Removes a successor from this node.
buffer_node< T, A >::size_type size_type
unsigned int node_priority_t
iterator begin()
start iterator
void reset_node(reset_flags f) __TBB_override
internal::unfolded_indexer_node< InputTuple > unfolded_type
internal::wrap_tuple_elements< N, internal::multifunction_output, TupleType >::type output_ports_type
internal::function_output< output_type > fOutput_type
bool try_put_impl(const Output &i)
Implements gateway_type::try_put for an external activity to submit a message to FG.
buffer_node< T, A > class_type
An empty class used for messages that mean "I'm done".
internal::broadcast_cache< output_type > my_successors
static void fgt_begin_body(void *)
void add_nodes_impl(CompositeType *, bool)
void internal_pop(queue_operation *op) __TBB_override
__TBB_NOINLINE_SYM source_node(const source_node &src)
Copy constructor.
bool remove_successor(successor_type &r) __TBB_override
Removes s as a successor.
#define __TBB_ASSERT(predicate, comment)
No-op version of __TBB_ASSERT.
overwrite_node< T > base_type
__TBB_NOINLINE_SYM join_node(const join_node &other)
bool try_release() __TBB_override
Release a reserved item.
interface11::internal::Policy< queueing, lightweight > queueing_lightweight
bool try_put(const X &t)
Put an item to the receiver.
void spawn_in_graph_arena(tbb::flow::interface10::graph &g, tbb::task &arena_task)
Spawns a task inside graph arena.
__TBB_NOINLINE_SYM indexer_node(const indexer_node &other)
void reset_node(reset_flags f) __TBB_override
receiver< input_type >::predecessor_type predecessor_type
task * try_put_task(const T &t) __TBB_override
receive an item, return a task *if possible
void reset_receiver(reset_flags) __TBB_override
put receiver back in initial state
receiver< input_type >::predecessor_type predecessor_type
__TBB_NOINLINE_SYM indexer_node(const indexer_node &other)
iterator end()
end iterator
internal::unfolded_indexer_node< InputTuple > unfolded_type
void const char const char int ITT_FORMAT __itt_group_sync x void const char * name
async_body_base< Gateway > base_type
void remove(untyped_sender &n)
internal::unfolded_indexer_node< InputTuple > unfolded_type
receiver< input_type > receiver_type
void add_nodes(const NodeTypes &... n)
tbb::flow::interface11::graph_iterator< graph, tbb::flow::interface11::graph_node > iterator
internal::port_ref_impl< N1, N2 > port_ref()
async_body(const Body &body, gateway_type *gateway)
virtual bool internal_push(buffer_operation *op)
void internal_remove_edge(internal::untyped_sender &p, internal::untyped_receiver &s)
void add_visible_nodes(const NodeTypes &... n)
input_impl_type::predecessor_type predecessor_type
sender< output_type >::successor_type successor_type
The type of successors of this node.
void add(untyped_sender &n)
bool register_successor(successor_type &r) __TBB_override
Replace the current successor with this new successor.
void internal_reserve(prio_operation *op) __TBB_override
#define __TBB_CPP11_PRESENT
internal::tagged_msg< size_t, T0, T1, T2, T3, T4, T5 > output_type
virtual bool register_successor(successor_type &r)=0
Add a new successor to this node.
static void fgt_multioutput_node_desc(const NodeType *, const char *)
void remove_node(tbb::flow::interface11::graph_node *n)
bool try_put(const typename internal::async_helpers< T >::async_type &t)
task * try_put_task(const input_type &v) __TBB_override
Put item to successor; return task to run the successor if possible.
__TBB_NOINLINE_SYM indexer_node(graph &g)
void const char const char int ITT_FORMAT __itt_group_sync p
bool register_successor(successor_type &r) __TBB_override
Add a new successor to this node.
unfolded_type::input_ports_type input_ports_type
void reset_node(reset_flags) __TBB_override
output_ports_type & output_ports()
bool try_reserve(X &t)
Reserves an item in the sender.
void set_gateway(gateway_type *gateway)
void reset_node(reset_flags) __TBB_override
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 begin
virtual bool remove_successor(successor_type &r)=0
Removes a successor from this node.
tbb::flow::tuple< sender< OutputTypes > &... > output_ports_type
void reset_receiver(reset_flags) __TBB_override
put receiver back in initial state
internal::decrementer< limiter_node< T, DecrementType >, DecrementType > decrement
The internal receiver< DecrementType > that decrements the count.
~sequencer_node()
Destructor.
internal::tagged_msg< size_t, T0, T1, T2, T3, T4, T5, T6, T7 > output_type
buffer_node< T, A > base_type
void internal_forward_task(queue_operation *op) __TBB_override
Tries to forward valid items to successors.
void register_successor(successor_type &r)
void reset_node(reset_flags f) __TBB_override
void reset_receiver(reset_flags) __TBB_override
put receiver back in initial state
broadcast_cache_type & successors()
__TBB_DEPRECATED bool register_predecessor(predecessor_type &) __TBB_override
Increments the trigger threshold.
internal::unfolded_join_node< N, queueing_port, OutputTuple, queueing > unfolded_type
Body copy_function_object()
~source_node()
The destructor.
__TBB_DEPRECATED bool remove_predecessor(predecessor_type &) __TBB_override
Decrements the trigger threshold.
std::unique_ptr< output_ports_type > my_output_ports
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 parent
receiver< input_type >::predecessor_type predecessor_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
static const void * to_void_ptr(const T &t)
bool remove_successor(successor_type &r) __TBB_override
Removes a successor from this node.
__TBB_NOINLINE_SYM overwrite_node(graph &g)
tbb::flow::tuple< receiver< InputTypes > &... > input_ports_type
virtual bool try_release()
Releases the reserved item.
bool try_get(T &v) __TBB_override
Request an item from the buffer_node.
tbb::task_arena * my_task_arena
internal::tagged_msg< size_t, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9 > output_type
graph & graph_reference() const __TBB_override
__TBB_NOINLINE_SYM buffer_node(graph &g)
Constructor.
internal::multifunction_input< input_type, output_ports_type, Policy, Allocator > base_type
virtual void internal_reg_succ(buffer_operation *op)
Register successor.
bool remove_predecessor(predecessor_type &src) __TBB_override
Removes src from the list of cached predecessors.
priority_queue_node class_type
virtual bool try_get_wrapper(void *p, bool is_async) __TBB_override
__TBB_NOINLINE_SYM split_node(const split_node &other)
sender< output_type >::successor_type successor_type
gateway_type * my_gateway
static void fgt_multiinput_multioutput_node(void *, string_index, void *, void *)
static void fgt_make_edge(void *, void *)
task * grab_forwarding_task(buffer_operation &op_data)
bool try_consume() __TBB_override
Consumes a reserved item.
static void alias_port(void *, PortsTuple &)
split_node: accepts a tuple as input, forwards each element of the tuple to its
task * try_put_task(const TupleType &t) __TBB_override
Put item to successor; return task to run the successor if possible.
bool try_release() __TBB_override
Releases the reserved item.
virtual void reset_node(reset_flags f=rf_reset_protocol)=0
bool try_get(X &t)
Request an item from the sender.
static void fgt_node_desc(const NodeType *, const char *)
void reset_node(reset_flags f) __TBB_override
internal::broadcast_cache< input_type, null_rw_mutex > my_successors
sender< output_type >::successor_type successor_type
task * try_put_task(const T &t) __TBB_override
Puts an item to this receiver.
bool internal_push(prio_operation *op) __TBB_override
__TBB_NOINLINE_SYM continue_node(const continue_node &src)
Copy constructor.
__TBB_NOINLINE_SYM indexer_node(const indexer_node &other)
The base of all graph nodes.
void add_nodes(const NodeTypes &... n)
bool try_put(const output_type &i)
wrap_tuple_elements< N, PT, OutputTuple >::type input_ports_type
internal::multifunction_output< Output > output_port_type
internal::multifunction_input< Input, typename base_type::output_ports_type, Policy, Allocator > mfn_input_type
tbb::task * execute() __TBB_override
Should be overridden by derived classes.
void deactivate_graph(tbb::flow::interface10::graph &g)
static void fgt_reserve_wait(void *)
internal::tagged_msg< size_t, T0, T1, T2, T3, T4 > output_type
__TBB_DEPRECATED continue_receiver(__TBB_FLOW_GRAPH_PRIORITY_ARG1(int number_of_predecessors, node_priority_t priority))
Constructor.
tbb::spin_mutex nodelist_mutex
receiver< input_type >::predecessor_type predecessor_type
void reserve_wait() __TBB_override
Inform a graph that messages may come from outside, to prevent premature graph completion.
virtual void internal_release(buffer_operation *op)
fOutput_type::successor_type successor_type
int my_initial_predecessor_count
bool try_consume() __TBB_override
Consumes the reserved item.
tuple< T0, T1, T2, T3, T4, T5, T6, T7 > InputTuple
static T & from_void_ptr(void *p)
tuple< T0, T1, T2, T3, T4, T5, T6 > InputTuple
__TBB_NOINLINE_SYM indexer_node(const indexer_node &other)
virtual void finalize() const
async_storage_ptr my_storage
virtual task * try_put_task_wrapper(const void *p, bool is_async) __TBB_override
void reset_node(reset_flags f) __TBB_override
__TBB_NOINLINE_SYM queue_node(graph &g)
Constructor.
buffer_node< T, A > base_type
receiver_gateway< output_type > gateway_type
internal::reservable_predecessor_cache< T, spin_mutex > my_predecessors
void set_owner(successor_type *owner)
__TBB_NOINLINE_SYM indexer_node(const indexer_node &other)
static const node_priority_t no_priority
function_body that takes an Input and a set of output ports
internal::multifunction_input< input_type, output_ports_type, Policy, Allocator > input_impl_type
An cache of predecessors that supports requests and reservations.
static void clear_this(P &p)
std::unique_ptr< output_ports_type > my_output_ports
Forwards messages in FIFO order.
internal::function_input< input_type, output_type, Policy, Allocator > input_impl_type
__TBB_NOINLINE_SYM priority_queue_node(const priority_queue_node &src)
Copy constructor.
void prio_push(const T &src)
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 size_t void ITT_FORMAT p const __itt_domain __itt_id __itt_string_handle const wchar_t size_t ITT_FORMAT lu const __itt_domain __itt_id __itt_relation __itt_id ITT_FORMAT p const wchar_t int ITT_FORMAT __itt_group_mark S
__TBB_NOINLINE_SYM indexer_node(graph &g)
__TBB_NOINLINE_SYM buffer_node(const buffer_node &src)
Copy constructor.
tbb::internal::uint64_t tag_value
__TBB_NOINLINE_SYM join_node(graph &g)
std::unique_ptr< input_ports_type > my_input_ports
graph()
Constructs a graph with isolated task_group_context.
bool try_get(output_type &v) __TBB_override
Request an item from the node.
~graph()
Destroys the graph.
tbb::flow::tuple_element< N, typename MOP::output_ports_type >::type & output_port(MOP &op)
void remove_successor(successor_type &r)
internal::unfolded_join_node< N, key_matching_port, OutputTuple, key_matching< K, KHash > > unfolded_type
indexer_node(const indexer_node &other)
Output output_type
The type of the output message, which is complete.
internal::aggregating_functor< class_type, buffer_operation > handler_type
void add_visible_nodes(const NodeTypes &... n)
std::unique_ptr< input_ports_type > my_input_ports
tuple< T0, T1 > InputTuple
tbb::flow::tuple_element< N, typename JNT::input_ports_type >::type & input_port(JNT &jn)
templated function to refer to input ports of the join node
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