17 #ifndef __TBB_flow_graph_H
18 #define __TBB_flow_graph_H
20 #define __TBB_flow_graph_H_include_area
39 #if TBB_USE_THREADING_TOOLS && TBB_PREVIEW_FLOW_GRAPH_TRACE && ( __linux__ || __APPLE__ )
42 #pragma warning (push)
43 #pragma warning( disable: 2196 )
45 #define __TBB_NOINLINE_SYM __attribute__((noinline))
47 #define __TBB_NOINLINE_SYM
50 #if __TBB_PREVIEW_ASYNC_MSG
55 #if __TBB_PREVIEW_STREAMING_NODE
58 #include <unordered_map>
59 #include <type_traits>
60 #endif // __TBB_PREVIEW_STREAMING_NODE
62 #if TBB_DEPRECATED_FLOW_ENQUEUE
63 #define FLOW_SPAWN(a) tbb::task::enqueue((a))
65 #define FLOW_SPAWN(a) tbb::task::spawn((a))
68 #if TBB_DEPRECATED_FLOW_NODE_ALLOCATOR
69 #define __TBB_DEFAULT_NODE_ALLOCATOR(T) cache_aligned_allocator<T>
71 #define __TBB_DEFAULT_NODE_ALLOCATOR(T) null_type
75 #if __TBB_CPP11_TUPLE_PRESENT
80 using std::tuple_size;
81 using std::tuple_element;
86 #include "compat/tuple"
108 namespace interface11 {
133 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
138 template<
typename Order,
typename... Args>
struct node_set;
141 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
145 class edge_container {
148 typedef std::list<C *, tbb::tbb_allocator<C *> > edge_list_type;
150 void add_edge(C &
s) {
151 built_edges.push_back(&
s);
154 void delete_edge(C &
s) {
155 for (
typename edge_list_type::iterator i = built_edges.begin(); i != built_edges.end(); ++i) {
157 (
void)built_edges.erase(i);
163 void copy_edges(edge_list_type &v) {
167 size_t edge_count() {
168 return (
size_t)(built_edges.size());
177 template<
typename S >
void sender_extract(
S &
s);
178 template<
typename R >
void receiver_extract(R &r);
181 edge_list_type built_edges;
196 namespace interface11 {
201 if (right == NULL)
return left;
203 if (left == NULL)
return right;
214 #if __TBB_PREVIEW_ASYNC_MSG
222 template<
typename T,
typename =
void >
230 return static_cast<const void*
>(&t);
234 return static_cast<void*
>(&t);
238 return *
static_cast<const T*
>(
p);
242 return *
static_cast<T*
>(
p);
250 task*
const new_task = msg.my_storage->subscribe(*this_recv, this_recv->graph_reference());
263 template<
typename T >
272 return static_cast<const void*
>(&
static_cast<const async_msg<filtered_type>&
>(t));
276 return static_cast<void*
>(&
static_cast<async_msg<filtered_type>&
>(t));
281 return *
static_cast<const T*
>(
static_cast<const async_msg<filtered_type>*
>(
p));
285 return *
static_cast<T*
>(
static_cast<async_msg<filtered_type>*
>(
p));
304 class untyped_receiver;
331 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
332 typedef internal::edge_container<successor_type> built_successors_type;
334 typedef built_successors_type::edge_list_type successor_list_type;
335 virtual built_successors_type &built_successors() = 0;
336 virtual void internal_add_built_successor(
successor_type & ) = 0;
337 virtual void internal_delete_built_successor(
successor_type & ) = 0;
338 virtual void copy_successors( successor_list_type &) = 0;
339 virtual size_t successor_count() = 0;
343 template<
typename X >
349 template<
typename X >
365 #if __TBB_PREVIEW_OPENCL_NODE
379 if (!res)
return false;
394 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
395 typedef internal::edge_container<predecessor_type> built_predecessors_type;
396 typedef built_predecessors_type::edge_list_type predecessor_list_type;
397 virtual built_predecessors_type &built_predecessors() = 0;
400 virtual void copy_predecessors( predecessor_list_type & ) = 0;
401 virtual size_t predecessor_count() = 0;
424 template<
typename T >
425 class sender :
public internal::untyped_sender {
445 __TBB_ASSERT(
false,
"async_msg interface does not support 'pull' protocol in try_get()");
455 __TBB_ASSERT(
false,
"async_msg interface does not support 'pull' protocol in try_reserve()");
461 template<
typename T >
462 class receiver :
public internal::untyped_receiver {
490 #else // __TBB_PREVIEW_ASYNC_MSG
493 template<
typename T >
513 virtual bool try_get( T & ) {
return false; }
519 virtual bool try_release( ) {
return false; }
522 virtual bool try_consume( ) {
return false; }
524 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
525 __TBB_DEPRECATED typedef typename internal::edge_container<successor_type> built_successors_type;
527 __TBB_DEPRECATED typedef typename built_successors_type::edge_list_type successor_list_type;
529 __TBB_DEPRECATED virtual void internal_add_built_successor( successor_type & ) = 0;
530 __TBB_DEPRECATED virtual void internal_delete_built_successor( successor_type & ) = 0;
537 template<
typename T >
547 virtual ~receiver() {}
552 if (!res)
return false;
559 template<
typename R,
typename B >
friend class run_and_put_task;
563 virtual graph& graph_reference()
const = 0;
568 __TBB_DEPRECATED virtual bool register_predecessor( predecessor_type & ) {
return false; }
571 __TBB_DEPRECATED virtual bool remove_predecessor( predecessor_type & ) {
return false; }
573 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
574 __TBB_DEPRECATED typedef typename internal::edge_container<predecessor_type> built_predecessors_type;
575 __TBB_DEPRECATED typedef typename built_predecessors_type::edge_list_type predecessor_list_type;
577 __TBB_DEPRECATED virtual void internal_add_built_predecessor( predecessor_type & ) = 0;
578 __TBB_DEPRECATED virtual void internal_delete_built_predecessor( predecessor_type & ) = 0;
579 __TBB_DEPRECATED virtual void copy_predecessors( predecessor_list_type & ) = 0;
588 virtual bool is_continue_receiver() {
return false; }
590 #if __TBB_PREVIEW_OPENCL_NODE
591 template<
typename,
typename >
friend class proxy_dependency_receiver;
595 #endif // __TBB_PREVIEW_ASYNC_MSG
640 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
641 __TBB_DEPRECATED typedef internal::edge_container<predecessor_type> built_predecessors_type;
642 __TBB_DEPRECATED typedef built_predecessors_type::edge_list_type predecessor_list_type;
643 built_predecessors_type &built_predecessors()
__TBB_override {
return my_built_predecessors; }
647 my_built_predecessors.add_edge(
s );
652 my_built_predecessors.delete_edge(
s);
657 my_built_predecessors.copy_edges(v);
662 return my_built_predecessors.edge_count();
684 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
687 built_predecessors_type my_built_predecessors;
701 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
702 my_built_predecessors.clear();
719 #if __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING
720 template <
typename K,
typename T>
726 using interface11::sender;
727 using interface11::receiver;
728 using interface11::continue_receiver;
737 namespace interface11 {
742 #if __TBB_PREVIEW_ASYNC_MSG
747 template <
typename C,
typename N>
750 if (
begin) current_node = my_graph->my_nodes;
754 template <
typename C,
typename N>
757 return *operator->();
760 template <
typename C,
typename N>
765 template <
typename C,
typename N>
767 if (current_node) current_node = current_node->next;
772 namespace interface10 {
774 inline graph::graph() : my_nodes(NULL), my_nodes_last(NULL), my_task_arena(NULL) {
787 my_context(&use_this_context), my_nodes(NULL), my_nodes_last(NULL), my_task_arena(NULL) {
878 #if TBB_PREVIEW_FLOW_GRAPH_TRACE
879 inline void graph::set_name(
const char *
name) {
886 namespace interface11 {
898 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
899 using internal::node_set;
903 template <
typename Output >
915 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
921 template<
typename Body >
933 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
934 template <
typename Body,
typename... Successors>
935 input_node(
const node_set<internal::order::preceding, Successors...>& successors, Body body )
936 :
input_node(successors.graph_reference(), body) {
937 make_edges(*
this, successors);
956 #if TBB_PREVIEW_FLOW_GRAPH_TRACE
978 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
1068 template<
typename Body>
1074 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
1118 #if TBB_DEPRECATED_INPUT_NODE_BODY
1140 return (
new ( task::allocate_additional_child_of( *(this->
my_graph.
root_task()) ) )
1167 #if TBB_USE_SOURCE_NODE_AS_ALIAS
1168 template <
typename Output >
1172 template<
typename Body >
1178 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
1179 template <
typename Body,
typename... Successors>
1180 source_node(
const node_set<internal::order::preceding, Successors...>& successors, Body body )
1181 : input_node<Output>(successors, body) {
1185 #else // TBB_USE_SOURCE_NODE_AS_ALIAS
1186 template <
typename Output >
class
1188 __TBB_DEPRECATED_MSG(
"TBB Warning: tbb::flow::source_node is deprecated, use tbb::flow::input_node." )
1189 source_node : public graph_node, public sender< Output > {
1200 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
1206 template<
typename Body >
1208 :
graph_node(g), my_active(is_active), init_my_active(is_active),
1211 my_reserved(false), my_has_cached_item(false)
1213 my_successors.set_owner(
this);
1218 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
1219 template <
typename Body,
typename... Successors>
1220 source_node(
const node_set<internal::order::preceding, Successors...>& successors, Body body,
bool is_active =
true )
1221 :
source_node(successors.graph_reference(), body, is_active) {
1222 make_edges(*
this, successors);
1229 my_active(src.init_my_active),
1230 init_my_active(src.init_my_active), my_body( src.my_init_body->clone() ), my_init_body(src.my_init_body->clone() ),
1231 my_reserved(false), my_has_cached_item(false)
1233 my_successors.set_owner(
this);
1241 #if TBB_PREVIEW_FLOW_GRAPH_TRACE
1250 my_successors.register_successor(r);
1259 my_successors.remove_successor(r);
1263 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
1265 built_successors_type &built_successors()
__TBB_override {
return my_successors.built_successors(); }
1267 void internal_add_built_successor( successor_type &r)
__TBB_override {
1269 my_successors.internal_add_built_successor(r);
1272 void internal_delete_built_successor( successor_type &r)
__TBB_override {
1274 my_successors.internal_delete_built_successor(r);
1279 return my_successors.successor_count();
1284 my_successors.copy_successors(v);
1294 if ( my_has_cached_item ) {
1296 my_has_cached_item =
false;
1308 if ( my_reserved ) {
1312 if ( my_has_cached_item ) {
1325 __TBB_ASSERT( my_reserved && my_has_cached_item,
"releasing non-existent reservation" );
1326 my_reserved =
false;
1327 if(!my_successors.empty())
1335 __TBB_ASSERT( my_reserved && my_has_cached_item,
"consuming non-existent reservation" );
1336 my_reserved =
false;
1337 my_has_cached_item =
false;
1338 if ( !my_successors.empty() ) {
1348 if (!my_successors.empty())
1352 template<
typename Body>
1358 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
1360 my_successors.built_successors().sender_extract(*
this);
1361 my_active = init_my_active;
1362 my_reserved =
false;
1363 if(my_has_cached_item) my_has_cached_item =
false;
1371 my_active = init_my_active;
1373 if(my_has_cached_item) {
1374 my_has_cached_item =
false;
1400 if ( my_reserved ) {
1403 if ( !my_has_cached_item ) {
1405 bool r = (*my_body)(my_cached_item);
1408 my_has_cached_item =
true;
1411 if ( my_has_cached_item ) {
1425 return (
new ( task::allocate_additional_child_of( *(this->my_graph.root_task()) ) )
1440 if ( !try_reserve_apply_body(v) )
1443 task *last_task = my_successors.try_put_task(v);
1451 #endif // TBB_USE_SOURCE_NODE_AS_ALIAS
1458 #if TBB_DEPRECATED_FLOW_NODE_ALLOCATOR
1465 #if TBB_DEPRECATED_FLOW_NODE_ALLOCATOR
1472 "Allocator template parameter for flow graph nodes is deprecated and will be removed. "
1473 "Specify TBB_DEPRECATED_FLOW_NODE_ALLOCATOR to temporary enable the deprecated interface."
1485 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
1486 typedef typename input_impl_type::predecessor_list_type predecessor_list_type;
1487 typedef typename fOutput_type::successor_list_type successor_list_type;
1495 template<
typename Body >
1508 #if __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES && __TBB_CPP11_PRESENT
1509 template <
typename Body>
1512 #endif // __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES && __TBB_CPP11_PRESENT
1514 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
1515 template <
typename Body,
typename... Args>
1519 make_edges_in_order(nodes, *
this);
1522 #if __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES
1523 template <
typename Body,
typename... Args>
1526 #endif // __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES
1527 #endif // __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
1538 #if TBB_PREVIEW_FLOW_GRAPH_TRACE
1544 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
1547 successors().built_successors().sender_extract(*
this);
1574 template<
typename Input,
typename Output,
typename Policy =
queueing,
1581 typename internal::wrap_tuple_elements<
1582 tbb::flow::tuple_size<Output>::value,
1583 internal::multifunction_output,
1587 #if TBB_DEPRECATED_FLOW_NODE_ALLOCATOR
1590 cache_aligned_allocator<Input>
1593 #if TBB_DEPRECATED_FLOW_NODE_ALLOCATOR
1600 "Allocator template parameter for flow graph nodes is deprecated and will be removed. "
1601 "Specify TBB_DEPRECATED_FLOW_NODE_ALLOCATOR to temporary enable the deprecated interface."
1617 template<
typename Body>
1626 tbb::internal::fgt_multioutput_node_with_body<N>(
1627 CODEPTR(), tbb::internal::FLOW_MULTIFUNCTION_NODE,
1633 #if __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES && __TBB_CPP11_PRESENT
1634 template <
typename Body>
1637 #endif // TBB_PREVIEW_FLOW_GRAPH_PRIORITIES && __TBB_CPP11_PRESENT
1639 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
1640 template <
typename Body,
typename... Args>
1644 make_edges_in_order(nodes, *
this);
1647 #if __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES
1648 template <
typename Body,
typename... Args>
1651 #endif // __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES
1652 #endif // __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
1656 tbb::internal::fgt_multioutput_node_with_body<N>(
CODEPTR(), tbb::internal::FLOW_MULTIFUNCTION_NODE,
1661 #if TBB_PREVIEW_FLOW_GRAPH_TRACE
1667 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
1670 input_impl_type::extract();
1680 template<
typename TupleType,
typename Allocator=__TBB_DEFAULT_NODE_ALLOCATOR(TupleType)>
1686 #if TBB_DEPRECATED_FLOW_NODE_ALLOCATOR
1691 "Allocator template parameter for flow graph nodes is deprecated and will be removed. "
1692 "Specify TBB_DEPRECATED_FLOW_NODE_ALLOCATOR to temporary enable the deprecated interface."
1695 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
1696 typedef typename base_type::predecessor_type predecessor_type;
1697 typedef typename base_type::predecessor_list_type predecessor_list_type;
1699 typedef typename predecessor_cache_type::built_predecessors_type built_predecessors_type;
1712 tbb::internal::fgt_multioutput_node<N>(
CODEPTR(), tbb::internal::FLOW_SPLIT_NODE, &this->
my_graph,
1716 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
1717 template <
typename... Args>
1719 make_edges_in_order(nodes, *
this);
1727 tbb::internal::fgt_multioutput_node<N>(
CODEPTR(), tbb::internal::FLOW_SPLIT_NODE, &this->
my_graph,
1731 #if TBB_PREVIEW_FLOW_GRAPH_TRACE
1755 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
1760 void internal_add_built_predecessor(predecessor_type&)
__TBB_override {}
1763 void internal_delete_built_predecessor(predecessor_type&)
__TBB_override {}
1769 built_predecessors_type &built_predecessors()
__TBB_override {
return my_predessors; }
1772 built_predecessors_type my_predessors;
1780 template <
typename Output,
typename Policy =
internal::Policy<
void> >
1792 template <
typename Body >
1808 #if __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES && __TBB_CPP11_PRESENT
1809 template <
typename Body>
1814 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
1815 template <
typename Body,
typename... Args>
1819 make_edges_in_order(nodes, *
this);
1821 #if __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES
1822 template <
typename Body,
typename... Args>
1825 #endif // __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES
1826 #endif // __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
1829 template <
typename Body >
1831 graph &g,
int number_of_predecessors,
1845 #if __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES && __TBB_CPP11_PRESENT
1846 template <
typename Body>
1848 :
continue_node(g, number_of_predecessors, body, Policy(), priority) {}
1851 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
1852 template <
typename Body,
typename... Args>
1853 continue_node(
const node_set<Args...>& nodes,
int number_of_predecessors,
1856 make_edges_in_order(nodes, *
this);
1859 #if __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES
1860 template <
typename Body,
typename... Args>
1861 continue_node(
const node_set<Args...>& nodes,
int number_of_predecessors,
1863 :
continue_node(nodes, number_of_predecessors, body, Policy(), priority) {}
1876 #if TBB_PREVIEW_FLOW_GRAPH_TRACE
1882 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
1884 input_impl_type::my_built_predecessors.receiver_extract(*
this);
1885 successors().built_successors().sender_extract(*
this);
1893 using input_impl_type::try_put_task;
1904 template <
typename T>
1911 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
1917 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
1918 internal::edge_container<predecessor_type> my_built_predecessors;
1929 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
1930 template <
typename... Args>
1932 make_edges_in_order(nodes, *
this);
1945 #if TBB_PREVIEW_FLOW_GRAPH_TRACE
1963 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
1984 typedef typename receiver<T>::built_predecessors_type built_predecessors_type;
1986 built_predecessors_type &built_predecessors()
__TBB_override {
return my_built_predecessors; }
1990 my_built_predecessors.add_edge(
p);
1995 my_built_predecessors.delete_edge(
p);
2000 return my_built_predecessors.edge_count();
2003 void copy_predecessors(predecessor_list_type &v)
__TBB_override {
2005 my_built_predecessors.copy_edges(v);
2009 my_built_predecessors.receiver_extract(*
this);
2034 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
2035 my_built_predecessors.clear();
2043 template <
typename T,
typename Allocator=__TBB_DEFAULT_NODE_ALLOCATOR(T) >
2046 #if TBB_DEPRECATED_FLOW_NODE_ALLOCATOR
2052 #if TBB_DEPRECATED_FLOW_NODE_ALLOCATOR
2063 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
2067 #if !TBB_DEPRECATED_FLOW_NODE_ALLOCATOR
2070 "Allocator template parameter for flow graph nodes is deprecated and will be removed. "
2071 "Specify TBB_DEPRECATED_FLOW_NODE_ALLOCATOR to temporary enable the deprecated interface."
2079 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
2080 internal::edge_container<predecessor_type> my_built_predecessors;
2086 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
2087 , add_blt_succ, del_blt_succ,
2088 add_blt_pred, del_blt_pred,
2089 blt_succ_cnt, blt_pred_cnt,
2090 blt_succ_cpy, blt_pred_cpy
2098 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
2105 successor_list_type *svec;
2106 predecessor_list_type *pvec;
2115 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
2118 ,
elem(const_cast<T*>(&e)) ,
ltask(NULL)
2133 template<
typename derived_type>
2137 buffer_operation *tmp = NULL;
2138 bool try_forwarding =
false;
2141 op_list = op_list->next;
2142 switch (tmp->type) {
2151 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
2153 case add_blt_succ: internal_add_built_succ(tmp);
break;
2154 case del_blt_succ: internal_del_built_succ(tmp);
break;
2155 case add_blt_pred: internal_add_built_pred(tmp);
break;
2156 case del_blt_pred: internal_del_built_pred(tmp);
break;
2157 case blt_succ_cnt: internal_succ_cnt(tmp);
break;
2158 case blt_pred_cnt: internal_pred_cnt(tmp);
break;
2159 case blt_succ_cpy: internal_copy_succs(tmp);
break;
2160 case blt_pred_cpy: internal_copy_preds(tmp);
break;
2169 forwarder_busy =
true;
2171 forward_task_bypass<class_type>(*
this);
2183 return op_data.ltask;
2198 task *last_task = NULL;
2201 op_data.ltask = NULL;
2224 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
2229 virtual void internal_add_built_succ(buffer_operation *op) {
2234 virtual void internal_del_built_succ(buffer_operation *op) {
2239 typedef typename receiver<T>::built_predecessors_type built_predecessors_type;
2241 built_predecessors_type &built_predecessors()
__TBB_override {
return my_built_predecessors; }
2243 virtual void internal_add_built_pred(buffer_operation *op) {
2244 my_built_predecessors.add_edge(*(op->p));
2248 virtual void internal_del_built_pred(buffer_operation *op) {
2249 my_built_predecessors.delete_edge(*(op->p));
2253 virtual void internal_succ_cnt(buffer_operation *op) {
2258 virtual void internal_pred_cnt(buffer_operation *op) {
2259 op->cnt_val = my_built_predecessors.edge_count();
2263 virtual void internal_copy_succs(buffer_operation *op) {
2268 virtual void internal_copy_preds(buffer_operation *op) {
2269 my_built_predecessors.copy_edges(*(op->pvec));
2298 template<
typename derived_type>
2302 if (this->
my_reserved || !derived->is_item_valid()) {
2304 this->forwarder_busy =
false;
2308 task * last_task = NULL;
2310 for (; counter > 0 && derived->is_item_valid(); --counter)
2311 derived->try_put_and_add_task(last_task);
2313 op->ltask = last_task;
2314 if (last_task && !counter) {
2369 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
2370 template <
typename... Args>
2372 make_edges_in_order(nodes, *
this);
2387 #if TBB_PREVIEW_FLOW_GRAPH_TRACE
2400 buffer_operation op_data(
reg_succ);
2407 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
2409 buffer_operation op_data(add_blt_succ);
2415 buffer_operation op_data(del_blt_succ);
2421 buffer_operation op_data(add_blt_pred);
2427 buffer_operation op_data(del_blt_pred);
2433 buffer_operation op_data(blt_pred_cnt);
2435 return op_data.cnt_val;
2439 buffer_operation op_data(blt_succ_cnt);
2441 return op_data.cnt_val;
2444 void copy_predecessors( predecessor_list_type &v )
__TBB_override {
2445 buffer_operation op_data(blt_pred_cpy);
2451 buffer_operation op_data(blt_succ_cpy);
2462 r.remove_predecessor(*
this);
2463 buffer_operation op_data(
rem_succ);
2477 buffer_operation op_data(
req_item);
2488 buffer_operation op_data(
res_item);
2498 buffer_operation op_data(
rel_res);
2507 buffer_operation op_data(
con_res);
2520 buffer_operation op_data(t,
put_item);
2544 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
2547 my_built_predecessors.receiver_extract(*
this);
2558 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
2559 my_built_predecessors.clear();
2567 template <
typename T,
typename Allocator=__TBB_DEFAULT_NODE_ALLOCATOR(T) >
2569 #if !TBB_DEPRECATED_FLOW_NODE_ALLOCATOR
2572 "Allocator template parameter for flow graph nodes is deprecated and will be removed. "
2573 "Specify TBB_DEPRECATED_FLOW_NODE_ALLOCATOR to temporary enable the deprecated interface."
2590 task *new_task = this->my_successors.try_put_task(this->
front());
2640 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
2641 template <
typename... Args>
2643 make_edges_in_order(nodes, *
this);
2654 #if TBB_PREVIEW_FLOW_GRAPH_TRACE
2667 template<
typename T,
typename Allocator=__TBB_DEFAULT_NODE_ALLOCATOR(T) >
2673 #if !TBB_DEPRECATED_FLOW_NODE_ALLOCATOR
2676 "Allocator template parameter for flow graph nodes is deprecated and will be removed. "
2677 "Specify TBB_DEPRECATED_FLOW_NODE_ALLOCATOR to temporary enable the deprecated interface."
2686 template<
typename Sequencer >
2694 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
2695 template <
typename Sequencer,
typename... Args>
2698 make_edges_in_order(nodes, *
this);
2713 #if TBB_PREVIEW_FLOW_GRAPH_TRACE
2725 size_type tag = (*my_sequencer)(*(op->elem));
2726 #if !TBB_DEPRECATED_SEQUENCER_DUPLICATES
2734 size_t new_tail = (tag+1 > this->
my_tail) ? tag+1 : this->
my_tail;
2748 template<
typename T,
typename Compare = std::less<T>,
typename Allocator=__TBB_DEFAULT_NODE_ALLOCATOR(T)>
2751 #if !TBB_DEPRECATED_FLOW_NODE_ALLOCATOR
2754 "Allocator template parameter for flow graph nodes is deprecated and will removed in the future. "
2755 "To temporary enable the deprecated interface specify TBB_ENABLE_DEPRECATED_NODE_ALLOCATOR."
2773 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
2774 template <
typename... Args>
2777 make_edges_in_order(nodes, *
this);
2790 #if TBB_PREVIEW_FLOW_GRAPH_TRACE
2829 *(op->elem) =
prio();
2842 *(op->elem) =
prio();
2874 task * new_task = this->my_successors.try_put_task(this->
prio());
2941 size_type cur_pos =
mark;
2958 while (child <
mark) {
2971 child = (cur_pos<<1)+1;
2978 namespace interface11 {
2984 template<
typename T,
typename DecrementType=continue_msg >
2985 class limiter_node :
public graph_node,
public receiver< T >,
public sender< T > {
2991 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
3021 bool reserved =
false;
3043 task *rtask =
new ( task::allocate_additional_child_of( *(this->my_graph.root_task()) ) )
3061 task *rtask =
new ( task::allocate_additional_child_of( *(this->my_graph.root_task()) ) )
3079 if( delta > 0 &&
size_t(delta) >
my_count )
3094 CODEPTR(), tbb::internal::FLOW_LIMITER_NODE, &this->my_graph,
3103 #if TBB_DEPRECATED_LIMITER_NODE_CONSTRUCTOR
3105 "Deprecated interface of the limiter node can be used only in conjunction "
3106 "with continue_msg as the type of DecrementType template parameter." );
3107 #endif // Check for incompatible interface
3115 init_decrement_predecessors(num_decrement_predecessors),
3116 decrement(num_decrement_predecessors)) {
3120 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
3121 template <
typename... Args>
3122 limiter_node(
const node_set<Args...>& nodes,
size_t threshold)
3124 make_edges_in_order(nodes, *
this);
3134 init_decrement_predecessors(src.init_decrement_predecessors),
3135 decrement(src.init_decrement_predecessors)) {
3139 #if TBB_PREVIEW_FLOW_GRAPH_TRACE
3153 task*
task =
new ( task::allocate_additional_child_of( *(this->my_graph.root_task()) ) )
3164 r.remove_predecessor(*
this);
3169 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
3197 void copy_predecessors(predecessor_list_type &v)
__TBB_override {
3214 task*
task =
new ( task::allocate_additional_child_of( *(this->my_graph.root_task()) ) )
3248 rtask =
new ( task::allocate_additional_child_of( *(this->my_graph.root_task()) ) )
3288 template<
typename OutputTuple,
typename JP=queueing>
class join_node;
3290 template<
typename OutputTuple>
3299 tbb::internal::fgt_multiinput_node<N>(
CODEPTR(), tbb::internal::FLOW_JOIN_NODE_RESERVING, &this->my_graph,
3303 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
3304 template <
typename... Args>
3306 make_edges_in_order(nodes, *
this);
3311 tbb::internal::fgt_multiinput_node<N>(
CODEPTR(), tbb::internal::FLOW_JOIN_NODE_RESERVING, &this->my_graph,
3315 #if TBB_PREVIEW_FLOW_GRAPH_TRACE
3323 template<
typename OutputTuple>
3332 tbb::internal::fgt_multiinput_node<N>(
CODEPTR(), tbb::internal::FLOW_JOIN_NODE_QUEUEING, &this->my_graph,
3336 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
3337 template <
typename... Args>
3339 make_edges_in_order(nodes, *
this);
3344 tbb::internal::fgt_multiinput_node<N>(
CODEPTR(), tbb::internal::FLOW_JOIN_NODE_QUEUEING, &this->my_graph,
3348 #if TBB_PREVIEW_FLOW_GRAPH_TRACE
3358 template<
typename OutputTuple,
typename K,
typename KHash>
3360 key_matching_port, OutputTuple, key_matching<K,KHash> > {
3368 #if __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING
3371 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
3372 template <
typename... Args>
3375 make_edges_in_order(nodes, *
this);
3381 template<
typename __TBB_B0,
typename __TBB_B1>
3383 tbb::internal::fgt_multiinput_node<N>(
CODEPTR(), tbb::internal::FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph,
3386 template<
typename __TBB_B0,
typename __TBB_B1,
typename __TBB_B2>
3388 tbb::internal::fgt_multiinput_node<N>(
CODEPTR(), tbb::internal::FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph,
3391 template<
typename __TBB_B0,
typename __TBB_B1,
typename __TBB_B2,
typename __TBB_B3>
3393 tbb::internal::fgt_multiinput_node<N>(
CODEPTR(), tbb::internal::FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph,
3396 template<
typename __TBB_B0,
typename __TBB_B1,
typename __TBB_B2,
typename __TBB_B3,
typename __TBB_B4>
3399 tbb::internal::fgt_multiinput_node<N>(
CODEPTR(), tbb::internal::FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph,
3402 #if __TBB_VARIADIC_MAX >= 6
3403 template<
typename __TBB_B0,
typename __TBB_B1,
typename __TBB_B2,
typename __TBB_B3,
typename __TBB_B4,
3407 tbb::internal::fgt_multiinput_node<N>(
CODEPTR(), tbb::internal::FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph,
3411 #if __TBB_VARIADIC_MAX >= 7
3412 template<
typename __TBB_B0,
typename __TBB_B1,
typename __TBB_B2,
typename __TBB_B3,
typename __TBB_B4,
3413 typename __TBB_B5,
typename __TBB_B6>
3416 tbb::internal::fgt_multiinput_node<N>(
CODEPTR(), tbb::internal::FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph,
3420 #if __TBB_VARIADIC_MAX >= 8
3421 template<
typename __TBB_B0,
typename __TBB_B1,
typename __TBB_B2,
typename __TBB_B3,
typename __TBB_B4,
3422 typename __TBB_B5,
typename __TBB_B6,
typename __TBB_B7>
3424 __TBB_B7 b7) :
unfolded_type(g, b0, b1, b2, b3, b4, b5, b6, b7) {
3425 tbb::internal::fgt_multiinput_node<N>(
CODEPTR(), tbb::internal::FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph,
3429 #if __TBB_VARIADIC_MAX >= 9
3430 template<
typename __TBB_B0,
typename __TBB_B1,
typename __TBB_B2,
typename __TBB_B3,
typename __TBB_B4,
3431 typename __TBB_B5,
typename __TBB_B6,
typename __TBB_B7,
typename __TBB_B8>
3433 __TBB_B7 b7, __TBB_B8 b8) :
unfolded_type(g, b0, b1, b2, b3, b4, b5, b6, b7, b8) {
3434 tbb::internal::fgt_multiinput_node<N>(
CODEPTR(), tbb::internal::FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph,
3438 #if __TBB_VARIADIC_MAX >= 10
3439 template<
typename __TBB_B0,
typename __TBB_B1,
typename __TBB_B2,
typename __TBB_B3,
typename __TBB_B4,
3440 typename __TBB_B5,
typename __TBB_B6,
typename __TBB_B7,
typename __TBB_B8,
typename __TBB_B9>
3442 __TBB_B7 b7, __TBB_B8 b8, __TBB_B9 b9) :
unfolded_type(g, b0, b1, b2, b3, b4, b5, b6, b7, b8, b9) {
3443 tbb::internal::fgt_multiinput_node<N>(
CODEPTR(), tbb::internal::FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph,
3448 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
3449 template <
typename... Args,
typename... Bodies>
3451 :
join_node(nodes.graph_reference(), bodies...) {
3452 make_edges_in_order(nodes, *
this);
3457 tbb::internal::fgt_multiinput_node<N>(
CODEPTR(), tbb::internal::FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph,
3461 #if TBB_PREVIEW_FLOW_GRAPH_TRACE
3473 template<
typename T0,
typename T1=null_type,
typename T2=null_type,
typename T3=null_type,
3474 typename T4=null_type,
typename T5=null_type,
typename T6=null_type,
3478 template<
typename T0>
3481 static const int N = 1;
3487 tbb::internal::fgt_multiinput_node<N>(
CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
3491 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
3492 template <
typename... Args>
3494 make_edges_in_order(nodes, *
this);
3500 tbb::internal::fgt_multiinput_node<N>(
CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
3504 #if TBB_PREVIEW_FLOW_GRAPH_TRACE
3511 template<
typename T0,
typename T1>
3514 static const int N = 2;
3520 tbb::internal::fgt_multiinput_node<N>(
CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
3524 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
3525 template <
typename... Args>
3527 make_edges_in_order(nodes, *
this);
3533 tbb::internal::fgt_multiinput_node<N>(
CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
3537 #if TBB_PREVIEW_FLOW_GRAPH_TRACE
3544 template<
typename T0,
typename T1,
typename T2>
3547 static const int N = 3;
3553 tbb::internal::fgt_multiinput_node<N>(
CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
3557 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
3558 template <
typename... Args>
3560 make_edges_in_order(nodes, *
this);
3566 tbb::internal::fgt_multiinput_node<N>(
CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
3570 #if TBB_PREVIEW_FLOW_GRAPH_TRACE
3577 template<
typename T0,
typename T1,
typename T2,
typename T3>
3580 static const int N = 4;
3586 tbb::internal::fgt_multiinput_node<N>(
CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
3590 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
3591 template <
typename... Args>
3593 make_edges_in_order(nodes, *
this);
3599 tbb::internal::fgt_multiinput_node<N>(
CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
3603 #if TBB_PREVIEW_FLOW_GRAPH_TRACE
3610 template<
typename T0,
typename T1,
typename T2,
typename T3,
typename T4>
3613 static const int N = 5;
3619 tbb::internal::fgt_multiinput_node<N>(
CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
3623 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
3624 template <
typename... Args>
3626 make_edges_in_order(nodes, *
this);
3632 tbb::internal::fgt_multiinput_node<N>(
CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
3636 #if TBB_PREVIEW_FLOW_GRAPH_TRACE
3643 #if __TBB_VARIADIC_MAX >= 6
3644 template<
typename T0,
typename T1,
typename T2,
typename T3,
typename T4,
typename T5>
3645 class indexer_node<T0, T1, T2, T3, T4, T5> :
public internal::unfolded_indexer_node<tuple<T0, T1, T2, T3, T4, T5> > {
3647 static const int N = 6;
3653 tbb::internal::fgt_multiinput_node<N>(
CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
3657 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
3658 template <
typename... Args>
3660 make_edges_in_order(nodes, *
this);
3666 tbb::internal::fgt_multiinput_node<N>(
CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
3670 #if TBB_PREVIEW_FLOW_GRAPH_TRACE
3676 #endif //variadic max 6
3678 #if __TBB_VARIADIC_MAX >= 7
3679 template<
typename T0,
typename T1,
typename T2,
typename T3,
typename T4,
typename T5,
3681 class indexer_node<T0, T1, T2, T3, T4, T5, T6> :
public internal::unfolded_indexer_node<tuple<T0, T1, T2, T3, T4, T5, T6> > {
3683 static const int N = 7;
3689 tbb::internal::fgt_multiinput_node<N>(
CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
3693 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
3694 template <
typename... Args>
3696 make_edges_in_order(nodes, *
this);
3702 tbb::internal::fgt_multiinput_node<N>(
CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
3706 #if TBB_PREVIEW_FLOW_GRAPH_TRACE
3712 #endif //variadic max 7
3714 #if __TBB_VARIADIC_MAX >= 8
3715 template<
typename T0,
typename T1,
typename T2,
typename T3,
typename T4,
typename T5,
3716 typename T6,
typename T7>
3717 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> > {
3719 static const int N = 8;
3725 tbb::internal::fgt_multiinput_node<N>(
CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
3729 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
3730 template <
typename... Args>
3732 make_edges_in_order(nodes, *
this);
3738 tbb::internal::fgt_multiinput_node<N>(
CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
3742 #if TBB_PREVIEW_FLOW_GRAPH_TRACE
3748 #endif //variadic max 8
3750 #if __TBB_VARIADIC_MAX >= 9
3751 template<
typename T0,
typename T1,
typename T2,
typename T3,
typename T4,
typename T5,
3752 typename T6,
typename T7,
typename T8>
3753 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> > {
3755 static const int N = 9;
3761 tbb::internal::fgt_multiinput_node<N>(
CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
3765 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
3766 template <
typename... Args>
3768 make_edges_in_order(nodes, *
this);
3774 tbb::internal::fgt_multiinput_node<N>(
CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
3778 #if TBB_PREVIEW_FLOW_GRAPH_TRACE
3784 #endif //variadic max 9
3786 #if __TBB_VARIADIC_MAX >= 10
3787 template<
typename T0,
typename T1,
typename T2,
typename T3,
typename T4,
typename T5,
3788 typename T6,
typename T7,
typename T8,
typename T9>
3791 static const int N = 10;
3793 typedef tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>
InputTuple;
3794 typedef typename internal::tagged_msg<size_t, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> output_type;
3797 tbb::internal::fgt_multiinput_node<N>(
CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
3801 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
3802 template <
typename... Args>
3804 make_edges_in_order(nodes, *
this);
3810 tbb::internal::fgt_multiinput_node<N>(
CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
3814 #if TBB_PREVIEW_FLOW_GRAPH_TRACE
3820 #endif //variadic max 10
3822 #if __TBB_PREVIEW_ASYNC_MSG
3825 template<
typename T >
3828 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
3829 s.internal_add_built_predecessor(
p);
3830 p.internal_add_built_successor(
s);
3832 p.register_successor(
s );
3837 template<
typename T >
3842 #if __TBB_PREVIEW_ASYNC_MSG
3843 template<
typename TS,
typename TR,
3850 template<
typename T >
3855 template<
typename T >
3860 #endif // __TBB_PREVIEW_ASYNC_MSG
3862 #if __TBB_FLOW_GRAPH_CPP11_FEATURES
3864 template<
typename T,
typename V,
3865 typename =
typename T::output_ports_type,
typename =
typename V::input_ports_type >
3867 make_edge(get<0>(output.output_ports()), get<0>(input.input_ports()));
3871 template<
typename T,
typename R,
3872 typename =
typename T::output_ports_type >
3874 make_edge(get<0>(output.output_ports()), input);
3878 template<
typename S,
typename V,
3879 typename =
typename V::input_ports_type >
3881 make_edge(output, get<0>(input.input_ports()));
3885 #if __TBB_PREVIEW_ASYNC_MSG
3888 template<
typename T >
3891 p.remove_successor(
s );
3892 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
3894 p.internal_delete_built_successor(
s);
3895 s.internal_delete_built_predecessor(
p);
3901 template<
typename T >
3906 #if __TBB_PREVIEW_ASYNC_MSG
3907 template<
typename TS,
typename TR,
3914 template<
typename T >
3919 template<
typename T >
3923 #endif // __TBB_PREVIEW_ASYNC_MSG
3925 #if __TBB_FLOW_GRAPH_CPP11_FEATURES
3927 template<
typename T,
typename V,
3928 typename =
typename T::output_ports_type,
typename =
typename V::input_ports_type >
3930 remove_edge(get<0>(output.output_ports()), get<0>(input.input_ports()));
3934 template<
typename T,
typename R,
3935 typename =
typename T::output_ports_type >
3937 remove_edge(get<0>(output.output_ports()), input);
3940 template<
typename S,
typename V,
3941 typename =
typename V::input_ports_type >
3947 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
3948 template<
typename C >
3949 template<
typename S >
3950 void internal::edge_container<C>::sender_extract(
S &
s ) {
3951 edge_list_type e = built_edges;
3952 for (
typename edge_list_type::iterator i = e.begin(); i != e.end(); ++i ) {
3957 template<
typename C >
3958 template<
typename R >
3959 void internal::edge_container<C>::receiver_extract( R &r ) {
3960 edge_list_type e = built_edges;
3961 for (
typename edge_list_type::iterator i = e.begin(); i != e.end(); ++i ) {
3968 template<
typename Body,
typename Node >
3970 return n.template copy_function_object<Body>();
3973 #if __TBB_FLOW_GRAPH_CPP11_FEATURES
3978 template<
typename... InputTypes,
typename... OutputTypes>
3989 static const size_t NUM_INPUTS =
sizeof...(InputTypes);
3990 static const size_t NUM_OUTPUTS =
sizeof...(OutputTypes);
3996 #if TBB_PREVIEW_FLOW_GRAPH_TRACE
4007 template<
typename T1,
typename T2>
4011 my_input_ports = tbb::internal::make_unique<input_ports_type>(std::forward<T1>(input_ports_tuple));
4012 my_output_ports = tbb::internal::make_unique<output_ports_type>(std::forward<T2>(output_ports_tuple));
4018 template<
typename... NodeTypes >
4021 template<
typename... NodeTypes >
4024 #if TBB_PREVIEW_FLOW_GRAPH_TRACE
4031 __TBB_ASSERT(my_input_ports,
"input ports not set, call set_external_ports to set input ports");
4032 return *my_input_ports;
4036 __TBB_ASSERT(my_output_ports,
"output ports not set, call set_external_ports to set output ports");
4037 return *my_output_ports;
4040 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
4042 __TBB_ASSERT(
false,
"Current composite_node implementation does not support extract");
4048 template<
typename... InputTypes>
4055 static const size_t NUM_INPUTS =
sizeof...(InputTypes);
4061 #if TBB_PREVIEW_FLOW_GRAPH_TRACE
4072 template<
typename T>
4076 my_input_ports = tbb::internal::make_unique<input_ports_type>(std::forward<T>(input_ports_tuple));
4081 template<
typename... NodeTypes >
4084 template<
typename... NodeTypes >
4087 #if TBB_PREVIEW_FLOW_GRAPH_TRACE
4094 __TBB_ASSERT(my_input_ports,
"input ports not set, call set_external_ports to set input ports");
4095 return *my_input_ports;
4098 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
4100 __TBB_ASSERT(
false,
"Current composite_node implementation does not support extract");
4107 template<
typename... OutputTypes>
4114 static const size_t NUM_OUTPUTS =
sizeof...(OutputTypes);
4120 #if TBB_PREVIEW_FLOW_GRAPH_TRACE
4131 template<
typename T>
4135 my_output_ports = tbb::internal::make_unique<output_ports_type>(std::forward<T>(output_ports_tuple));
4140 template<
typename... NodeTypes >
4143 template<
typename... NodeTypes >
4146 #if TBB_PREVIEW_FLOW_GRAPH_TRACE
4153 __TBB_ASSERT(my_output_ports,
"output ports not set, call set_external_ports to set output ports");
4154 return *my_output_ports;
4157 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
4159 __TBB_ASSERT(
false,
"Current composite_node implementation does not support extract");
4165 #endif // __TBB_FLOW_GRAPH_CPP11_FEATURES
4169 template<
typename Gateway>
4183 template<
typename Input,
typename Ports,
typename Gateway,
typename Body>
4205 namespace interface11 {
4208 template <
typename Input,
typename Output,
4214 #if !TBB_DEPRECATED_FLOW_NODE_ALLOCATOR
4217 "Allocator template parameter for flow graph nodes is deprecated and will removed in the future. "
4218 "To temporary enable the deprecated interface specify TBB_ENABLE_DEPRECATED_NODE_ALLOCATOR."
4252 my_node->my_graph.reserve_wait();
4256 my_node->my_graph.release_wait();
4262 return my_node->try_put_impl(i);
4278 bool is_at_least_one_put_successful = port_successors.gather_successful_try_puts(i, tasks);
4280 "Return status is inconsistent with the method operation." );
4282 while( !tasks.
empty() ) {
4286 return is_at_least_one_put_successful;
4290 template<
typename Body>
4302 tbb::internal::fgt_multioutput_node_with_body<1>(
4303 CODEPTR(), tbb::internal::FLOW_ASYNC_NODE,
4305 this->output_ports(), this->my_body
4309 #if __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES && __TBB_CPP11_PRESENT
4310 template <
typename Body,
typename... Args>
4313 #endif // __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES
4315 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
4316 template <
typename Body,
typename... Args>
4318 const node_set<Args...>& nodes,
size_t concurrency, Body body,
4321 make_edges_in_order(nodes, *
this);
4324 #if __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES
4325 template <
typename Body,
typename... Args>
4327 : async_node(nodes,
concurrency, body, Policy(), priority) {}
4328 #endif // __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES
4329 #endif // __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
4333 static_cast<async_body_base_type*
>(this->my_init_body->get_body_ptr())->set_gateway(&my_gateway);
4335 tbb::internal::fgt_multioutput_node_with_body<1>(
CODEPTR(), tbb::internal::FLOW_ASYNC_NODE,
4337 this->output_ports(), this->my_body );
4344 #if TBB_PREVIEW_FLOW_GRAPH_TRACE
4354 return internal::output_port<0>(*this).register_successor(r);
4359 return internal::output_port<0>(*this).remove_successor(r);
4362 template<
typename Body>
4366 mfn_body_type &body_ref = *this->my_body;
4371 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
4372 typedef typename internal::edge_container<successor_type> built_successors_type;
4374 typedef typename built_successors_type::edge_list_type successor_list_type;
4376 return internal::output_port<0>(*this).built_successors();
4379 void internal_add_built_successor( successor_type &r )
__TBB_override {
4380 internal::output_port<0>(*this).internal_add_built_successor(r);
4383 void internal_delete_built_successor( successor_type &r )
__TBB_override {
4384 internal::output_port<0>(*this).internal_delete_built_successor(r);
4388 internal::output_port<0>(*this).copy_successors(l);
4392 return internal::output_port<0>(*this).successor_count();
4399 base_type::reset_node(f);
4403 #if __TBB_PREVIEW_STREAMING_NODE
4405 #endif // __TBB_PREVIEW_STREAMING_NODE
4409 template<
typename T >
4416 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
4424 my_successors.set_owner(
this );
4429 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
4430 template <
typename... Args>
4432 make_edges_in_order(nodes, *
this);
4440 my_successors.set_owner(
this );
4447 #if TBB_PREVIEW_FLOW_GRAPH_TRACE
4457 bool ret =
s.try_put( my_buffer );
4460 my_successors.register_successor(
s );
4466 task *rtask =
new ( task::allocate_additional_child_of( *( my_graph.root_task() ) ) )
4472 my_successors.register_successor(
s );
4479 my_successors.remove_successor(
s);
4483 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
4484 built_predecessors_type &built_predecessors()
__TBB_override {
return my_built_predecessors; }
4485 built_successors_type &built_successors()
__TBB_override {
return my_successors.built_successors(); }
4487 void internal_add_built_successor( successor_type &
s)
__TBB_override {
4489 my_successors.internal_add_built_successor(
s);
4492 void internal_delete_built_successor( successor_type &
s)
__TBB_override {
4494 my_successors.internal_delete_built_successor(
s);
4499 return my_successors.successor_count();
4504 my_successors.copy_successors(v);
4507 void internal_add_built_predecessor( predecessor_type &
p)
__TBB_override {
4509 my_built_predecessors.add_edge(
p);
4512 void internal_delete_built_predecessor( predecessor_type &
p)
__TBB_override {
4514 my_built_predecessors.delete_edge(
p);
4519 return my_built_predecessors.edge_count();
4522 void copy_predecessors( predecessor_list_type &v )
__TBB_override {
4524 my_built_predecessors.copy_edges(v);
4528 my_buffer_is_valid =
false;
4529 built_successors().sender_extract(*
this);
4530 built_predecessors().receiver_extract(*
this);
4537 if ( my_buffer_is_valid ) {
4557 return my_buffer_is_valid;
4562 my_buffer_is_valid =
false;
4572 return try_put_task_impl(v);
4577 my_buffer_is_valid =
true;
4591 o(owner),
s(succ) {};
4594 if (!
s.register_predecessor(o)) {
4595 o.register_successor(
s);
4606 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
4607 internal::edge_container<predecessor_type> my_built_predecessors;
4614 my_buffer_is_valid =
false;
4616 my_successors.clear();
4621 template<
typename T >
4637 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
4638 template <
typename... Args>
4640 make_edges_in_order(nodes, *
this);
4651 #if TBB_PREVIEW_FLOW_GRAPH_TRACE
4663 return this->my_buffer_is_valid ? NULL : this->try_put_task_impl(v);
4674 using interface11::graph;
4675 using interface11::graph_node;
4676 using interface11::continue_msg;
4677 using interface11::source_node;
4678 using interface11::input_node;
4679 using interface11::function_node;
4680 using interface11::multifunction_node;
4681 using interface11::split_node;
4683 using interface11::indexer_node;
4684 using interface11::internal::tagged_msg;
4687 using interface11::continue_node;
4688 using interface11::overwrite_node;
4689 using interface11::write_once_node;
4690 using interface11::broadcast_node;
4691 using interface11::buffer_node;
4692 using interface11::queue_node;
4693 using interface11::sequencer_node;
4694 using interface11::priority_queue_node;
4695 using interface11::limiter_node;
4696 using namespace interface11::internal::graph_policy_namespace;
4697 using interface11::join_node;
4703 #if __TBB_FLOW_GRAPH_CPP11_FEATURES
4704 using interface11::composite_node;
4706 using interface11::async_node;
4707 #if __TBB_PREVIEW_ASYNC_MSG
4710 #if __TBB_PREVIEW_STREAMING_NODE
4713 #endif // __TBB_PREVIEW_STREAMING_NODE
4714 #if __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES
4719 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
4720 using interface11::internal::follows;
4721 using interface11::internal::precedes;
4722 using interface11::internal::make_node_set;
4723 using interface11::internal::make_edges;
4732 #undef __TBB_PFG_RESET_ARG
4734 #undef __TBB_DEFAULT_NODE_ALLOCATOR
4737 #undef __TBB_flow_graph_H_include_area
4739 #if TBB_USE_THREADING_TOOLS && TBB_PREVIEW_FLOW_GRAPH_TRACE && ( __linux__ || __APPLE__ )
4740 #undef __TBB_NOINLINE_SYM
4743 #endif // __TBB_flow_graph_H