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 {
128 template<
typename T,
typename M>
class broadcast_cache;
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) {
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 >
225 typedef T filtered_type;
227 static const bool is_async_type =
false;
229 static const void* to_void_ptr(
const T& t) {
230 return static_cast<const void*
>(&t);
234 return static_cast<void*
>(&t);
237 static const T& from_void_ptr(
const void*
p) {
238 return *
static_cast<const T*
>(
p);
241 static T& from_void_ptr(
void*
p) {
242 return *
static_cast<T*
>(
p);
263 template<
typename T >
265 typedef T async_type;
268 static const bool is_async_type =
true;
284 static T& from_void_ptr(
void* p) {
304 class untyped_receiver;
320 virtual bool register_successor( successor_type &r ) = 0;
323 virtual bool remove_successor( successor_type &r ) = 0;
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 >
354 virtual bool try_get_wrapper(
void* p,
bool is_async ) = 0;
355 virtual bool try_reserve_wrapper(
void* p,
bool is_async ) = 0;
358 class untyped_receiver {
365 #if __TBB_PREVIEW_OPENCL_NODE 366 template<
typename,
typename >
friend class proxy_dependency_receiver;
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;
398 virtual void internal_add_built_predecessor( predecessor_type & ) = 0;
399 virtual void internal_delete_built_predecessor( predecessor_type & ) = 0;
400 virtual void copy_predecessors( predecessor_list_type & ) = 0;
401 virtual size_t predecessor_count() = 0;
409 virtual task* try_put_task_wrapper(
const void* p,
bool is_async ) = 0;
411 virtual graph& graph_reference()
const = 0;
418 virtual bool is_continue_receiver() {
return false; }
424 template<
typename T >
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 >
473 return internal::untyped_receiver::try_put(t);
477 return internal::untyped_receiver::try_put(t);
486 virtual task *try_put_task(
const T& t) = 0;
490 #else // __TBB_PREVIEW_ASYNC_MSG 493 template<
typename T >
513 virtual bool try_get( T & ) {
return false; }
516 virtual bool try_reserve( 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;
537 template<
typename T >
550 bool try_put(
const T& t ) {
551 task *res = try_put_task(t);
552 if (!res)
return false;
563 virtual graph& graph_reference()
const = 0;
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;
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 611 my_predecessor_count = my_initial_predecessor_count = number_of_predecessors;
612 my_current_count = 0;
619 my_current_count = 0;
626 ++my_predecessor_count;
636 --my_predecessor_count;
640 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION 641 __TBB_DEPRECATED typedef internal::edge_container<predecessor_type> built_predecessors_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();
675 if ( ++my_current_count < my_predecessor_count )
678 my_current_count = 0;
684 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION 687 built_predecessors_type my_built_predecessors;
691 int my_current_count;
699 my_current_count = 0;
701 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION 702 my_built_predecessors.clear();
704 my_predecessor_count = my_initial_predecessor_count;
719 #if __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING 720 template <
typename K,
typename T>
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) {
788 prepare_task_arena();
791 caught_exception =
false;
793 my_root_task->set_ref_count(1);
800 my_root_task->set_ref_count(0);
801 tbb::task::destroy(*my_root_task);
802 if (own_context)
delete my_context;
803 delete my_task_arena;
808 my_root_task->increment_ref_count();
816 my_root_task->decrement_ref_count();
824 n->
prev = my_nodes_last;
825 if (my_nodes_last) my_nodes_last->
next = n;
827 if (!my_nodes) my_nodes = n;
834 __TBB_ASSERT(my_nodes && my_nodes_last,
"graph::remove_node: Error: no registered nodes");
837 if (my_nodes_last == n) my_nodes_last = n->
prev;
838 if (my_nodes == n) my_nodes = n->
next;
847 if(my_context) my_context->reset();
849 caught_exception =
false;
851 for(iterator ii =
begin(); ii !=
end(); ++ii) {
857 prepare_task_arena(
true );
860 for(task_list_type::iterator rti = my_reset_task_list.begin(); rti != my_reset_task_list.end(); ++rti) {
863 my_reset_task_list.clear();
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 >
924 my_body( new
internal::input_body_leaf< output_type, Body>(body) ),
926 my_reserved(false), my_has_cached_item(false)
928 my_successors.set_owner(
this);
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);
945 my_body( src.my_init_body->clone() ), my_init_body(src.my_init_body->clone() ),
946 my_reserved(false), my_has_cached_item(false)
948 my_successors.set_owner(
this);
956 #if TBB_PREVIEW_FLOW_GRAPH_TRACE 965 my_successors.register_successor(r);
974 my_successors.remove_successor(r);
978 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION 980 built_successors_type &built_successors()
__TBB_override {
return my_successors.built_successors(); }
982 void internal_add_built_successor( successor_type &r)
__TBB_override {
984 my_successors.internal_add_built_successor(r);
987 void internal_delete_built_successor( successor_type &r)
__TBB_override {
989 my_successors.internal_delete_built_successor(r);
994 return my_successors.successor_count();
999 my_successors.copy_successors(v);
1009 if ( my_has_cached_item ) {
1011 my_has_cached_item =
false;
1024 if ( my_reserved ) {
1028 if ( my_has_cached_item ) {
1041 __TBB_ASSERT( my_reserved && my_has_cached_item,
"releasing non-existent reservation" );
1042 my_reserved =
false;
1043 if(!my_successors.empty())
1051 __TBB_ASSERT( my_reserved && my_has_cached_item,
"consuming non-existent reservation" );
1052 my_reserved =
false;
1053 my_has_cached_item =
false;
1054 if ( !my_successors.empty() ) {
1064 if (!my_successors.empty())
1068 template<
typename Body>
1074 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION 1076 my_successors.built_successors().sender_extract(*
this);
1078 my_reserved =
false;
1079 if(my_has_cached_item) my_has_cached_item =
false;
1088 my_reserved =
false;
1089 my_has_cached_item =
false;
1112 if ( my_reserved ) {
1115 if ( !my_has_cached_item ) {
1118 #if TBB_DEPRECATED_INPUT_NODE_BODY 1119 bool r = (*my_body)(my_cached_item);
1121 my_has_cached_item =
true;
1125 my_cached_item = (*my_body)(control);
1130 if ( my_has_cached_item ) {
1140 return (
new ( task::allocate_additional_child_of( *(this->
my_graph.
root_task()) ) )
1155 if ( !try_reserve_apply_body(v) )
1167 #if TBB_USE_SOURCE_NODE_AS_ALIAS 1168 template <
typename Output >
1172 template<
typename Body >
1174 : input_node<Output>(g, 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 )
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." )
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);
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;
1376 if(f & rf_clear_edges) my_successors.clear();
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) )
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;
1489 using input_impl_type::my_predecessors;
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>
1525 : function_node(nodes, concurrency, body, Policy(), priority) {}
1526 #endif // __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES 1527 #endif // __TBB_PREVIEW_FLOW_GRAPH_NODE_SET 1532 input_impl_type(src),
1538 #if TBB_PREVIEW_FLOW_GRAPH_TRACE 1544 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION 1546 my_predecessors.built_predecessors().receiver_extract(*
this);
1547 successors().built_successors().sender_extract(*
this);
1555 using input_impl_type::try_put_task;
1560 input_impl_type::reset_function_input(f);
1562 if(f & rf_clear_edges) {
1563 successors().clear();
1564 my_predecessors.clear();
1566 __TBB_ASSERT(!(f & rf_clear_edges) || successors().
empty(),
"function_node successors not empty");
1567 __TBB_ASSERT(this->my_predecessors.empty(),
"function_node predecessors not empty");
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 1594 typedef Allocator internals_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." 1612 input_type, output_ports_type, Policy, internals_allocator> input_impl_type;
1615 using input_impl_type::my_predecessors;
1617 template<
typename Body>
1619 graph &g,
size_t concurrency,
1626 tbb::internal::fgt_multioutput_node_with_body<N>(
1627 CODEPTR(), tbb::internal::FLOW_MULTIFUNCTION_NODE,
1629 this->output_ports(), this->my_body
1633 #if __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES && __TBB_CPP11_PRESENT 1634 template <
typename Body>
1636 : multifunction_node(g, concurrency, body, Policy(), priority) {}
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>
1650 : multifunction_node(nodes, concurrency, body, Policy(), priority) {}
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,
1658 this->output_ports(), this->my_body );
1661 #if TBB_PREVIEW_FLOW_GRAPH_TRACE 1667 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION 1669 my_predecessors.built_predecessors().receiver_extract(*
this);
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);
1724 : graph_node(other.
my_graph), base_type(other),
1725 my_output_ports(
internal::init_output_ports<output_ports_type>::
call(other.
my_graph, my_output_ports))
1727 tbb::internal::fgt_multioutput_node<N>(
CODEPTR(), tbb::internal::FLOW_SPLIT_NODE, &this->
my_graph,
1731 #if TBB_PREVIEW_FLOW_GRAPH_TRACE 1746 if (f & rf_clear_edges)
1755 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION 1760 void internal_add_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>
1811 : continue_node(g, body, Policy(), priority) {}
1814 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET 1815 template <
typename Body,
typename... Args>
1816 continue_node(
const node_set<Args...>& nodes, Body body,
1819 make_edges_in_order(nodes, *
this);
1821 #if __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES 1822 template <
typename Body,
typename... Args>
1824 : continue_node(nodes, body, Policy(), priority) {}
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;
1897 input_impl_type::reset_receiver(f);
1898 if(f & rf_clear_edges)successors().clear();
1899 __TBB_ASSERT(!(f & rf_clear_edges) || successors().
empty(),
"continue_node not reset");
1904 template <
typename T>
1908 typedef T output_type;
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 1966 built_successors_type &built_successors()
__TBB_override {
return my_successors.built_successors(); }
1968 void internal_add_built_successor(successor_type &r)
__TBB_override {
1969 my_successors.internal_add_built_successor(r);
1972 void internal_delete_built_successor(successor_type &r)
__TBB_override {
1973 my_successors.internal_delete_built_successor(r);
1977 return my_successors.successor_count();
1981 my_successors.copy_successors(v);
1986 built_predecessors_type &built_predecessors()
__TBB_override {
return my_built_predecessors; }
1988 void internal_add_built_predecessor( predecessor_type &p)
__TBB_override {
1990 my_built_predecessors.add_edge(p);
1993 void internal_delete_built_predecessor( predecessor_type &p)
__TBB_override {
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);
2010 my_successors.built_successors().sender_extract(*
this);
2032 if (f&rf_clear_edges) {
2033 my_successors.
clear();
2034 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION 2035 my_built_predecessors.clear();
2038 __TBB_ASSERT(!(f & rf_clear_edges) || my_successors.
empty(),
"Error resetting broadcast_node");
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 2053 typedef Allocator internals_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;
2085 enum op_type {reg_succ, rem_succ, req_item, res_item, rel_res, con_res, put_item, try_fwd_task
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 2103 predecessor_type *
p;
2105 successor_list_type *svec;
2106 predecessor_list_type *pvec;
2115 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
2116 , ltask(NULL), elem(const_cast<T*>(&e))
2118 , elem(const_cast<T*>(&e)) , ltask(NULL)
2125 typedef internal::aggregating_functor<class_type, buffer_operation>
handler_type;
2130 handle_operations_impl(op_list,
this);
2133 template<
typename derived_type>
2135 __TBB_ASSERT(static_cast<class_type*>(derived) ==
this,
"'this' is not a base class for derived");
2138 bool try_forwarding =
false;
2141 op_list = op_list->next;
2142 switch (tmp->
type) {
2143 case reg_succ: internal_reg_succ(tmp); try_forwarding =
true;
break;
2144 case rem_succ: internal_rem_succ(tmp);
break;
2145 case req_item: internal_pop(tmp);
break;
2146 case res_item: internal_reserve(tmp);
break;
2147 case rel_res: internal_release(tmp); try_forwarding =
true;
break;
2148 case con_res: internal_consume(tmp); try_forwarding =
true;
break;
2149 case put_item: try_forwarding = internal_push(tmp);
break;
2150 case try_fwd_task: internal_forward_task(tmp);
break;
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;
2167 if (try_forwarding && !forwarder_busy) {
2169 forwarder_busy =
true;
2171 forward_task_bypass<class_type>(*
this);
2183 return op_data.
ltask;
2187 task *ft = grab_forwarding_task(op_data);
2198 task *last_task = NULL;
2201 op_data.
ltask = NULL;
2202 my_aggregator.
execute(&op_data);
2224 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION 2227 built_successors_type &built_successors()
__TBB_override {
return my_successors.built_successors(); }
2230 my_successors.internal_add_built_successor(*(op->
r));
2235 my_successors.internal_delete_built_successor(*(op->
r));
2241 built_predecessors_type &built_predecessors()
__TBB_override {
return my_built_predecessors; }
2244 my_built_predecessors.add_edge(*(op->p));
2249 my_built_predecessors.delete_edge(*(op->p));
2254 op->cnt_val = my_successors.successor_count();
2259 op->cnt_val = my_built_predecessors.edge_count();
2264 my_successors.copy_successors(*(op->svec));
2269 my_built_predecessors.copy_edges(*(op->pvec));
2279 return this->my_item_valid(this->my_tail - 1);
2288 this->destroy_back();
2295 internal_forward_task_impl(op,
this);
2298 template<
typename derived_type>
2300 __TBB_ASSERT(static_cast<class_type*>(derived) ==
this,
"'this' is not a base class for derived");
2302 if (this->my_reserved || !derived->is_item_valid()) {
2304 this->forwarder_busy =
false;
2308 task * last_task = NULL;
2309 size_type counter = my_successors.
size();
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) {
2319 forwarder_busy =
false;
2324 this->push_back(*(op->
elem));
2330 if(this->pop_back(*(op->
elem))) {
2339 if(this->reserve_front(*(op->
elem))) {
2348 this->consume_front();
2353 this->release_front();
2360 : graph_node(g),
internal::reservable_item_buffer<T, internals_allocator>(),
receiver<T>(),
2361 sender<T>(), forwarder_busy(false)
2364 my_aggregator.initialize_handler(handler_type(
this));
2369 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET 2370 template <
typename... Args>
2371 buffer_node(
const node_set<Args...>& nodes) : buffer_node(nodes.graph_reference()) {
2372 make_edges_in_order(nodes, *
this);
2378 : graph_node(src.
my_graph),
internal::reservable_item_buffer<T, internals_allocator>(),
2382 my_aggregator.initialize_handler(handler_type(
this));
2387 #if TBB_PREVIEW_FLOW_GRAPH_TRACE 2402 my_aggregator.execute(&op_data);
2403 (
void)enqueue_forwarding_task(op_data);
2407 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION 2408 void internal_add_built_successor( successor_type &r)
__TBB_override {
2411 my_aggregator.execute(&op_data);
2414 void internal_delete_built_successor( successor_type &r)
__TBB_override {
2417 my_aggregator.execute(&op_data);
2420 void internal_add_built_predecessor( predecessor_type &p)
__TBB_override {
2423 my_aggregator.execute(&op_data);
2426 void internal_delete_built_predecessor( predecessor_type &p)
__TBB_override {
2429 my_aggregator.execute(&op_data);
2434 my_aggregator.execute(&op_data);
2435 return op_data.cnt_val;
2440 my_aggregator.execute(&op_data);
2441 return op_data.cnt_val;
2444 void copy_predecessors( predecessor_list_type &v )
__TBB_override {
2447 my_aggregator.execute(&op_data);
2453 my_aggregator.execute(&op_data);
2465 my_aggregator.execute(&op_data);
2469 (
void)enqueue_forwarding_task(op_data);
2479 my_aggregator.execute(&op_data);
2480 (
void)enqueue_forwarding_task(op_data);
2490 my_aggregator.execute(&op_data);
2491 (
void)enqueue_forwarding_task(op_data);
2499 my_aggregator.execute(&op_data);
2500 (
void)enqueue_forwarding_task(op_data);
2508 my_aggregator.execute(&op_data);
2509 (
void)enqueue_forwarding_task(op_data);
2521 my_aggregator.execute(&op_data);
2522 task *ft = grab_forwarding_task(op_data);
2544 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION 2547 my_built_predecessors.receiver_extract(*
this);
2548 my_successors.built_successors().sender_extract(*
this);
2556 if (f&rf_clear_edges) {
2557 my_successors.
clear();
2558 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION 2559 my_built_predecessors.clear();
2562 forwarder_busy =
false;
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." 2586 return this->my_item_valid(this->my_head);
2593 graph& graph_ref = this->graph_reference();
2595 this->destroy_front();
2601 this->internal_forward_task_impl(op,
this);
2605 if ( this->my_reserved || !this->my_item_valid(this->my_head)){
2609 this->pop_front(*(op->elem));
2614 if (this->my_reserved || !this->my_item_valid(this->my_head)) {
2618 this->reserve_front(*(op->elem));
2623 this->consume_front();
2640 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET 2641 template <
typename... Args>
2642 queue_node(
const node_set<Args...>& nodes) : queue_node(nodes.graph_reference()) {
2643 make_edges_in_order(nodes, *
this);
2654 #if TBB_PREVIEW_FLOW_GRAPH_TRACE 2662 base_type::reset_node(f);
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 >
2688 my_sequencer(new
internal::function_body_leaf< T, size_t, Sequencer>(s) ) {
2694 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET 2695 template <
typename Sequencer,
typename... Args>
2697 : sequencer_node(nodes.graph_reference(),
s) {
2698 make_edges_in_order(nodes, *
this);
2704 my_sequencer( src.my_sequencer->clone() ) {
2713 #if TBB_PREVIEW_FLOW_GRAPH_TRACE 2725 size_type tag = (*my_sequencer)(*(op->elem));
2726 #if !TBB_DEPRECATED_SEQUENCER_DUPLICATES 2727 if (tag < this->my_head) {
2734 size_t new_tail = (tag+1 > this->my_tail) ? tag+1 : this->my_tail;
2736 if (this->
size(new_tail) > this->capacity()) {
2737 this->grow_my_array(this->
size(new_tail));
2739 this->my_tail = new_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." 2767 :
buffer_node<T, Allocator>(g), compare(comp), mark(0) {
2773 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET 2774 template <
typename... Args>
2776 : priority_queue_node(nodes.graph_reference(), comp) {
2777 make_edges_in_order(nodes, *
this);
2790 #if TBB_PREVIEW_FLOW_GRAPH_TRACE 2800 base_type::reset_node(f);
2809 this->internal_forward_task_impl(op,
this);
2813 this->handle_operations_impl(op_list,
this);
2817 prio_push(*(op->elem));
2824 if ( this->my_reserved ==
true || this->my_tail == 0 ) {
2829 *(op->elem) = prio();
2837 if (this->my_reserved ==
true || this->my_tail == 0) {
2841 this->my_reserved =
true;
2842 *(op->elem) = prio();
2843 reserved_item = *(op->elem);
2850 this->my_reserved =
false;
2851 reserved_item = input_type();
2856 prio_push(reserved_item);
2857 this->my_reserved =
false;
2858 reserved_item = input_type();
2865 if (mark < this->my_tail) heapify();
2866 __TBB_ASSERT(mark == this->my_tail,
"mark unequal after heapify");
2870 return this->my_tail > 0;
2877 graph& graph_ref = this->graph_reference();
2891 __TBB_ASSERT(mark <= this->my_tail,
"mark outside bounds before test");
2892 return mark < this->my_tail && compare(this->get_my_item(0), this->get_my_item(this->my_tail - 1));
2897 if ( this->my_tail >= this->my_array_size )
2898 this->grow_my_array( this->my_tail + 1 );
2899 (
void) this->place_item(this->my_tail, src);
2901 __TBB_ASSERT(mark < this->my_tail,
"mark outside bounds after push");
2908 if (prio_use_tail()) {
2911 this->destroy_item(this->my_tail-1);
2913 __TBB_ASSERT(mark <= this->my_tail,
"mark outside bounds after pop");
2916 this->destroy_item(0);
2917 if(this->my_tail > 1) {
2919 __TBB_ASSERT(this->my_item_valid(this->my_tail - 1), NULL);
2920 this->move_item(0,this->my_tail - 1);
2923 if(mark > this->my_tail) --mark;
2924 if (this->my_tail > 1)
2926 __TBB_ASSERT(mark <= this->my_tail,
"mark outside bounds after pop");
2930 return this->get_my_item(prio_use_tail() ? this->my_tail-1 : 0);
2935 if(this->my_tail == 0) {
2939 if (!mark) mark = 1;
2940 for (; mark<this->my_tail; ++mark) {
2941 size_type cur_pos = mark;
2942 input_type to_place;
2943 this->fetch_item(mark,to_place);
2945 size_type
parent = (cur_pos-1)>>1;
2946 if (!compare(this->get_my_item(parent), to_place))
2948 this->move_item(cur_pos, parent);
2951 (
void) this->place_item(cur_pos, to_place);
2957 size_type cur_pos=0, child=1;
2958 while (child < mark) {
2959 size_type target = child;
2961 compare(this->get_my_item(child),
2962 this->get_my_item(child+1)))
2965 if (compare(this->get_my_item(target),
2966 this->get_my_item(cur_pos)))
2969 this->swap_items(cur_pos, target);
2971 child = (cur_pos<<1)+1;
2978 namespace interface11 {
2984 template<
typename T,
typename DecrementType=continue_msg >
2991 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION 3014 return ( my_count + my_tries < my_threshold && !my_predecessors.
empty() && !my_successors.
empty() );
3021 bool reserved =
false;
3024 if ( check_conditions() )
3041 if ( check_conditions() ) {
3059 if ( check_conditions() ) {
3079 if( delta > 0 &&
size_t(delta) > my_count )
3081 else if( delta < 0 &&
size_t(delta) > my_threshold - my_count )
3082 my_count = my_threshold;
3084 my_count -= size_t(delta);
3086 return forward_task();
3092 decrement.set_owner(
this);
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 3112 : graph_node(g), my_threshold(threshold), my_count(0),
3114 my_tries(0), decrement(),
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)
3123 : limiter_node(nodes.graph_reference(), threshold) {
3124 make_edges_in_order(nodes, *
this);
3131 my_threshold(src.my_threshold), my_count(0),
3133 my_tries(0), decrement(),
3134 init_decrement_predecessors(src.init_decrement_predecessors),
3135 decrement(src.init_decrement_predecessors)) {
3139 #if TBB_PREVIEW_FLOW_GRAPH_TRACE 3148 bool was_empty = my_successors.
empty();
3151 if ( was_empty && !my_predecessors.
empty() && my_count + my_tries < my_threshold ) {
3169 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION 3170 built_successors_type &built_successors()
__TBB_override {
return my_successors.built_successors(); }
3171 built_predecessors_type &built_predecessors()
__TBB_override {
return my_predecessors.built_predecessors(); }
3173 void internal_add_built_successor(successor_type &src)
__TBB_override {
3174 my_successors.internal_add_built_successor(src);
3177 void internal_delete_built_successor(successor_type &src)
__TBB_override {
3178 my_successors.internal_delete_built_successor(src);
3181 size_t successor_count()
__TBB_override {
return my_successors.successor_count(); }
3184 my_successors.copy_successors(v);
3187 void internal_add_built_predecessor(predecessor_type &src)
__TBB_override {
3188 my_predecessors.internal_add_built_predecessor(src);
3191 void internal_delete_built_predecessor(predecessor_type &src)
__TBB_override {
3192 my_predecessors.internal_delete_built_predecessor(src);
3195 size_t predecessor_count()
__TBB_override {
return my_predecessors.predecessor_count(); }
3197 void copy_predecessors(predecessor_list_type &v)
__TBB_override {
3198 my_predecessors.copy_predecessors(v);
3203 my_successors.built_successors().sender_extract(*
this);
3204 my_predecessors.built_predecessors().receiver_extract(*
this);
3205 decrement.built_predecessors().receiver_extract(decrement);
3212 my_predecessors.
add( src );
3223 my_predecessors.
remove( src );
3236 if ( my_count + my_tries >= my_threshold )
3248 rtask =
new ( task::allocate_additional_child_of( *(this->
my_graph.
root_task()) ) )
3268 if(f & rf_clear_edges) {
3269 my_predecessors.
clear();
3270 my_successors.
clear();
3274 my_predecessors.
reset( );
3276 decrement.reset_receiver(f);
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>
3374 : join_node(nodes.graph_reference()) {
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>
3398 unfolded_type(g, b0, b1, b2, b3, 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,
3406 unfolded_type(g, b0, b1, b2, b3, b4, b5) {
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>
3415 unfolded_type(g, b0, b1, b2, b3, b4, b5, 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 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>
3493 indexer_node(
const node_set<Args...>& nodes) : indexer_node(nodes.graph_reference()) {
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>
3526 indexer_node(
const node_set<Args...>& nodes) : indexer_node(nodes.graph_reference()) {
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>
3559 indexer_node(
const node_set<Args...>& nodes) : indexer_node(nodes.graph_reference()) {
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>
3592 indexer_node(
const node_set<Args...>& nodes) : indexer_node(nodes.graph_reference()) {
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>
3625 indexer_node(
const node_set<Args...>& nodes) : indexer_node(nodes.graph_reference()) {
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>
3659 indexer_node(
const node_set<Args...>& nodes) : indexer_node(nodes.graph_reference()) {
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>
3695 indexer_node(
const node_set<Args...>& nodes) : indexer_node(nodes.graph_reference()) {
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>
3731 indexer_node(
const node_set<Args...>& nodes) : indexer_node(nodes.graph_reference()) {
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>
3767 indexer_node(
const node_set<Args...>& nodes) : indexer_node(nodes.graph_reference()) {
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>
3803 indexer_node(
const node_set<Args...>& nodes) : indexer_node(nodes.graph_reference()) {
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);
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 >
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>
3979 class composite_node <
tbb::flow::tuple<InputTypes...>, tbb::flow::tuple<OutputTypes...> > :
public graph_node{
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>
4176 my_gateway = gateway;
4183 template<
typename Input,
typename Ports,
typename Gateway,
typename Body>
4190 : base_type(gateway), my_body(body) { }
4193 my_body(v, *this->my_gateway);
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." 4241 try_put_functor(output_port_type &p,
const Output &v) : port(&p), value(&v), result(false) { }
4243 result = port->
try_put(*value);
4252 my_node->my_graph.reserve_wait();
4256 my_node->my_graph.release_wait();
4262 return my_node->try_put_impl(i);
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>
4292 graph &g,
size_t concurrency,
4300 internal::async_body<Input, typename base_type::output_ports_type, gateway_type, 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>
4312 : async_node(g, concurrency, body, Policy(), priority) {}
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 4332 static_cast<async_body_base_type*
>(this->my_body->get_body_ptr())->set_gateway(&my_gateway);
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;
4368 return ab.get_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 4429 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET 4430 template <
typename... Args>
4431 overwrite_node(
const node_set<Args...>& nodes) : overwrite_node(nodes.graph_reference()) {
4432 make_edges_in_order(nodes, *
this);
4447 #if TBB_PREVIEW_FLOW_GRAPH_TRACE 4457 bool ret = s.
try_put( my_buffer );
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) {};
4595 o.register_successor(s);
4600 predecessor_type&
o;
4606 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION 4607 internal::edge_container<predecessor_type> my_built_predecessors;
4614 my_buffer_is_valid =
false;
4615 if (f&rf_clear_edges) {
4616 my_successors.
clear();
4621 template<
typename T >
4637 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET 4638 template <
typename... Args>
4639 write_once_node(
const node_set<Args...>& nodes) : write_once_node(nodes.graph_reference()) {
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);
4696 using namespace interface11::internal::graph_policy_namespace;
4703 #if __TBB_FLOW_GRAPH_CPP11_FEATURES 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 Body copy_function_object()
bool try_get(output_type &v) __TBB_override
Request an item from the node.
virtual task * execute()=0
Should be overridden by derived classes.
Base class for tasks generated by graph nodes.
bool try_reserve(output_type &v) __TBB_override
Reserves an item.
bool gather_successful_try_puts(const X &t, task_list &tasks)
internal::tagged_msg< size_t, T0, T1, T2, T3, T4 > output_type
__TBB_DEPRECATED bool remove_predecessor(predecessor_type &) __TBB_override
Decrements the trigger threshold.
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 end
__TBB_DEPRECATED typedef receiver< input_type >::predecessor_type predecessor_type
The predecessor type for this node.
receiver< input_type >::predecessor_type predecessor_type
bool register_successor(successor_type &r) __TBB_override
Adds a new successor.
__TBB_NOINLINE_SYM overwrite_node(graph &g)
buffer_node< T, Allocator >::item_type item_type
bool try_release() __TBB_override
Release a reserved item.
static task * emit_this(graph &g, const T &t, P &p)
buffer_node< T, Allocator >::buffer_operation prio_operation
pointer operator->() const
Dereference.
output_type my_cached_item
virtual bool register_predecessor(predecessor_type &)
Add a predecessor to the node.
void set_ref_count(int count)
Set reference count.
void reset_node(reset_flags) __TBB_override
base_type::size_type size_type
void reset_node(reset_flags f) __TBB_override
void reset_receiver(reset_flags) __TBB_override
put receiver back in initial state
buffer_operation(op_type t)
internal::broadcast_cache< input_type > my_successors
void internal_reserve(queue_operation *op) __TBB_override
output_ports_type & output_ports()
task * try_put_task(const T &t) __TBB_override
Puts an item to this receiver.
void set_gateway(gateway_type *gateway)
bool remove_successor(successor_type &r) __TBB_override
Removes a successor from this node.
bool try_reserve(output_type &v)
tbb::task_group_context * my_context
std::unique_ptr< output_ports_type > my_output_ports
buffer_node< T, Allocator >::size_type size_type
void reset(tbb::flow::interface11::reset_flags f=tbb::flow::interface11::rf_reset_protocol)
__TBB_NOINLINE_SYM join_node(const join_node &other)
field of type K being used for matching.
An empty class used for messages that mean "I'm done".
GraphNodeType & reference
__TBB_NOINLINE_SYM join_node(graph &g, __TBB_B0 b0, __TBB_B1 b1, __TBB_B2 b2, __TBB_B3 b3, __TBB_B4 b4)
buffer_node< T, Allocator >::size_type size_type
Implements methods for an executable node that takes continue_msg as input.
#define __TBB_DEPRECATED_LIMITER_ARG2(arg1, arg2)
void call(F &&f, Pack &&p)
Calls the given function with arguments taken from a stored_pack.
void handle_operations_impl(buffer_operation *op_list, derived_type *derived)
input_ports_type & input_ports()
void set_external_ports(T &&input_ports_tuple)
buffer_node< T, Allocator > base_type
#define __TBB_NOINLINE_SYM
__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)
__TBB_NOINLINE_SYM queue_node(graph &g)
Constructor.
__TBB_NOINLINE_SYM indexer_node(const indexer_node &other)
const_iterator cbegin() const
start const iterator
sender< output_type >::successor_type successor_type
The type of successors of this node.
tuple< T0, T1, T2, T3, T4 > InputTuple
void internal_remove_edge(internal::untyped_sender &p, internal::untyped_receiver &s)
tuple< T0, T1, T2 > InputTuple
task * try_put_task(const TupleType &t) __TBB_override
Put item to successor; return task to run the successor if possible.
internal::function_body< T, size_t > * my_sequencer
base_type::output_ports_type output_ports_type
internal::async_body_base< gateway_type > async_body_base_type
__TBB_NOINLINE_SYM composite_node(graph &g)
internal::tagged_msg< size_t, T0, T1, T2, T3, T4, T5 > output_type
bool try_release() __TBB_override
Release a reserved item.
__TBB_NOINLINE_SYM continue_node(graph &g,)
Constructor for executable node with continue_msg -> Output.
bool remove_successor(successor_type &r) __TBB_override
Removes a successor from this node.
void reserve_wait() __TBB_override
Inform a graph that messages may come from outside, to prevent premature graph completion.
__TBB_NOINLINE_SYM split_node(const split_node &other)
bool try_put_impl(const Output &i)
Implements gateway_type::try_put for an external activity to submit a message to FG.
__TBB_NOINLINE_SYM indexer_node(const indexer_node &other)
static const void * to_void_ptr(const T &t)
internal::unfolded_join_node< N, key_matching_port, OutputTuple, key_matching< K, KHash > > unfolded_type
#define __TBB_DEPRECATED_LIMITER_ARG4(arg1, arg2, arg3, arg4)
bool register_successor(successor_type &r) __TBB_override
Replace the current successor with this new successor.
bool empty() const
True if list is empty; false otherwise.
static void fgt_async_reserve(void *, void *)
graph & graph_reference() const __TBB_override
virtual graph & graph_reference() const =0
void reset_node(reset_flags f) __TBB_override
bool try_reserve(T &v) __TBB_override
Reserves an item.
internal::unfolded_indexer_node< InputTuple > unfolded_type
__TBB_NOINLINE_SYM indexer_node(const indexer_node &other)
__TBB_NOINLINE_SYM split_node(graph &g)
task that does nothing. Useful for synchronization.
task * try_put_task(const input_type &) __TBB_override
#define __TBB_FLOW_GRAPH_PRIORITY_ARG0(priority)
tbb::flow::tuple< sender< OutputTypes > &... > output_ports_type
internal::unfolded_indexer_node< InputTuple > unfolded_type
void reset_node(reset_flags f) __TBB_override
static void fgt_graph(void *)
unfolded_type::input_ports_type input_ports_type
void reset_node(reset_flags f) __TBB_override
An abstract cache of successors.
bool try_put(const output_type &i)
Implements a function node that supports Input -> Output.
static void fgt_make_edge(void *, void *)
void enqueue_in_graph_arena(tbb::flow::interface10::graph &g, tbb::task &arena_task)
Enqueues a task inside graph arena.
__TBB_NOINLINE_SYM join_node(const join_node &other)
receiver_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_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
bool internal_push(prio_operation *op) __TBB_override
void add_nodes(const NodeTypes &... n)
buffer_node< T, Allocator >::buffer_operation sequencer_operation
void operator()(const Input &v, Ports &)
bool remove_successor(successor_type &r) __TBB_override
Removes a successor from this node.
__TBB_NOINLINE_SYM indexer_node(const indexer_node &other)
limiter_node(graph &g, __TBB_DEPRECATED_LIMITER_ARG2(size_t threshold, int num_decrement_predecessors=0))
Constructor.
Pure virtual template class that defines a receiver of messages of type T.
task * try_put_task(const X &t)
void internal_pop(queue_operation *op) __TBB_override
void add(untyped_sender &n)
void reset_node(reset_flags f) __TBB_override
receiver< input_type >::predecessor_type predecessor_type
~input_node()
The destructor.
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
void add_nodes_impl(CompositeType *, bool)
__TBB_DEPRECATED internal::port_ref_impl< N1, N2 > port_ref()
virtual bool internal_push(buffer_operation *op)
internal::unfolded_indexer_node< InputTuple > unfolded_type
__TBB_DEPRECATED continue_receiver(__TBB_FLOW_GRAPH_PRIORITY_ARG1(int number_of_predecessors, node_priority_t priority))
Constructor.
void internal_consume(queue_operation *op) __TBB_override
void try_put_and_add_task(task *&last_task)
static void fgt_remove_edge(void *, void *)
__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)
virtual void reset_node(reset_flags f=rf_reset_protocol)=0
static internal::allocate_root_proxy allocate_root()
Returns proxy for overloaded new that allocates a root task.
static void fgt_composite(void *, void *, void *)
virtual void finalize() const
bool try_consume() __TBB_override
Consumes the reserved item.
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(graph &g)
void try_put_and_add_task(task *&last_task)
__TBB_NOINLINE_SYM indexer_node(const indexer_node &other)
void handle_operations(prio_operation *op_list) __TBB_override
sender< output_type >::successor_type successor_type
bool register_successor(successor_type &s) __TBB_override
Add a new successor to this node.
Represents acquisition of a mutex.
bool try_put(const X &t)
Put an item to the receiver.
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
internal::tagged_msg< size_t, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9 > output_type
~graph()
Destroys the graph.
void reset_receiver(reset_flags) __TBB_override
put receiver back in initial state
task * apply_body_bypass()
Applies the body. Returning SUCCESSFULLY_ENQUEUED okay; forward_task_bypass will handle it...
internal::input_body< output_type > * my_init_body
static void fgt_graph_desc(void *, const char *)
bool try_get(input_type &v) __TBB_override
Request an item from the sender.
Body copy_function_object()
internal::unfolded_indexer_node< InputTuple > unfolded_type
iterator end()
end iterator
function_body that takes an Input and a set of output ports
internal::broadcast_cache< output_type > my_successors
__TBB_NOINLINE_SYM indexer_node(const indexer_node &other)
bool try_reserve(output_type &v) __TBB_override
Reserves an item.
try_put_functor(output_port_type &p, const Output &v)
Forwards messages in arbitrary order.
void activate()
Activates a node that was created in the inactive state.
void register_node(tbb::flow::interface11::graph_node *n)
internal::multifunction_input< Input, typename base_type::output_ports_type, Policy, Allocator > mfn_input_type
void prepare_task_arena(bool reinit=false)
virtual ~untyped_sender()
A cache of successors that are put in a round-robin fashion.
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
input_impl_type::predecessor_type predecessor_type
split_node: accepts a tuple as input, forwards each element of the tuple to its
#define __TBB_CPP11_PRESENT
tbb::flow::tuple< receiver< InputTypes > &... > input_ports_type
virtual void internal_pop(buffer_operation *op)
void deactivate_graph(tbb::flow::interface10::graph &g)
bool register_successor(successor_type &r) __TBB_override
Adds a successor.
task * try_put_task(const input_type &v) __TBB_override
Put item to successor; return task to run the successor if possible.
bool remove_successor(successor_type &r) __TBB_override
Removes a successor.
internal::reservable_predecessor_cache< T, spin_mutex > my_predecessors
gateway_type * my_gateway
The base of all graph nodes.
__TBB_NOINLINE_SYM buffer_node(const buffer_node &src)
Copy constructor.
__TBB_NOINLINE_SYM indexer_node(graph &g)
bool register_successor(successor_type &r) __TBB_override
Add a new successor to this node.
static void fgt_node(void *, string_index, void *, void *)
internal::aggregator< handler_type, buffer_operation > my_aggregator
void set_owner(successor_type *owner)
unsigned int node_priority_t
__TBB_NOINLINE_SYM priority_queue_node(const priority_queue_node &src)
Copy constructor.
receiver_gateway< output_type > gateway_type
virtual bool try_reserve(T &)
Reserves an item in the sender.
sender< output_type >::successor_type successor_type
Detects whether two given types are the same.
internal::tagged_msg< size_t, T0, T1, T2 > output_type
static task * try_put_task_wrapper_impl(receiver< T > *const this_recv, const void *p, bool is_async)
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
void internal_pop(prio_operation *op) __TBB_override
tuple< T0, T1, T2, T3 > InputTuple
Meets "allocator" requirements of ISO C++ Standard, Section 20.1.5.
task * apply_body_bypass()
Applies the body. Returning SUCCESSFULLY_ENQUEUED okay; forward_task_bypass will handle it...
__TBB_NOINLINE_SYM join_node(graph &g, __TBB_B0 b0, __TBB_B1 b1, __TBB_B2 b2, __TBB_B3 b3)
Class for determining type of std::allocator<T>::value_type.
class __TBB_DEPRECATED_MSG("tbb::tbb_hash is deprecated, use std::hash") tbb_hash
receiver< input_type >::predecessor_type predecessor_type
Base class for receivers of completion messages.
~sequencer_node()
Destructor.
#define __TBB_DEFAULT_NODE_ALLOCATOR(T)
internal::function_input< input_type, output_type, Policy, internals_allocator > input_impl_type
void set_external_ports(T1 &&input_ports_tuple, T2 &&output_ports_tuple)
void reset_node(reset_flags f) __TBB_override
void add_visible_nodes(const NodeTypes &... n)
tbb::flow::tuple_element< N, typename MOP::output_ports_type >::type & output_port(MOP &op)
graph()
Constructs a graph with isolated task_group_context.
internal::input_body< output_type > * my_body
sender< output_type >::successor_type successor_type
async_body_base(gateway_type *gateway)
void reset_receiver(reset_flags) __TBB_override
put receiver back in initial state
Forwards messages in FIFO order.
void remove_successor(successor_type &r)
__TBB_DEPRECATED continue_receiver(const continue_receiver &src)
Copy constructor.
void add_nodes(const NodeTypes &... n)
void __TBB_store_with_release(volatile T &location, V value)
static void fgt_multiinput_multioutput_node(void *, string_index, void *, void *)
void prio_push(const T &src)
T::async_msg_data_type filtered_type
reference operator*() const
Dereference.
virtual void internal_reg_succ(buffer_operation *op)
Register successor.
bool is_graph_active(tbb::flow::interface10::graph &g)
void reset_node(reset_flags f) __TBB_override
resets the source_node to its initial state
bool try_get(output_type &v) __TBB_override
Request an item from the node.
bool register_successor(successor_type &r) __TBB_override
Add a new successor to this node.
virtual bool try_reserve_wrapper(void *p, bool is_async) __TBB_override
tbb::task_arena * my_task_arena
static void alias_port(void *, PortsTuple &)
void remove(untyped_sender &n)
#define __TBB_STATIC_ASSERT(condition, msg)
virtual bool try_get(T &)
Request an item from the sender.
void add_task_to_graph_reset_list(tbb::flow::interface10::graph &g, tbb::task *tp)
sender< output_type >::successor_type successor_type
receiver< T > successor_type
task * try_put_task(const X &t)
void reset_receiver(reset_flags) __TBB_override
put receiver back in initial state
Base class for user-defined tasks.
tbb::internal::uint64_t tag_value
void reset_node(reset_flags f) __TBB_override
resets the input_node to its initial state
__TBB_DEPRECATED bool register_predecessor(predecessor_type &) __TBB_override
Increments the trigger threshold.
The leaf for source_body.
virtual task * forward_task()
This is executed by an enqueued task, the "forwarder".
static void fgt_release_wait(void *)
receiver< TupleType > base_type
void set_owner(owner_type *owner)
An executable node that acts as a source, i.e. it has no predecessors.
internal::round_robin_cache< T, null_rw_mutex > my_successors
Forward declaration section.
input_ports_type & input_ports()
__TBB_NOINLINE_SYM queue_node(const queue_node &src)
Copy constructor.
bool try_reserve_apply_body(output_type &v)
Implements methods for both executable and function nodes that puts Output to its successors...
sender< output_type >::successor_type successor_type
cache_aligned_allocator< Input > internals_allocator
__TBB_NOINLINE_SYM join_node(graph &g)
__TBB_NOINLINE_SYM join_node(const join_node &other)
bool try_reserve_apply_body(output_type &v)
iterator begin()
start iterator
#define __TBB_FLOW_GRAPH_PRIORITY_ARG1(arg1, priority)
__TBB_NOINLINE_SYM indexer_node(graph &g)
__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_NOINLINE_SYM write_once_node(const write_once_node &src)
Copy constructor: call base class copy constructor.
virtual bool remove_successor(successor_type &r)=0
Removes a successor from this node.
static void fgt_async_try_put_begin(void *, void *)
__TBB_DEPRECATED tbb::task * root_task()
Returns the root task of the graph.
__TBB_NOINLINE_SYM write_once_node(graph &g)
Constructor.
internal::decrementer< limiter_node< T, DecrementType >, DecrementType > decrement
The internal receiver< DecrementType > that decrements the count.
sender< output_type >::successor_type successor_type
task * try_put_task(const T &t) __TBB_override
virtual source_body * clone()=0
void try_put_and_add_task(task *&last_task)
static const T & from_void_ptr(const void *p)
__TBB_NOINLINE_SYM indexer_node(graph &g)
concurrency
An enumeration the provides the two most common concurrency levels: unlimited and serial...
__TBB_NOINLINE_SYM sequencer_node(const sequencer_node &src)
Copy constructor.
A lock that occupies a single byte.
virtual void internal_reserve(buffer_operation *op)
void internal_forward_task_impl(buffer_operation *op, derived_type *derived)
internal::broadcast_cache< output_type > & successors() __TBB_override
task * try_put_task(const T &t) __TBB_override
build a task to run the successor if possible. Default is old behavior.
input_filter control to signal end-of-input for parallel_pipeline
internal::broadcast_cache< output_type > & successors() __TBB_override
static void fgt_end_body(void *)
async_storage_ptr my_storage
receiver< input_type >::predecessor_type predecessor_type
buffer_node< T, Allocator > base_type
wrap_tuple_elements< N, PT, OutputTuple >::type input_ports_type
task & pop_front()
Pop the front task from the list.
Base class for types that should not be assigned.
Body copy_body(Node &n)
Returns a copy of the body from a function or continue node.
void const char const char int ITT_FORMAT __itt_group_sync p
async_body(const Body &body, gateway_type *gateway)
An cache of predecessors that supports requests and reservations.
sender< output_type >::successor_type successor_type
The type of successors of this node.
__TBB_NOINLINE_SYM async_node(graph &g, size_t concurrency,)
__TBB_NOINLINE_SYM indexer_node(graph &g)
void release_wait() __TBB_override
Inform a graph that a previous call to reserve_wait is no longer in effect.
int my_initial_predecessor_count
Forwards messages of type T to all successors.
void reset_node(reset_flags) __TBB_override
fOutput_type::successor_type successor_type
Implements methods for a function node that takes a type Input as input.
graph & graph_reference() const __TBB_override
sender< output_type >::successor_type successor_type
virtual void internal_consume(buffer_operation *op)
Breaks an infinite loop between the node reservation and register_successor call. ...
virtual bool register_successor(successor_type &r)=0
Add a new successor to this node.
static void fgt_async_commit(void *, void *)
bool try_consume() __TBB_override
Consumes a reserved item.
__TBB_DEPRECATED typedef continue_msg input_type
The input type.
A cache of successors that are broadcast to.
Body copy_function_object()
graph & graph_reference() const __TBB_override
void internal_forward_task(prio_operation *op) __TBB_override
Tries to forward valid items to successors.
implements a function node that supports Input -> (set of outputs)
task * try_put_task(const X &t)
buffer_operation(const T &e, op_type t)
virtual void handle_operations(buffer_operation *op_list)
__TBB_NOINLINE_SYM indexer_node(const indexer_node &other)
bool try_put(const Output &i) __TBB_override
Implements gateway_type::try_put for an external activity to submit a message to FG.
tbb::flow::interface11::graph_node * my_nodes_last
std::unique_ptr< output_ports_type > my_output_ports
receiver< input_type >::predecessor_type predecessor_type
void add_visible_nodes(const NodeTypes &... n)
tuple< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9 > InputTuple
internal::tagged_msg< size_t, T0, T1, T2, T3, T4, T5, T6 > output_type
overwrite_node< T > base_type
async_body_base< Gateway > base_type
Forwards messages only if the threshold has not been reached.
static const node_priority_t no_priority
An executable node that acts as a source, i.e. it has no predecessors.
~source_node()
The destructor.
static tbb::task *const SUCCESSFULLY_ENQUEUED
bool try_release() __TBB_override
Releases the reserved item.
__TBB_NOINLINE_SYM indexer_node(graph &g)
internal::broadcast_cache< T > my_successors
tuple< T0, T1, T2, T3, T4, T5, T6, T7, T8 > InputTuple
static void fgt_reserve_wait(void *)
__TBB_NOINLINE_SYM priority_queue_node(graph &g, const Compare &comp=Compare())
Constructor.
input_impl_type::predecessor_type predecessor_type
class __TBB_DEPRECATED streaming_node
__TBB_NOINLINE_SYM input_node(const input_node &src)
Copy constructor.
task * try_put_task(const T &v) __TBB_override
Put item to successor; return task to run the successor if possible.
task * try_put_task_impl(const input_type &v)
void reset_node(reset_flags f) __TBB_override
base_type::buffer_operation queue_operation
__TBB_NOINLINE_SYM source_node(const source_node &src)
Copy constructor.
bool try_reserve(T &v) __TBB_override
Reserves an item.
internal::function_input_queue< input_type, internals_allocator > input_queue_type
tbb::flow::interface11::graph_node * my_nodes
virtual void internal_forward_task(buffer_operation *op)
Tries to forward valid items to successors.
std::unique_ptr< input_ports_type > my_input_ports
Forwards messages in priority order.
void fgt_multiinput_multioutput_node_desc(const NodeType *, const char *)
#define __TBB_FLOW_GRAPH_PRIORITY_EXPR(expr)
register_predecessor_task(predecessor_type &owner, successor_type &succ)
void add_visible_nodes(const NodeTypes &... n)
internal::source_body< output_type > * my_body
leaf for multifunction. OutputSet can be a std::tuple or a vector.
bool try_reserve(X &t)
Reserves an item in the sender.
graph & graph_reference() const __TBB_override
internal::unfolded_indexer_node< InputTuple > unfolded_type
virtual input_body * clone()=0
void reset_node(reset_flags f) __TBB_override
bool remove_successor(successor_type &r) __TBB_override
Removes a successor from this node.
internal::unfolded_indexer_node< InputTuple > unfolded_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)
A cache of predecessors that only supports try_get.
void internal_reserve(prio_operation *op) __TBB_override
Implements an executable node that supports continue_msg -> Output.
virtual bool try_get_wrapper(void *p, bool is_async) __TBB_override
virtual ~untyped_receiver()
Destructor.
void const char const char int ITT_FORMAT __itt_group_sync x void const char * name
internal::broadcast_cache< input_type, null_rw_mutex > my_successors
bool try_consume() __TBB_override
Consumes a reserved item.
internal::source_body< output_type > * my_init_body
sender< output_type >::successor_type successor_type
void internal_release(prio_operation *op) __TBB_override
void internal_make_edge(internal::untyped_sender &p, internal::untyped_receiver &s)
__TBB_NOINLINE_SYM indexer_node(graph &g)
__TBB_NOINLINE_SYM async_node(const async_node &other)
Output output_type
The type of the output message, which is complete.
receiver< input_type > receiver_type
receiver< input_type >::predecessor_type predecessor_type
void spawn_put()
Spawns a task that applies the body.
bool remove_successor(successor_type &s) __TBB_override
Removes a successor from this node.
internal::unfolded_join_node< N, reserving_port, OutputTuple, reserving > unfolded_type
void make_edge(sender< T > &p, receiver< T > &s)
Makes an edge between a single predecessor and a single successor.
void release_wait() __TBB_override
Deregisters an external entity that may have interacted with the graph.
buffer_node< T, Allocator > class_type
static void * to_void_ptr(T &t)
bool register_predecessor(predecessor_type &src) __TBB_override
Adds src to the list of cached predecessors.
static void * to_void_ptr(T &t)
static void fgt_multioutput_node_desc(const NodeType *, const char *)
void const char const char int ITT_FORMAT __itt_group_sync s
__TBB_NOINLINE_SYM indexer_node(graph &g)
static void alias_port(void *, PortsTuple &)
output_ports_type & output_ports()
A task that calls a node's forward_task function.
bool try_consume() __TBB_override
Consumes a reserved item.
__TBB_NOINLINE_SYM join_node(graph &g)
__TBB_NOINLINE_SYM broadcast_node(graph &g)
static void fgt_async_try_put_end(void *, void *)
bool try_release() __TBB_override
Release a reserved item.
__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)
unfolded_join_node : passes input_ports_type to join_node_base. We build the input port type ...
tuple< T0, T1, T2, T3, T4, T5 > InputTuple
virtual void internal_rem_succ(buffer_operation *op)
Remove successor.
void reset_node(reset_flags f) __TBB_override
internal::broadcast_cache< output_type > my_successors
void reset_node(reset_flags) __TBB_override
item_buffer with reservable front-end. NOTE: if reserving, do not
internal::unfolded_indexer_node< InputTuple > unfolded_type
interface11::internal::Policy< queueing, lightweight > queueing_lightweight
unfolded_type::input_ports_type input_ports_type
__TBB_NOINLINE_SYM indexer_node(graph &g)
Forwards messages in sequence order.
internal::unfolded_join_node< N, queueing_port, OutputTuple, queueing > unfolded_type
__TBB_NOINLINE_SYM input_node(graph &g, Body body)
Constructor for a node with a successor.
void internal_consume(prio_operation *op) __TBB_override
static void fgt_node_desc(const NodeType *, const char *)
Output output_type
The type of the output message, which is complete.
tbb::flow::tuple< receiver< InputTypes > &... > input_ports_type
cache_aligned_allocator< Input > internals_allocator
virtual void internal_release(buffer_operation *op)
internal::multifunction_output< Output > output_port_type
__TBB_NOINLINE_SYM sequencer_node(graph &g, const Sequencer &s)
Constructor.
internal::unfolded_indexer_node< InputTuple > unfolded_type
Used to form groups of tasks.
#define __TBB_ASSERT(predicate, comment)
No-op version of __TBB_ASSERT.
task * try_put_task(const T &t) __TBB_override
receive an item, return a task *if possible
void reset_node(reset_flags f) __TBB_override
__TBB_NOINLINE_SYM overwrite_node(const overwrite_node &src)
Copy constructor; doesn't take anything from src; default won't work.
receiver< input_type >::predecessor_type predecessor_type
Enables one or the other code branches.
std::unique_ptr< input_ports_type > my_input_ports
void add_nodes(const NodeTypes &... n)
internal::function_output< output_type > fOutput_type
sender< output_type >::successor_type successor_type
bool try_get(T &v) __TBB_override
Request an item from the buffer_node.
indexer_node(const indexer_node &other)
__TBB_NOINLINE_SYM indexer_node(const indexer_node &other)
internal::aggregating_functor< class_type, buffer_operation > handler_type
internal::tagged_msg< size_t, T0 > output_type
static void fgt_node_with_body(void *, string_index, void *, void *, void *)
receiver< input_type >::predecessor_type predecessor_type
output_type my_cached_item
void set_external_ports(T &&output_ports_tuple)
void reserve_wait() __TBB_override
Used to register that an external entity may still interact with the graph.
internal::wrap_tuple_elements< N, internal::multifunction_output, TupleType >::type output_ports_type
static void fgt_begin_body(void *)
__TBB_NOINLINE_SYM join_node(graph &g, __TBB_B0 b0, __TBB_B1 b1, __TBB_B2 b2)
virtual bool remove_predecessor(predecessor_type &)
Remove a predecessor from the node.
output_ports_type my_output_ports
void remove_edge(sender< T > &p, receiver< T > &s)
Removes an edge between a single predecessor and a single successor.
limiter_node(const limiter_node &src)
Copy constructor.
internal::tagged_msg< size_t, T0, T1 > output_type
static task * try_put_task_wrapper_impl(receiver< T > *const this_recv, const void *p, bool is_async)
virtual task * try_put_task(const T &t)=0
Put item to successor; return task to run the successor if possible.
#define __TBB_DEPRECATED_LIMITER_EXPR(expr)
task * grab_forwarding_task(buffer_operation &op_data)
cache_aligned_allocator< T > internals_allocator
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
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
bool internal_push(sequencer_operation *op) __TBB_override
internal::tagged_msg< size_t, T0, T1, T2, T3, T4, T5, T6, T7 > output_type
bool register_successor(successor_type &r) __TBB_override
Add a new successor to this node.
bool remove_predecessor(predecessor_type &src) __TBB_override
Removes src from the list of cached predecessors.
internal::unfolded_indexer_node< InputTuple > unfolded_type
static void clear_this(P &p)
virtual task * try_put_task_wrapper(const void *p, bool is_async) __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 __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_string_handle unsigned long long ITT_FORMAT lu const __itt_domain __itt_id __itt_string_handle __itt_metadata_type type
Implements methods for a function node that takes a type Input as input and sends.
__TBB_NOINLINE_SYM indexer_node(const indexer_node &other)
A task that calls a node's apply_body_bypass function with no input.
bool try_get(X &t)
Request an item from the sender.
bool enqueue_forwarding_task(buffer_operation &op_data)
internal::function_output< output_type > fOutput_type
task * decrement_counter(long long delta)
fOutput_type::successor_type successor_type
static tbb::task * combine_tasks(graph &g, tbb::task *left, tbb::task *right)
void reset_node(reset_flags f) __TBB_override
broadcast_cache_type & successors()
const_iterator cend() const
end const iterator
internal::wrap_tuple_elements< N, internal::multifunction_output, Output >::type output_ports_type
receiver_gateway_impl(async_node *node)
void spawn_put()
Spawns a task that applies the body.
internal::tagged_msg< size_t, T0, T1, T2, T3, T4, T5, T6, T7, T8 > output_type
tbb::task * execute() __TBB_override
Should be overridden by derived classes.
virtual bool try_release()
Releases the reserved item.
internal::unfolded_indexer_node< InputTuple > unfolded_type
unfolded_type::input_ports_type input_ports_type
void reset_receiver(reset_flags f) __TBB_override
put receiver back in initial state
__TBB_NOINLINE_SYM buffer_node(graph &g)
Constructor.
output_ports_type & output_ports()
tuple< T0, T1, T2, T3, T4, T5, T6, T7 > InputTuple
async_msg< T > async_type
tuple< T0, T1, T2, T3, T4, T5, T6 > InputTuple
__TBB_NOINLINE_SYM source_node(graph &g, Body body, bool is_active=true)
Constructor for a node with a successor.
class __TBB_DEPRECATED async_msg
tuple< T0, T1 > InputTuple
__TBB_NOINLINE_SYM join_node(graph &g, __TBB_B0 b0, __TBB_B1 b1)
void activate_graph(tbb::flow::interface10::graph &g)
void register_successor(successor_type &r)
internal::tagged_msg< size_t, T0, T1, T2, T3 > output_type
multifunction_node< Input, tuple< Output >, Policy, Allocator > base_type
const V & cast_to(T const &t)
void remove_node(tbb::flow::interface11::graph_node *n)
K key_from_message(const T &t)
bool try_put(const typename internal::async_helpers< T >::filtered_type &t)
Put an item to the receiver.
void internal_forward_task(queue_operation *op) __TBB_override
Tries to forward valid items to successors.
tbb::flow::tuple< sender< OutputTypes > &... > output_ports_type
priority_queue_node class_type