Intel(R) Threading Building Blocks Doxygen Documentation  version 4.2.3
flow_graph.h
Go to the documentation of this file.
1 /*
2  Copyright (c) 2005-2020 Intel Corporation
3 
4  Licensed under the Apache License, Version 2.0 (the "License");
5  you may not use this file except in compliance with the License.
6  You may obtain a copy of the License at
7 
8  http://www.apache.org/licenses/LICENSE-2.0
9 
10  Unless required by applicable law or agreed to in writing, software
11  distributed under the License is distributed on an "AS IS" BASIS,
12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  See the License for the specific language governing permissions and
14  limitations under the License.
15 */
16 
17 #ifndef __TBB_flow_graph_H
18 #define __TBB_flow_graph_H
19 
20 #define __TBB_flow_graph_H_include_area
22 
23 #include "tbb_stddef.h"
24 #include "atomic.h"
25 #include "spin_mutex.h"
26 #include "null_mutex.h"
27 #include "spin_rw_mutex.h"
28 #include "null_rw_mutex.h"
29 #include "task.h"
31 #include "tbb_exception.h"
35 #include "tbb_profiling.h"
36 #include "task_arena.h"
37 
38 #if TBB_USE_THREADING_TOOLS && TBB_PREVIEW_FLOW_GRAPH_TRACE && ( __linux__ || __APPLE__ )
39  #if __INTEL_COMPILER
40  // Disabled warning "routine is both inline and noinline"
41  #pragma warning (push)
42  #pragma warning( disable: 2196 )
43  #endif
44  #define __TBB_NOINLINE_SYM __attribute__((noinline))
45 #else
46  #define __TBB_NOINLINE_SYM
47 #endif
48 
49 #if __TBB_PREVIEW_ASYNC_MSG
50 #include <vector> // std::vector in internal::async_storage
51 #include <memory> // std::shared_ptr in async_msg
52 #endif
53 
54 #if __TBB_PREVIEW_STREAMING_NODE
55 // For streaming_node
56 #include <array> // std::array
57 #include <unordered_map> // std::unordered_map
58 #include <type_traits> // std::decay, std::true_type, std::false_type
59 #endif // __TBB_PREVIEW_STREAMING_NODE
60 
61 #if TBB_DEPRECATED_FLOW_ENQUEUE
62 #define FLOW_SPAWN(a) tbb::task::enqueue((a))
63 #else
64 #define FLOW_SPAWN(a) tbb::task::spawn((a))
65 #endif
66 
67 #if TBB_DEPRECATED_FLOW_NODE_ALLOCATOR
68 #define __TBB_DEFAULT_NODE_ALLOCATOR(T) cache_aligned_allocator<T>
69 #else
70 #define __TBB_DEFAULT_NODE_ALLOCATOR(T) null_type
71 #endif
72 
73 // use the VC10 or gcc version of tuple if it is available.
74 #if __TBB_CPP11_TUPLE_PRESENT
75  #include <tuple>
76 namespace tbb {
77  namespace flow {
78  using std::tuple;
79  using std::tuple_size;
80  using std::tuple_element;
81  using std::get;
82  }
83 }
84 #else
85  #include "compat/tuple"
86 #endif
87 
88 #include<list>
89 #include<queue>
90 
101 namespace tbb {
102 namespace flow {
103 
105 enum concurrency { unlimited = 0, serial = 1 };
106 
107 namespace interface11 {
108 
110 struct null_type {};
111 
113 class continue_msg {};
114 
116 template< typename T > class sender;
117 template< typename T > class receiver;
118 class continue_receiver;
119 
120 template< typename T, typename U > class limiter_node; // needed for resetting decrementer
121 
122 template< typename R, typename B > class run_and_put_task;
123 
124 namespace internal {
125 
126 template<typename T, typename M> class successor_cache;
127 template<typename T, typename M> class broadcast_cache;
128 template<typename T, typename M> class round_robin_cache;
129 template<typename T, typename M> class predecessor_cache;
130 template<typename T, typename M> class reservable_predecessor_cache;
131 
132 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
133 namespace order {
134 struct following;
135 struct preceding;
136 }
137 template<typename Order, typename... Args> struct node_set;
138 #endif
139 
140 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
141 // Holder of edges both for caches and for those nodes which do not have predecessor caches.
142 // C == receiver< ... > or sender< ... >, depending.
143 template<typename C>
144 class edge_container {
145 
146 public:
147  typedef std::list<C *, tbb::tbb_allocator<C *> > edge_list_type;
148 
149  void add_edge(C &s) {
150  built_edges.push_back(&s);
151  }
152 
153  void delete_edge(C &s) {
154  for (typename edge_list_type::iterator i = built_edges.begin(); i != built_edges.end(); ++i) {
155  if (*i == &s) {
156  (void)built_edges.erase(i);
157  return; // only remove one predecessor per request
158  }
159  }
160  }
161 
162  void copy_edges(edge_list_type &v) {
163  v = built_edges;
164  }
165 
166  size_t edge_count() {
167  return (size_t)(built_edges.size());
168  }
169 
170  void clear() {
171  built_edges.clear();
172  }
173 
174  // methods remove the statement from all predecessors/successors liste in the edge
175  // container.
176  template< typename S > void sender_extract(S &s);
177  template< typename R > void receiver_extract(R &r);
178 
179 private:
180  edge_list_type built_edges;
181 }; // class edge_container
182 #endif /* TBB_DEPRECATED_FLOW_NODE_EXTRACTION */
183 
184 } // namespace internal
185 
186 } // namespace interfaceX
187 } // namespace flow
188 } // namespace tbb
189 
192 
193 namespace tbb {
194 namespace flow {
195 namespace interface11 {
196 
197 // enqueue left task if necessary. Returns the non-enqueued task if there is one.
198 static inline tbb::task *combine_tasks(graph& g, tbb::task * left, tbb::task * right) {
199  // if no RHS task, don't change left.
200  if (right == NULL) return left;
201  // right != NULL
202  if (left == NULL) return right;
203  if (left == SUCCESSFULLY_ENQUEUED) return right;
204  // left contains a task
205  if (right != SUCCESSFULLY_ENQUEUED) {
206  // both are valid tasks
208  return right;
209  }
210  return left;
211 }
212 
213 #if __TBB_PREVIEW_ASYNC_MSG
214 
215 template < typename T > class __TBB_DEPRECATED async_msg;
216 
217 namespace internal {
218 
219 template < typename T > class async_storage;
220 
221 template< typename T, typename = void >
222 struct async_helpers {
223  typedef async_msg<T> async_type;
224  typedef T filtered_type;
225 
226  static const bool is_async_type = false;
227 
228  static const void* to_void_ptr(const T& t) {
229  return static_cast<const void*>(&t);
230  }
231 
232  static void* to_void_ptr(T& t) {
233  return static_cast<void*>(&t);
234  }
235 
236  static const T& from_void_ptr(const void* p) {
237  return *static_cast<const T*>(p);
238  }
239 
240  static T& from_void_ptr(void* p) {
241  return *static_cast<T*>(p);
242  }
243 
244  static task* try_put_task_wrapper_impl(receiver<T>* const this_recv, const void *p, bool is_async) {
245  if (is_async) {
246  // This (T) is NOT async and incoming 'A<X> t' IS async
247  // Get data from async_msg
248  const async_msg<filtered_type>& msg = async_helpers< async_msg<filtered_type> >::from_void_ptr(p);
249  task* const new_task = msg.my_storage->subscribe(*this_recv, this_recv->graph_reference());
250  // finalize() must be called after subscribe() because set() can be called in finalize()
251  // and 'this_recv' client must be subscribed by this moment
252  msg.finalize();
253  return new_task;
254  }
255  else {
256  // Incoming 't' is NOT async
257  return this_recv->try_put_task(from_void_ptr(p));
258  }
259  }
260 };
261 
262 template< typename T >
263 struct async_helpers< T, typename std::enable_if< std::is_base_of<async_msg<typename T::async_msg_data_type>, T>::value >::type > {
264  typedef T async_type;
265  typedef typename T::async_msg_data_type filtered_type;
266 
267  static const bool is_async_type = true;
268 
269  // Receiver-classes use const interfaces
270  static const void* to_void_ptr(const T& t) {
271  return static_cast<const void*>(&static_cast<const async_msg<filtered_type>&>(t));
272  }
273 
274  static void* to_void_ptr(T& t) {
275  return static_cast<void*>(&static_cast<async_msg<filtered_type>&>(t));
276  }
277 
278  // Sender-classes use non-const interfaces
279  static const T& from_void_ptr(const void* p) {
280  return *static_cast<const T*>(static_cast<const async_msg<filtered_type>*>(p));
281  }
282 
283  static T& from_void_ptr(void* p) {
284  return *static_cast<T*>(static_cast<async_msg<filtered_type>*>(p));
285  }
286 
287  // Used in receiver<T> class
288  static task* try_put_task_wrapper_impl(receiver<T>* const this_recv, const void *p, bool is_async) {
289  if (is_async) {
290  // Both are async
291  return this_recv->try_put_task(from_void_ptr(p));
292  }
293  else {
294  // This (T) is async and incoming 'X t' is NOT async
295  // Create async_msg for X
296  const filtered_type& t = async_helpers<filtered_type>::from_void_ptr(p);
297  const T msg(t);
298  return this_recv->try_put_task(msg);
299  }
300  }
301 };
302 
303 class untyped_receiver;
304 
305 class untyped_sender {
306  template< typename, typename > friend class internal::predecessor_cache;
307  template< typename, typename > friend class internal::reservable_predecessor_cache;
308 public:
310  typedef untyped_receiver successor_type;
311 
312  virtual ~untyped_sender() {}
313 
314  // NOTE: Following part of PUBLIC section is copy-paste from original sender<T> class
315 
316  // TODO: Prevent untyped successor registration
317 
319  virtual bool register_successor( successor_type &r ) = 0;
320 
322  virtual bool remove_successor( successor_type &r ) = 0;
323 
325  virtual bool try_release( ) { return false; }
326 
328  virtual bool try_consume( ) { return false; }
329 
330 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
331  typedef internal::edge_container<successor_type> built_successors_type;
333  typedef built_successors_type::edge_list_type successor_list_type;
334  virtual built_successors_type &built_successors() = 0;
335  virtual void internal_add_built_successor( successor_type & ) = 0;
336  virtual void internal_delete_built_successor( successor_type & ) = 0;
337  virtual void copy_successors( successor_list_type &) = 0;
338  virtual size_t successor_count() = 0;
339 #endif /* TBB_DEPRECATED_FLOW_NODE_EXTRACTION */
340 protected:
342  template< typename X >
343  bool try_get( X &t ) {
344  return try_get_wrapper( internal::async_helpers<X>::to_void_ptr(t), internal::async_helpers<X>::is_async_type );
345  }
346 
348  template< typename X >
349  bool try_reserve( X &t ) {
350  return try_reserve_wrapper( internal::async_helpers<X>::to_void_ptr(t), internal::async_helpers<X>::is_async_type );
351  }
352 
353  virtual bool try_get_wrapper( void* p, bool is_async ) = 0;
354  virtual bool try_reserve_wrapper( void* p, bool is_async ) = 0;
355 };
356 
357 class untyped_receiver {
358  template< typename, typename > friend class run_and_put_task;
359 
360  template< typename, typename > friend class internal::broadcast_cache;
361  template< typename, typename > friend class internal::round_robin_cache;
362  template< typename, typename > friend class internal::successor_cache;
363 
364 #if __TBB_PREVIEW_OPENCL_NODE
365  template< typename, typename > friend class proxy_dependency_receiver;
366 #endif /* __TBB_PREVIEW_OPENCL_NODE */
367 public:
369  typedef untyped_sender predecessor_type;
370 
372  virtual ~untyped_receiver() {}
373 
375  template<typename X>
376  bool try_put(const X& t) {
377  task *res = try_put_task(t);
378  if (!res) return false;
379  if (res != SUCCESSFULLY_ENQUEUED) internal::spawn_in_graph_arena(graph_reference(), *res);
380  return true;
381  }
382 
383  // NOTE: Following part of PUBLIC section is copy-paste from original receiver<T> class
384 
385  // TODO: Prevent untyped predecessor registration
386 
388  virtual bool register_predecessor( predecessor_type & ) { return false; }
389 
391  virtual bool remove_predecessor( predecessor_type & ) { return false; }
392 
393 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
394  typedef internal::edge_container<predecessor_type> built_predecessors_type;
395  typedef built_predecessors_type::edge_list_type predecessor_list_type;
396  virtual built_predecessors_type &built_predecessors() = 0;
397  virtual void internal_add_built_predecessor( predecessor_type & ) = 0;
398  virtual void internal_delete_built_predecessor( predecessor_type & ) = 0;
399  virtual void copy_predecessors( predecessor_list_type & ) = 0;
400  virtual size_t predecessor_count() = 0;
401 #endif /* TBB_DEPRECATED_FLOW_NODE_EXTRACTION */
402 protected:
403  template<typename X>
404  task *try_put_task(const X& t) {
405  return try_put_task_wrapper( internal::async_helpers<X>::to_void_ptr(t), internal::async_helpers<X>::is_async_type );
406  }
407 
408  virtual task* try_put_task_wrapper( const void* p, bool is_async ) = 0;
409 
410  virtual graph& graph_reference() const = 0;
411 
412  // NOTE: Following part of PROTECTED and PRIVATE sections is copy-paste from original receiver<T> class
413 
415  virtual void reset_receiver(reset_flags f = rf_reset_protocol) = 0;
416 
417  virtual bool is_continue_receiver() { return false; }
418 };
419 
420 } // namespace internal
421 
423 template< typename T >
424 class sender : public internal::untyped_sender {
425 public:
427  __TBB_DEPRECATED typedef T output_type;
428 
429  __TBB_DEPRECATED typedef typename internal::async_helpers<T>::filtered_type filtered_type;
430 
432  virtual bool try_get( T & ) { return false; }
433 
435  virtual bool try_reserve( T & ) { return false; }
436 
437 protected:
438  virtual bool try_get_wrapper( void* p, bool is_async ) __TBB_override {
439  // Both async OR both are NOT async
440  if ( internal::async_helpers<T>::is_async_type == is_async ) {
441  return try_get( internal::async_helpers<T>::from_void_ptr(p) );
442  }
443  // Else: this (T) is async OR incoming 't' is async
444  __TBB_ASSERT(false, "async_msg interface does not support 'pull' protocol in try_get()");
445  return false;
446  }
447 
448  virtual bool try_reserve_wrapper( void* p, bool is_async ) __TBB_override {
449  // Both async OR both are NOT async
450  if ( internal::async_helpers<T>::is_async_type == is_async ) {
451  return try_reserve( internal::async_helpers<T>::from_void_ptr(p) );
452  }
453  // Else: this (T) is async OR incoming 't' is async
454  __TBB_ASSERT(false, "async_msg interface does not support 'pull' protocol in try_reserve()");
455  return false;
456  }
457 }; // class sender<T>
458 
460 template< typename T >
461 class receiver : public internal::untyped_receiver {
462  template< typename > friend class internal::async_storage;
463  template< typename, typename > friend struct internal::async_helpers;
464 public:
466  __TBB_DEPRECATED typedef T input_type;
467 
468  __TBB_DEPRECATED typedef typename internal::async_helpers<T>::filtered_type filtered_type;
469 
471  bool try_put( const typename internal::async_helpers<T>::filtered_type& t ) {
472  return internal::untyped_receiver::try_put(t);
473  }
474 
475  bool try_put( const typename internal::async_helpers<T>::async_type& t ) {
476  return internal::untyped_receiver::try_put(t);
477  }
478 
479 protected:
480  virtual task* try_put_task_wrapper( const void *p, bool is_async ) __TBB_override {
481  return internal::async_helpers<T>::try_put_task_wrapper_impl(this, p, is_async);
482  }
483 
485  virtual task *try_put_task(const T& t) = 0;
486 
487 }; // class receiver<T>
488 
489 #else // __TBB_PREVIEW_ASYNC_MSG
490 
492 template< typename T >
493 class sender {
494 public:
497 
500 
501  virtual ~sender() {}
502 
503  // NOTE: Following part of PUBLIC section is partly copy-pasted in sender<T> under #if __TBB_PREVIEW_ASYNC_MSG
504 
506  __TBB_DEPRECATED virtual bool register_successor( successor_type &r ) = 0;
507 
509  __TBB_DEPRECATED virtual bool remove_successor( successor_type &r ) = 0;
510 
512  virtual bool try_get( T & ) { return false; }
513 
515  virtual bool try_reserve( T & ) { return false; }
516 
518  virtual bool try_release( ) { return false; }
519 
521  virtual bool try_consume( ) { return false; }
522 
523 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
524  __TBB_DEPRECATED typedef typename internal::edge_container<successor_type> built_successors_type;
526  __TBB_DEPRECATED typedef typename built_successors_type::edge_list_type successor_list_type;
527  __TBB_DEPRECATED virtual built_successors_type &built_successors() = 0;
528  __TBB_DEPRECATED virtual void internal_add_built_successor( successor_type & ) = 0;
529  __TBB_DEPRECATED virtual void internal_delete_built_successor( successor_type & ) = 0;
530  __TBB_DEPRECATED virtual void copy_successors( successor_list_type &) = 0;
531  __TBB_DEPRECATED virtual size_t successor_count() = 0;
532 #endif /* TBB_DEPRECATED_FLOW_NODE_EXTRACTION */
533 }; // class sender<T>
534 
536 template< typename T >
537 class receiver {
538 public:
541 
544 
546  virtual ~receiver() {}
547 
549  bool try_put( const T& t ) {
550  task *res = try_put_task(t);
551  if (!res) return false;
553  return true;
554  }
555 
557 protected:
558  template< typename R, typename B > friend class run_and_put_task;
559  template< typename X, typename Y > friend class internal::broadcast_cache;
560  template< typename X, typename Y > friend class internal::round_robin_cache;
561  virtual task *try_put_task(const T& t) = 0;
562  virtual graph& graph_reference() const = 0;
563 public:
564  // NOTE: Following part of PUBLIC and PROTECTED sections is copy-pasted in receiver<T> under #if __TBB_PREVIEW_ASYNC_MSG
565 
567  __TBB_DEPRECATED virtual bool register_predecessor( predecessor_type & ) { return false; }
568 
570  __TBB_DEPRECATED virtual bool remove_predecessor( predecessor_type & ) { return false; }
571 
572 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
573  __TBB_DEPRECATED typedef typename internal::edge_container<predecessor_type> built_predecessors_type;
574  __TBB_DEPRECATED typedef typename built_predecessors_type::edge_list_type predecessor_list_type;
575  __TBB_DEPRECATED virtual built_predecessors_type &built_predecessors() = 0;
576  __TBB_DEPRECATED virtual void internal_add_built_predecessor( predecessor_type & ) = 0;
577  __TBB_DEPRECATED virtual void internal_delete_built_predecessor( predecessor_type & ) = 0;
578  __TBB_DEPRECATED virtual void copy_predecessors( predecessor_list_type & ) = 0;
579  __TBB_DEPRECATED virtual size_t predecessor_count() = 0;
580 #endif /* TBB_DEPRECATED_FLOW_NODE_EXTRACTION */
581 
582 protected:
584  virtual void reset_receiver(reset_flags f = rf_reset_protocol) = 0;
585 
586  template<typename TT, typename M> friend class internal::successor_cache;
587  virtual bool is_continue_receiver() { return false; }
588 
589 #if __TBB_PREVIEW_OPENCL_NODE
590  template< typename, typename > friend class proxy_dependency_receiver;
591 #endif /* __TBB_PREVIEW_OPENCL_NODE */
592 }; // class receiver<T>
593 
594 #endif // __TBB_PREVIEW_ASYNC_MSG
595 
597 
598 class continue_receiver : public receiver< continue_msg > {
599 public:
600 
603 
606 
609  __TBB_FLOW_GRAPH_PRIORITY_ARG1(int number_of_predecessors, node_priority_t priority)) {
610  my_predecessor_count = my_initial_predecessor_count = number_of_predecessors;
611  my_current_count = 0;
612  __TBB_FLOW_GRAPH_PRIORITY_EXPR( my_priority = priority; )
613  }
614 
618  my_current_count = 0;
619  __TBB_FLOW_GRAPH_PRIORITY_EXPR( my_priority = src.my_priority; )
620  }
621 
626  return true;
627  }
628 
630 
636  return true;
637  }
638 
639 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
640  __TBB_DEPRECATED typedef internal::edge_container<predecessor_type> built_predecessors_type;
641  __TBB_DEPRECATED typedef built_predecessors_type::edge_list_type predecessor_list_type;
642  built_predecessors_type &built_predecessors() __TBB_override { return my_built_predecessors; }
643 
644  __TBB_DEPRECATED void internal_add_built_predecessor( predecessor_type &s) __TBB_override {
646  my_built_predecessors.add_edge( s );
647  }
648 
649  __TBB_DEPRECATED void internal_delete_built_predecessor( predecessor_type &s) __TBB_override {
651  my_built_predecessors.delete_edge(s);
652  }
653 
654  __TBB_DEPRECATED void copy_predecessors( predecessor_list_type &v) __TBB_override {
656  my_built_predecessors.copy_edges(v);
657  }
658 
659  __TBB_DEPRECATED size_t predecessor_count() __TBB_override {
661  return my_built_predecessors.edge_count();
662  }
663 
664 #endif /* TBB_DEPRECATED_FLOW_NODE_EXTRACTION */
665 
666 protected:
667  template< typename R, typename B > friend class run_and_put_task;
668  template<typename X, typename Y> friend class internal::broadcast_cache;
669  template<typename X, typename Y> friend class internal::round_robin_cache;
670  // execute body is supposed to be too small to create a task for.
672  {
675  return SUCCESSFULLY_ENQUEUED;
676  else
677  my_current_count = 0;
678  }
679  task * res = execute();
680  return res? res : SUCCESSFULLY_ENQUEUED;
681  }
682 
683 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
684  // continue_receiver must contain its own built_predecessors because it does
685  // not have a node_cache.
686  built_predecessors_type my_built_predecessors;
687 #endif
693  // the friend declaration in the base class did not eliminate the "protected class"
694  // error in gcc 4.1.2
695  template<typename U, typename V> friend class tbb::flow::interface11::limiter_node;
696 
698  my_current_count = 0;
699  if (f & rf_clear_edges) {
700 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
701  my_built_predecessors.clear();
702 #endif
704  }
705  }
706 
708 
710  virtual task * execute() = 0;
711  template<typename TT, typename M> friend class internal::successor_cache;
712  bool is_continue_receiver() __TBB_override { return true; }
713 
714 }; // class continue_receiver
715 
716 } // interfaceX
717 
718 #if __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING
719  template <typename K, typename T>
720  K key_from_message( const T &t ) {
721  return t.key();
722  }
723 #endif /* __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING */
724 
725  using interface11::sender;
726  using interface11::receiver;
727  using interface11::continue_receiver;
728 } // flow
729 } // tbb
730 
733 
734 namespace tbb {
735 namespace flow {
736 namespace interface11 {
737 
741 #if __TBB_PREVIEW_ASYNC_MSG
743 #endif
744 using namespace internal::graph_policy_namespace;
745 
746 template <typename C, typename N>
747 graph_iterator<C,N>::graph_iterator(C *g, bool begin) : my_graph(g), current_node(NULL)
748 {
749  if (begin) current_node = my_graph->my_nodes;
750  //else it is an end iterator by default
751 }
752 
753 template <typename C, typename N>
755  __TBB_ASSERT(current_node, "graph_iterator at end");
756  return *operator->();
757 }
758 
759 template <typename C, typename N>
761  return current_node;
762 }
763 
764 template <typename C, typename N>
766  if (current_node) current_node = current_node->next;
767 }
768 
769 } // namespace interfaceX
770 
771 namespace interface10 {
773 inline graph::graph() : my_nodes(NULL), my_nodes_last(NULL), my_task_arena(NULL) {
775  own_context = true;
776  cancelled = false;
777  caught_exception = false;
778  my_context = new task_group_context(tbb::internal::FLOW_TASKS);
782  my_is_active = true;
783 }
784 
785 inline graph::graph(task_group_context& use_this_context) :
786  my_context(&use_this_context), my_nodes(NULL), my_nodes_last(NULL), my_task_arena(NULL) {
788  own_context = false;
789  cancelled = false;
790  caught_exception = false;
794  my_is_active = true;
795 }
796 
797 inline graph::~graph() {
798  wait_for_all();
800  tbb::task::destroy(*my_root_task);
801  if (own_context) delete my_context;
802  delete my_task_arena;
803 }
804 
805 inline void graph::reserve_wait() {
806  if (my_root_task) {
809  }
810 }
811 
812 inline void graph::release_wait() {
813  if (my_root_task) {
816  }
817 }
818 
820  n->next = NULL;
821  {
823  n->prev = my_nodes_last;
824  if (my_nodes_last) my_nodes_last->next = n;
825  my_nodes_last = n;
826  if (!my_nodes) my_nodes = n;
827  }
828 }
829 
831  {
833  __TBB_ASSERT(my_nodes && my_nodes_last, "graph::remove_node: Error: no registered nodes");
834  if (n->prev) n->prev->next = n->next;
835  if (n->next) n->next->prev = n->prev;
836  if (my_nodes_last == n) my_nodes_last = n->prev;
837  if (my_nodes == n) my_nodes = n->next;
838  }
839  n->prev = n->next = NULL;
840 }
841 
843  // reset context
845 
846  if(my_context) my_context->reset();
847  cancelled = false;
848  caught_exception = false;
849  // reset all the nodes comprising the graph
850  for(iterator ii = begin(); ii != end(); ++ii) {
851  tbb::flow::interface11::graph_node *my_p = &(*ii);
852  my_p->reset_node(f);
853  }
854  // Reattach the arena. Might be useful to run the graph in a particular task_arena
855  // while not limiting graph lifetime to a single task_arena::execute() call.
856  prepare_task_arena( /*reinit=*/true );
858  // now spawn the tasks necessary to start the graph
859  for(task_list_type::iterator rti = my_reset_task_list.begin(); rti != my_reset_task_list.end(); ++rti) {
861  }
862  my_reset_task_list.clear();
863 }
864 
865 inline graph::iterator graph::begin() { return iterator(this, true); }
866 
867 inline graph::iterator graph::end() { return iterator(this, false); }
868 
869 inline graph::const_iterator graph::begin() const { return const_iterator(this, true); }
870 
871 inline graph::const_iterator graph::end() const { return const_iterator(this, false); }
872 
873 inline graph::const_iterator graph::cbegin() const { return const_iterator(this, true); }
874 
875 inline graph::const_iterator graph::cend() const { return const_iterator(this, false); }
876 
877 #if TBB_PREVIEW_FLOW_GRAPH_TRACE
878 inline void graph::set_name(const char *name) {
880 }
881 #endif
882 
883 } // namespace interface10
884 
885 namespace interface11 {
886 
887 inline graph_node::graph_node(graph& g) : my_graph(g) {
888  my_graph.register_node(this);
889 }
890 
892  my_graph.remove_node(this);
893 }
894 
896 
897 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
898 using internal::node_set;
899 #endif
900 
902 template < typename Output >
903 class input_node : public graph_node, public sender< Output > {
904 public:
906  typedef Output output_type;
907 
910 
911  //Source node has no input type
913 
914 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
915  typedef typename sender<output_type>::built_successors_type built_successors_type;
916  typedef typename sender<output_type>::successor_list_type successor_list_type;
917 #endif
918 
920  template< typename Body >
922  : graph_node(g), my_active(false),
923  my_body( new internal::source_body_leaf< output_type, Body>(body) ),
924  my_init_body( new internal::source_body_leaf< output_type, Body>(body) ),
925  my_reserved(false), my_has_cached_item(false)
926  {
927  my_successors.set_owner(this);
928  tbb::internal::fgt_node_with_body( CODEPTR(), tbb::internal::FLOW_SOURCE_NODE, &this->my_graph,
929  static_cast<sender<output_type> *>(this), this->my_body );
930  }
931 
932 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
933  template <typename Body, typename... Successors>
934  input_node( const node_set<internal::order::preceding, Successors...>& successors, Body body )
935  : input_node(successors.graph_reference(), body) {
936  make_edges(*this, successors);
937  }
938 #endif
939 
942  graph_node(src.my_graph), sender<Output>(),
943  my_active(false),
944  my_body( src.my_init_body->clone() ), my_init_body(src.my_init_body->clone() ),
945  my_reserved(false), my_has_cached_item(false)
946  {
947  my_successors.set_owner(this);
948  tbb::internal::fgt_node_with_body(CODEPTR(), tbb::internal::FLOW_SOURCE_NODE, &this->my_graph,
949  static_cast<sender<output_type> *>(this), this->my_body );
950  }
951 
953  ~input_node() { delete my_body; delete my_init_body; }
954 
955 #if TBB_PREVIEW_FLOW_GRAPH_TRACE
956  void set_name( const char *name ) __TBB_override {
958  }
959 #endif
960 
964  my_successors.register_successor(r);
965  if ( my_active )
966  spawn_put();
967  return true;
968  }
969 
973  my_successors.remove_successor(r);
974  return true;
975  }
976 
977 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
978 
979  built_successors_type &built_successors() __TBB_override { return my_successors.built_successors(); }
980 
981  void internal_add_built_successor( successor_type &r) __TBB_override {
983  my_successors.internal_add_built_successor(r);
984  }
985 
986  void internal_delete_built_successor( successor_type &r) __TBB_override {
988  my_successors.internal_delete_built_successor(r);
989  }
990 
991  size_t successor_count() __TBB_override {
993  return my_successors.successor_count();
994  }
995 
996  void copy_successors(successor_list_type &v) __TBB_override {
998  my_successors.copy_successors(v);
999  }
1000 #endif /* TBB_DEPRECATED_FLOW_NODE_EXTRACTION */
1001 
1005  if ( my_reserved )
1006  return false;
1007 
1008  if ( my_has_cached_item ) {
1009  v = my_cached_item;
1010  my_has_cached_item = false;
1011  return true;
1012  }
1013  // we've been asked to provide an item, but we have none. enqueue a task to
1014  // provide one.
1015  if ( my_active )
1016  spawn_put();
1017  return false;
1018  }
1019 
1023  if ( my_reserved ) {
1024  return false;
1025  }
1026 
1027  if ( my_has_cached_item ) {
1028  v = my_cached_item;
1029  my_reserved = true;
1030  return true;
1031  } else {
1032  return false;
1033  }
1034  }
1035 
1037 
1040  __TBB_ASSERT( my_reserved && my_has_cached_item, "releasing non-existent reservation" );
1041  my_reserved = false;
1042  if(!my_successors.empty())
1043  spawn_put();
1044  return true;
1045  }
1046 
1050  __TBB_ASSERT( my_reserved && my_has_cached_item, "consuming non-existent reservation" );
1051  my_reserved = false;
1052  my_has_cached_item = false;
1053  if ( !my_successors.empty() ) {
1054  spawn_put();
1055  }
1056  return true;
1057  }
1058 
1060  void activate() {
1062  my_active = true;
1063  if (!my_successors.empty())
1064  spawn_put();
1065  }
1066 
1067  template<typename Body>
1069  internal::source_body<output_type> &body_ref = *this->my_body;
1070  return dynamic_cast< internal::source_body_leaf<output_type, Body> & >(body_ref).get_body();
1071  }
1072 
1073 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
1074  void extract( ) __TBB_override {
1075  my_successors.built_successors().sender_extract(*this); // removes "my_owner" == this from each successor
1076  my_active = false;
1077  my_reserved = false;
1079  }
1080 #endif
1081 
1082 protected:
1083 
1086  my_active = false;
1087  my_reserved = false;
1088  my_has_cached_item = false;
1089 
1090  if(f & rf_clear_edges) my_successors.clear();
1091  if(f & rf_reset_bodies) {
1093  delete my_body;
1094  my_body = tmp;
1095  }
1096  }
1097 
1098 private:
1107 
1108  // used by apply_body_bypass, can invoke body of node.
1111  if ( my_reserved ) {
1112  return false;
1113  }
1114  if ( !my_has_cached_item ) {
1116  bool r = (*my_body)(my_cached_item);
1118  if (r) {
1119  my_has_cached_item = true;
1120  }
1121  }
1122  if ( my_has_cached_item ) {
1123  v = my_cached_item;
1124  my_reserved = true;
1125  return true;
1126  } else {
1127  return false;
1128  }
1129  }
1130 
1132  return ( new ( task::allocate_additional_child_of( *(this->my_graph.root_task()) ) )
1134  }
1135 
1137  void spawn_put( ) {
1138  if(internal::is_graph_active(this->my_graph)) {
1140  }
1141  }
1142 
1146  output_type v;
1147  if ( !try_reserve_apply_body(v) )
1148  return NULL;
1149 
1150  task *last_task = my_successors.try_put_task(v);
1151  if ( last_task )
1152  try_consume();
1153  else
1154  try_release();
1155  return last_task;
1156  }
1157 }; // class input_node
1158 
1159 #if TBB_USE_SOURCE_NODE_AS_ALIAS
1160 template < typename Output >
1161 class source_node : public input_node <Output> {
1162 public:
1164  template< typename Body >
1165  __TBB_NOINLINE_SYM source_node( graph &g, Body body )
1166  : input_node<Output>(g, body)
1167  {
1168  }
1169 
1170 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
1171  template <typename Body, typename... Successors>
1172  source_node( const node_set<internal::order::preceding, Successors...>& successors, Body body )
1173  : input_node<Output>(successors, body) {
1174  }
1175 #endif
1176 };
1177 #else // TBB_USE_SOURCE_NODE_AS_ALIAS
1178 template < typename Output > class
1180 __TBB_DEPRECATED_MSG("TBB Warning: tbb::flow::source_node is deprecated, use tbb::flow::input_node." )
1181 source_node : public graph_node, public sender< Output > {
1182 public:
1184  typedef Output output_type;
1185 
1188 
1189  //Source node has no input type
1191 
1192 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
1193  typedef typename sender<output_type>::built_successors_type built_successors_type;
1194  typedef typename sender<output_type>::successor_list_type successor_list_type;
1195 #endif
1196 
1198  template< typename Body >
1199  __TBB_NOINLINE_SYM source_node( graph &g, Body body, bool is_active = true )
1200  : graph_node(g), my_active(is_active), init_my_active(is_active),
1201  my_body( new internal::source_body_leaf< output_type, Body>(body) ),
1202  my_init_body( new internal::source_body_leaf< output_type, Body>(body) ),
1203  my_reserved(false), my_has_cached_item(false)
1204  {
1205  my_successors.set_owner(this);
1206  tbb::internal::fgt_node_with_body( CODEPTR(), tbb::internal::FLOW_SOURCE_NODE, &this->my_graph,
1207  static_cast<sender<output_type> *>(this), this->my_body );
1208  }
1209 
1210 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
1211  template <typename Body, typename... Successors>
1212  source_node( const node_set<internal::order::preceding, Successors...>& successors, Body body, bool is_active = true )
1213  : source_node(successors.graph_reference(), body, is_active) {
1214  make_edges(*this, successors);
1215  }
1216 #endif
1217 
1220  graph_node(src.my_graph), sender<Output>(),
1221  my_active(src.init_my_active),
1222  init_my_active(src.init_my_active), my_body( src.my_init_body->clone() ), my_init_body(src.my_init_body->clone() ),
1223  my_reserved(false), my_has_cached_item(false)
1224  {
1225  my_successors.set_owner(this);
1226  tbb::internal::fgt_node_with_body(CODEPTR(), tbb::internal::FLOW_SOURCE_NODE, &this->my_graph,
1227  static_cast<sender<output_type> *>(this), this->my_body );
1228  }
1229 
1231  ~source_node() { delete my_body; delete my_init_body; }
1232 
1233 #if TBB_PREVIEW_FLOW_GRAPH_TRACE
1234  void set_name( const char *name ) __TBB_override {
1236  }
1237 #endif
1238 
1241  spin_mutex::scoped_lock lock(my_mutex);
1242  my_successors.register_successor(r);
1243  if ( my_active )
1244  spawn_put();
1245  return true;
1246  }
1247 
1250  spin_mutex::scoped_lock lock(my_mutex);
1251  my_successors.remove_successor(r);
1252  return true;
1253  }
1254 
1255 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
1256 
1257  built_successors_type &built_successors() __TBB_override { return my_successors.built_successors(); }
1258 
1259  void internal_add_built_successor( successor_type &r) __TBB_override {
1260  spin_mutex::scoped_lock lock(my_mutex);
1261  my_successors.internal_add_built_successor(r);
1262  }
1263 
1264  void internal_delete_built_successor( successor_type &r) __TBB_override {
1265  spin_mutex::scoped_lock lock(my_mutex);
1266  my_successors.internal_delete_built_successor(r);
1267  }
1268 
1269  size_t successor_count() __TBB_override {
1270  spin_mutex::scoped_lock lock(my_mutex);
1271  return my_successors.successor_count();
1272  }
1273 
1274  void copy_successors(successor_list_type &v) __TBB_override {
1275  spin_mutex::scoped_lock l(my_mutex);
1276  my_successors.copy_successors(v);
1277  }
1278 #endif /* TBB_DEPRECATED_FLOW_NODE_EXTRACTION */
1279 
1282  spin_mutex::scoped_lock lock(my_mutex);
1283  if ( my_reserved )
1284  return false;
1285 
1286  if ( my_has_cached_item ) {
1287  v = my_cached_item;
1288  my_has_cached_item = false;
1289  return true;
1290  }
1291  // we've been asked to provide an item, but we have none. enqueue a task to
1292  // provide one.
1293  spawn_put();
1294  return false;
1295  }
1296 
1299  spin_mutex::scoped_lock lock(my_mutex);
1300  if ( my_reserved ) {
1301  return false;
1302  }
1303 
1304  if ( my_has_cached_item ) {
1305  v = my_cached_item;
1306  my_reserved = true;
1307  return true;
1308  } else {
1309  return false;
1310  }
1311  }
1312 
1314 
1316  spin_mutex::scoped_lock lock(my_mutex);
1317  __TBB_ASSERT( my_reserved && my_has_cached_item, "releasing non-existent reservation" );
1318  my_reserved = false;
1319  if(!my_successors.empty())
1320  spawn_put();
1321  return true;
1322  }
1323 
1326  spin_mutex::scoped_lock lock(my_mutex);
1327  __TBB_ASSERT( my_reserved && my_has_cached_item, "consuming non-existent reservation" );
1328  my_reserved = false;
1329  my_has_cached_item = false;
1330  if ( !my_successors.empty() ) {
1331  spawn_put();
1332  }
1333  return true;
1334  }
1335 
1337  void activate() {
1338  spin_mutex::scoped_lock lock(my_mutex);
1339  my_active = true;
1340  if (!my_successors.empty())
1341  spawn_put();
1342  }
1343 
1344  template<typename Body>
1346  internal::source_body<output_type> &body_ref = *this->my_body;
1347  return dynamic_cast< internal::source_body_leaf<output_type, Body> & >(body_ref).get_body();
1348  }
1349 
1350 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
1351  void extract( ) __TBB_override {
1352  my_successors.built_successors().sender_extract(*this); // removes "my_owner" == this from each successor
1353  my_active = init_my_active;
1354  my_reserved = false;
1355  if(my_has_cached_item) my_has_cached_item = false;
1356  }
1357 #endif
1358 
1359 protected:
1360 
1363  my_active = init_my_active;
1364  my_reserved =false;
1365  if(my_has_cached_item) {
1366  my_has_cached_item = false;
1367  }
1368  if(f & rf_clear_edges) my_successors.clear();
1369  if(f & rf_reset_bodies) {
1370  internal::source_body<output_type> *tmp = my_init_body->clone();
1371  delete my_body;
1372  my_body = tmp;
1373  }
1374  if(my_active)
1375  internal::add_task_to_graph_reset_list(this->my_graph, create_put_task());
1376  }
1377 
1378 private:
1388 
1389  // used by apply_body_bypass, can invoke body of node.
1391  spin_mutex::scoped_lock lock(my_mutex);
1392  if ( my_reserved ) {
1393  return false;
1394  }
1395  if ( !my_has_cached_item ) {
1396  tbb::internal::fgt_begin_body( my_body );
1397  bool r = (*my_body)(my_cached_item);
1398  tbb::internal::fgt_end_body( my_body );
1399  if (r) {
1400  my_has_cached_item = true;
1401  }
1402  }
1403  if ( my_has_cached_item ) {
1404  v = my_cached_item;
1405  my_reserved = true;
1406  return true;
1407  } else {
1408  return false;
1409  }
1410  }
1411 
1412  // when resetting, and if the source_node was created with my_active == true, then
1413  // when we reset the node we must store a task to run the node, and spawn it only
1414  // after the reset is complete and is_active() is again true. This is why we don't
1415  // test for is_active() here.
1417  return ( new ( task::allocate_additional_child_of( *(this->my_graph.root_task()) ) )
1419  }
1420 
1422  void spawn_put( ) {
1423  if(internal::is_graph_active(this->my_graph)) {
1424  internal::spawn_in_graph_arena(this->my_graph, *create_put_task());
1425  }
1426  }
1427 
1431  output_type v;
1432  if ( !try_reserve_apply_body(v) )
1433  return NULL;
1434 
1435  task *last_task = my_successors.try_put_task(v);
1436  if ( last_task )
1437  try_consume();
1438  else
1439  try_release();
1440  return last_task;
1441  }
1442 }; // class source_node
1443 #endif // TBB_USE_SOURCE_NODE_AS_ALIAS
1444 
1446 template<typename Input, typename Output = continue_msg, typename Policy = queueing,
1447  typename Allocator=__TBB_DEFAULT_NODE_ALLOCATOR(Input)>
1449  : public graph_node
1450 #if TBB_DEPRECATED_FLOW_NODE_ALLOCATOR
1451  , public internal::function_input< Input, Output, Policy, Allocator >
1452 #else
1453  , public internal::function_input< Input, Output, Policy, cache_aligned_allocator<Input> >
1454 #endif
1455  , public internal::function_output<Output> {
1456 
1457 #if TBB_DEPRECATED_FLOW_NODE_ALLOCATOR
1458  typedef Allocator internals_allocator;
1459 #else
1461 
1464  "Allocator template parameter for flow graph nodes is deprecated and will be removed. "
1465  "Specify TBB_DEPRECATED_FLOW_NODE_ALLOCATOR to temporary enable the deprecated interface."
1466  );
1467 #endif
1468 
1469 public:
1470  typedef Input input_type;
1471  typedef Output output_type;
1477 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
1478  typedef typename input_impl_type::predecessor_list_type predecessor_list_type;
1479  typedef typename fOutput_type::successor_list_type successor_list_type;
1480 #endif
1482 
1484  // input_queue_type is allocated here, but destroyed in the function_input_base.
1485  // TODO: pass the graph_buffer_policy to the function_input_base so it can all
1486  // be done in one place. This would be an interface-breaking change.
1487  template< typename Body >
1490  Body body, __TBB_FLOW_GRAPH_PRIORITY_ARG1( Policy = Policy(), node_priority_t priority = tbb::flow::internal::no_priority ))
1491 #else
1493 #endif
1495  fOutput_type(g) {
1496  tbb::internal::fgt_node_with_body( CODEPTR(), tbb::internal::FLOW_FUNCTION_NODE, &this->my_graph,
1497  static_cast<receiver<input_type> *>(this), static_cast<sender<output_type> *>(this), this->my_body );
1498  }
1499 
1500 #if __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES && __TBB_CPP11_PRESENT
1501  template <typename Body>
1502  function_node( graph& g, size_t concurrency, Body body, node_priority_t priority )
1503  : function_node(g, concurrency, body, Policy(), priority) {}
1504 #endif // __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES && __TBB_CPP11_PRESENT
1505 
1506 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
1507  template <typename Body, typename... Args>
1508  function_node( const node_set<Args...>& nodes, size_t concurrency, Body body,
1511  make_edges_in_order(nodes, *this);
1512  }
1513 
1514 #if __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES
1515  template <typename Body, typename... Args>
1516  function_node( const node_set<Args...>& nodes, size_t concurrency, Body body, node_priority_t priority )
1517  : function_node(nodes, concurrency, body, Policy(), priority) {}
1518 #endif // __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES
1519 #endif // __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
1520 
1523  graph_node(src.my_graph),
1524  input_impl_type(src),
1525  fOutput_type(src.my_graph) {
1526  tbb::internal::fgt_node_with_body( CODEPTR(), tbb::internal::FLOW_FUNCTION_NODE, &this->my_graph,
1527  static_cast<receiver<input_type> *>(this), static_cast<sender<output_type> *>(this), this->my_body );
1528  }
1529 
1530 #if TBB_PREVIEW_FLOW_GRAPH_TRACE
1531  void set_name( const char *name ) __TBB_override {
1533  }
1534 #endif
1535 
1536 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
1537  void extract( ) __TBB_override {
1538  my_predecessors.built_predecessors().receiver_extract(*this);
1539  successors().built_successors().sender_extract(*this);
1540  }
1541 #endif
1542 
1543 protected:
1544  template< typename R, typename B > friend class run_and_put_task;
1545  template<typename X, typename Y> friend class internal::broadcast_cache;
1546  template<typename X, typename Y> friend class internal::round_robin_cache;
1548 
1550 
1553  // TODO: use clear() instead.
1554  if(f & rf_clear_edges) {
1555  successors().clear();
1557  }
1558  __TBB_ASSERT(!(f & rf_clear_edges) || successors().empty(), "function_node successors not empty");
1559  __TBB_ASSERT(this->my_predecessors.empty(), "function_node predecessors not empty");
1560  }
1561 
1562 }; // class function_node
1563 
1565 // Output is a tuple of output types.
1566 template<typename Input, typename Output, typename Policy = queueing,
1567  typename Allocator=__TBB_DEFAULT_NODE_ALLOCATOR(Input)>
1569  public graph_node,
1571  <
1572  Input,
1573  typename internal::wrap_tuple_elements<
1574  tbb::flow::tuple_size<Output>::value, // #elements in tuple
1575  internal::multifunction_output, // wrap this around each element
1576  Output // the tuple providing the types
1577  >::type,
1578  Policy,
1579 #if TBB_DEPRECATED_FLOW_NODE_ALLOCATOR
1580  Allocator
1581 #else
1582  cache_aligned_allocator<Input>
1583 #endif
1584  > {
1585 #if TBB_DEPRECATED_FLOW_NODE_ALLOCATOR
1586  typedef Allocator internals_allocator;
1587 #else
1589 
1592  "Allocator template parameter for flow graph nodes is deprecated and will be removed. "
1593  "Specify TBB_DEPRECATED_FLOW_NODE_ALLOCATOR to temporary enable the deprecated interface."
1594  );
1595 #endif
1596 
1597 protected:
1599 public:
1600  typedef Input input_type;
1606 private:
1608 public:
1609  template<typename Body>
1611  graph &g, size_t concurrency,
1613  Body body, __TBB_FLOW_GRAPH_PRIORITY_ARG1( Policy = Policy(), node_priority_t priority = tbb::flow::internal::no_priority )
1614 #else
1616 #endif
1618  tbb::internal::fgt_multioutput_node_with_body<N>(
1619  CODEPTR(), tbb::internal::FLOW_MULTIFUNCTION_NODE,
1620  &this->my_graph, static_cast<receiver<input_type> *>(this),
1621  this->output_ports(), this->my_body
1622  );
1623  }
1624 
1625 #if __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES && __TBB_CPP11_PRESENT
1626  template <typename Body>
1627  __TBB_NOINLINE_SYM multifunction_node(graph& g, size_t concurrency, Body body, node_priority_t priority)
1628  : multifunction_node(g, concurrency, body, Policy(), priority) {}
1629 #endif // TBB_PREVIEW_FLOW_GRAPH_PRIORITIES && __TBB_CPP11_PRESENT
1630 
1631 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
1632  template <typename Body, typename... Args>
1633  __TBB_NOINLINE_SYM multifunction_node(const node_set<Args...>& nodes, size_t concurrency, Body body,
1636  make_edges_in_order(nodes, *this);
1637  }
1638 
1639 #if __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES
1640  template <typename Body, typename... Args>
1641  __TBB_NOINLINE_SYM multifunction_node(const node_set<Args...>& nodes, size_t concurrency, Body body, node_priority_t priority)
1642  : multifunction_node(nodes, concurrency, body, Policy(), priority) {}
1643 #endif // __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES
1644 #endif // __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
1645 
1647  graph_node(other.my_graph), input_impl_type(other) {
1648  tbb::internal::fgt_multioutput_node_with_body<N>( CODEPTR(), tbb::internal::FLOW_MULTIFUNCTION_NODE,
1649  &this->my_graph, static_cast<receiver<input_type> *>(this),
1650  this->output_ports(), this->my_body );
1651  }
1652 
1653 #if TBB_PREVIEW_FLOW_GRAPH_TRACE
1654  void set_name( const char *name ) __TBB_override {
1656  }
1657 #endif
1658 
1659 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
1660  void extract( ) __TBB_override {
1661  my_predecessors.built_predecessors().receiver_extract(*this);
1662  input_impl_type::extract();
1663  }
1664 #endif
1665  // all the guts are in multifunction_input...
1666 protected:
1668 }; // multifunction_node
1669 
1671 // successors. The node has unlimited concurrency, so it does not reject inputs.
1672 template<typename TupleType, typename Allocator=__TBB_DEFAULT_NODE_ALLOCATOR(TupleType)>
1673 class split_node : public graph_node, public receiver<TupleType> {
1676 public:
1677  typedef TupleType input_type;
1678 #if TBB_DEPRECATED_FLOW_NODE_ALLOCATOR
1679  typedef Allocator allocator_type;
1680 #else
1683  "Allocator template parameter for flow graph nodes is deprecated and will be removed. "
1684  "Specify TBB_DEPRECATED_FLOW_NODE_ALLOCATOR to temporary enable the deprecated interface."
1685  );
1686 #endif
1687 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
1689  typedef typename base_type::predecessor_list_type predecessor_list_type;
1690  typedef internal::predecessor_cache<input_type, null_mutex > predecessor_cache_type;
1691  typedef typename predecessor_cache_type::built_predecessors_type built_predecessors_type;
1692 #endif
1693 
1694  typedef typename internal::wrap_tuple_elements<
1695  N, // #elements in tuple
1696  internal::multifunction_output, // wrap this around each element
1697  TupleType // the tuple providing the types
1699 
1701  : graph_node(g),
1702  my_output_ports(internal::init_output_ports<output_ports_type>::call(g, my_output_ports))
1703  {
1704  tbb::internal::fgt_multioutput_node<N>(CODEPTR(), tbb::internal::FLOW_SPLIT_NODE, &this->my_graph,
1705  static_cast<receiver<input_type> *>(this), this->output_ports());
1706  }
1707 
1708 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
1709  template <typename... Args>
1710  __TBB_NOINLINE_SYM split_node(const node_set<Args...>& nodes) : split_node(nodes.graph_reference()) {
1711  make_edges_in_order(nodes, *this);
1712  }
1713 #endif
1714 
1716  : graph_node(other.my_graph), base_type(other),
1717  my_output_ports(internal::init_output_ports<output_ports_type>::call(other.my_graph, my_output_ports))
1718  {
1719  tbb::internal::fgt_multioutput_node<N>(CODEPTR(), tbb::internal::FLOW_SPLIT_NODE, &this->my_graph,
1720  static_cast<receiver<input_type> *>(this), this->output_ports());
1721  }
1722 
1723 #if TBB_PREVIEW_FLOW_GRAPH_TRACE
1724  void set_name( const char *name ) __TBB_override {
1726  }
1727 #endif
1728 
1730 
1731 protected:
1732  task *try_put_task(const TupleType& t) __TBB_override {
1733  // Sending split messages in parallel is not justified, as overheads would prevail.
1734  // Also, we do not have successors here. So we just tell the task returned here is successful.
1736  }
1738  if (f & rf_clear_edges)
1740 
1742  }
1745  return my_graph;
1746  }
1747 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
1748 private:
1749  void extract() __TBB_override {}
1750 
1752  void internal_add_built_predecessor(predecessor_type&) __TBB_override {}
1753 
1755  void internal_delete_built_predecessor(predecessor_type&) __TBB_override {}
1756 
1757  size_t predecessor_count() __TBB_override { return 0; }
1758 
1759  void copy_predecessors(predecessor_list_type&) __TBB_override {}
1760 
1761  built_predecessors_type &built_predecessors() __TBB_override { return my_predessors; }
1762 
1764  built_predecessors_type my_predessors;
1765 #endif /* TBB_DEPRECATED_FLOW_NODE_EXTRACTION */
1766 
1767 private:
1769 };
1770 
1772 template <typename Output, typename Policy = internal::Policy<void> >
1773 class continue_node : public graph_node, public internal::continue_input<Output, Policy>,
1774  public internal::function_output<Output> {
1775 public:
1777  typedef Output output_type;
1780  typedef typename input_impl_type::predecessor_type predecessor_type;
1782 
1784  template <typename Body >
1786  graph &g,
1788  Body body, __TBB_FLOW_GRAPH_PRIORITY_ARG1( Policy = Policy(), node_priority_t priority = tbb::flow::internal::no_priority )
1789 #else
1791 #endif
1792  ) : graph_node(g), input_impl_type( g, __TBB_FLOW_GRAPH_PRIORITY_ARG1(body, priority) ),
1793  fOutput_type(g) {
1794  tbb::internal::fgt_node_with_body( CODEPTR(), tbb::internal::FLOW_CONTINUE_NODE, &this->my_graph,
1795 
1796  static_cast<receiver<input_type> *>(this),
1797  static_cast<sender<output_type> *>(this), this->my_body );
1798  }
1799 
1800 #if __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES && __TBB_CPP11_PRESENT
1801  template <typename Body>
1802  continue_node( graph& g, Body body, node_priority_t priority )
1803  : continue_node(g, body, Policy(), priority) {}
1804 #endif
1805 
1806 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
1807  template <typename Body, typename... Args>
1808  continue_node( const node_set<Args...>& nodes, Body body,
1810  : continue_node(nodes.graph_reference(), body, __TBB_FLOW_GRAPH_PRIORITY_ARG1(p, priority) ) {
1811  make_edges_in_order(nodes, *this);
1812  }
1813 #if __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES
1814  template <typename Body, typename... Args>
1815  continue_node( const node_set<Args...>& nodes, Body body, node_priority_t priority)
1816  : continue_node(nodes, body, Policy(), priority) {}
1817 #endif // __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES
1818 #endif // __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
1819 
1821  template <typename Body >
1823  graph &g, int number_of_predecessors,
1825  Body body, __TBB_FLOW_GRAPH_PRIORITY_ARG1( Policy = Policy(), node_priority_t priority = tbb::flow::internal::no_priority )
1826 #else
1828 #endif
1829  ) : graph_node(g)
1830  , input_impl_type(g, number_of_predecessors, __TBB_FLOW_GRAPH_PRIORITY_ARG1(body, priority)),
1831  fOutput_type(g) {
1832  tbb::internal::fgt_node_with_body( CODEPTR(), tbb::internal::FLOW_CONTINUE_NODE, &this->my_graph,
1833  static_cast<receiver<input_type> *>(this),
1834  static_cast<sender<output_type> *>(this), this->my_body );
1835  }
1836 
1837 #if __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES && __TBB_CPP11_PRESENT
1838  template <typename Body>
1839  continue_node( graph& g, int number_of_predecessors, Body body, node_priority_t priority)
1840  : continue_node(g, number_of_predecessors, body, Policy(), priority) {}
1841 #endif
1842 
1843 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
1844  template <typename Body, typename... Args>
1845  continue_node( const node_set<Args...>& nodes, int number_of_predecessors,
1846  Body body, __TBB_FLOW_GRAPH_PRIORITY_ARG1( Policy p = Policy(), node_priority_t priority = tbb::flow::internal::no_priority ))
1847  : continue_node(nodes.graph_reference(), number_of_predecessors, body, __TBB_FLOW_GRAPH_PRIORITY_ARG1(p, priority)) {
1848  make_edges_in_order(nodes, *this);
1849  }
1850 
1851 #if __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES
1852  template <typename Body, typename... Args>
1853  continue_node( const node_set<Args...>& nodes, int number_of_predecessors,
1854  Body body, node_priority_t priority )
1855  : continue_node(nodes, number_of_predecessors, body, Policy(), priority) {}
1856 #endif
1857 #endif
1858 
1861  graph_node(src.my_graph), input_impl_type(src),
1862  internal::function_output<Output>(src.my_graph) {
1863  tbb::internal::fgt_node_with_body( CODEPTR(), tbb::internal::FLOW_CONTINUE_NODE, &this->my_graph,
1864  static_cast<receiver<input_type> *>(this),
1865  static_cast<sender<output_type> *>(this), this->my_body );
1866  }
1867 
1868 #if TBB_PREVIEW_FLOW_GRAPH_TRACE
1869  void set_name( const char *name ) __TBB_override {
1871  }
1872 #endif
1873 
1874 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
1875  void extract() __TBB_override {
1876  input_impl_type::my_built_predecessors.receiver_extract(*this);
1877  successors().built_successors().sender_extract(*this);
1878  }
1879 #endif
1880 
1881 protected:
1882  template< typename R, typename B > friend class run_and_put_task;
1883  template<typename X, typename Y> friend class internal::broadcast_cache;
1884  template<typename X, typename Y> friend class internal::round_robin_cache;
1885  using input_impl_type::try_put_task;
1887 
1890  if(f & rf_clear_edges)successors().clear();
1891  __TBB_ASSERT(!(f & rf_clear_edges) || successors().empty(), "continue_node not reset");
1892  }
1893 }; // continue_node
1894 
1896 template <typename T>
1897 class broadcast_node : public graph_node, public receiver<T>, public sender<T> {
1898 public:
1899  typedef T input_type;
1900  typedef T output_type;
1903 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
1904  typedef typename receiver<input_type>::predecessor_list_type predecessor_list_type;
1905  typedef typename sender<output_type>::successor_list_type successor_list_type;
1906 #endif
1907 private:
1909 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
1910  internal::edge_container<predecessor_type> my_built_predecessors;
1911  spin_mutex pred_mutex; // serialize accesses on edge_container
1912 #endif
1913 public:
1914 
1916  my_successors.set_owner( this );
1917  tbb::internal::fgt_node( CODEPTR(), tbb::internal::FLOW_BROADCAST_NODE, &this->my_graph,
1918  static_cast<receiver<input_type> *>(this), static_cast<sender<output_type> *>(this) );
1919  }
1920 
1921 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
1922  template <typename... Args>
1923  broadcast_node(const node_set<Args...>& nodes) : broadcast_node(nodes.graph_reference()) {
1924  make_edges_in_order(nodes, *this);
1925  }
1926 #endif
1927 
1928  // Copy constructor
1930  graph_node(src.my_graph), receiver<T>(), sender<T>()
1931  {
1932  my_successors.set_owner( this );
1933  tbb::internal::fgt_node( CODEPTR(), tbb::internal::FLOW_BROADCAST_NODE, &this->my_graph,
1934  static_cast<receiver<input_type> *>(this), static_cast<sender<output_type> *>(this) );
1935  }
1936 
1937 #if TBB_PREVIEW_FLOW_GRAPH_TRACE
1938  void set_name( const char *name ) __TBB_override {
1940  }
1941 #endif
1942 
1945  my_successors.register_successor( r );
1946  return true;
1947  }
1948 
1951  my_successors.remove_successor( r );
1952  return true;
1953  }
1954 
1955 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
1956  typedef typename sender<T>::built_successors_type built_successors_type;
1957 
1958  built_successors_type &built_successors() __TBB_override { return my_successors.built_successors(); }
1959 
1960  void internal_add_built_successor(successor_type &r) __TBB_override {
1961  my_successors.internal_add_built_successor(r);
1962  }
1963 
1964  void internal_delete_built_successor(successor_type &r) __TBB_override {
1965  my_successors.internal_delete_built_successor(r);
1966  }
1967 
1968  size_t successor_count() __TBB_override {
1969  return my_successors.successor_count();
1970  }
1971 
1972  void copy_successors(successor_list_type &v) __TBB_override {
1973  my_successors.copy_successors(v);
1974  }
1975 
1976  typedef typename receiver<T>::built_predecessors_type built_predecessors_type;
1977 
1978  built_predecessors_type &built_predecessors() __TBB_override { return my_built_predecessors; }
1979 
1980  void internal_add_built_predecessor( predecessor_type &p) __TBB_override {
1981  spin_mutex::scoped_lock l(pred_mutex);
1982  my_built_predecessors.add_edge(p);
1983  }
1984 
1985  void internal_delete_built_predecessor( predecessor_type &p) __TBB_override {
1986  spin_mutex::scoped_lock l(pred_mutex);
1987  my_built_predecessors.delete_edge(p);
1988  }
1989 
1990  size_t predecessor_count() __TBB_override {
1991  spin_mutex::scoped_lock l(pred_mutex);
1992  return my_built_predecessors.edge_count();
1993  }
1994 
1995  void copy_predecessors(predecessor_list_type &v) __TBB_override {
1996  spin_mutex::scoped_lock l(pred_mutex);
1997  my_built_predecessors.copy_edges(v);
1998  }
1999 
2000  void extract() __TBB_override {
2001  my_built_predecessors.receiver_extract(*this);
2002  my_successors.built_successors().sender_extract(*this);
2003  }
2004 #endif /* TBB_DEPRECATED_FLOW_NODE_EXTRACTION */
2005 
2006 protected:
2007  template< typename R, typename B > friend class run_and_put_task;
2008  template<typename X, typename Y> friend class internal::broadcast_cache;
2009  template<typename X, typename Y> friend class internal::round_robin_cache;
2012  task *new_task = my_successors.try_put_task(t);
2013  if (!new_task) new_task = SUCCESSFULLY_ENQUEUED;
2014  return new_task;
2015  }
2016 
2018  return my_graph;
2019  }
2020 
2022 
2024  if (f&rf_clear_edges) {
2025  my_successors.clear();
2026 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
2027  my_built_predecessors.clear();
2028 #endif
2029  }
2030  __TBB_ASSERT(!(f & rf_clear_edges) || my_successors.empty(), "Error resetting broadcast_node");
2031  }
2032 }; // broadcast_node
2033 
2035 template <typename T, typename Allocator=__TBB_DEFAULT_NODE_ALLOCATOR(T) >
2037  : public graph_node
2038 #if TBB_DEPRECATED_FLOW_NODE_ALLOCATOR
2039  , public internal::reservable_item_buffer< T, Allocator >
2040 #else
2041  , public internal::reservable_item_buffer< T, cache_aligned_allocator<T> >
2042 #endif
2043  , public receiver<T>, public sender<T> {
2044 #if TBB_DEPRECATED_FLOW_NODE_ALLOCATOR
2045  typedef Allocator internals_allocator;
2046 #else
2048 #endif
2049 public:
2050  typedef T input_type;
2051  typedef T output_type;
2055 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
2056  typedef typename receiver<input_type>::predecessor_list_type predecessor_list_type;
2057  typedef typename sender<output_type>::successor_list_type successor_list_type;
2058 #endif
2059 #if !TBB_DEPRECATED_FLOW_NODE_ALLOCATOR
2062  "Allocator template parameter for flow graph nodes is deprecated and will be removed. "
2063  "Specify TBB_DEPRECATED_FLOW_NODE_ALLOCATOR to temporary enable the deprecated interface."
2064  );
2065 #endif
2066 
2067 protected:
2068  typedef size_t size_type;
2070 
2071 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
2072  internal::edge_container<predecessor_type> my_built_predecessors;
2073 #endif
2074 
2076 
2078 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
2079  , add_blt_succ, del_blt_succ,
2080  add_blt_pred, del_blt_pred,
2081  blt_succ_cnt, blt_pred_cnt,
2082  blt_succ_cpy, blt_pred_cpy // create vector copies of preds and succs
2083 #endif
2084  };
2085 
2086  // implements the aggregator_operation concept
2087  class buffer_operation : public internal::aggregated_operation< buffer_operation > {
2088  public:
2089  char type;
2090 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
2091  task * ltask;
2092  union {
2093  input_type *elem;
2094  successor_type *r;
2096  size_t cnt_val;
2097  successor_list_type *svec;
2098  predecessor_list_type *pvec;
2099  };
2100 #else
2101  T *elem;
2104 #endif
2105  buffer_operation(const T& e, op_type t) : type(char(t))
2106 
2107 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
2108  , ltask(NULL), elem(const_cast<T*>(&e))
2109 #else
2110  , elem(const_cast<T*>(&e)) , ltask(NULL)
2111 #endif
2112  {}
2113  buffer_operation(op_type t) : type(char(t)), ltask(NULL) {}
2114  };
2115 
2118  friend class internal::aggregating_functor<class_type, buffer_operation>;
2120 
2121  virtual void handle_operations(buffer_operation *op_list) {
2122  handle_operations_impl(op_list, this);
2123  }
2124 
2125  template<typename derived_type>
2126  void handle_operations_impl(buffer_operation *op_list, derived_type* derived) {
2127  __TBB_ASSERT(static_cast<class_type*>(derived) == this, "'this' is not a base class for derived");
2128 
2129  buffer_operation *tmp = NULL;
2130  bool try_forwarding = false;
2131  while (op_list) {
2132  tmp = op_list;
2133  op_list = op_list->next;
2134  switch (tmp->type) {
2135  case reg_succ: internal_reg_succ(tmp); try_forwarding = true; break;
2136  case rem_succ: internal_rem_succ(tmp); break;
2137  case req_item: internal_pop(tmp); break;
2138  case res_item: internal_reserve(tmp); break;
2139  case rel_res: internal_release(tmp); try_forwarding = true; break;
2140  case con_res: internal_consume(tmp); try_forwarding = true; break;
2141  case put_item: try_forwarding = internal_push(tmp); break;
2142  case try_fwd_task: internal_forward_task(tmp); break;
2143 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
2144  // edge recording
2145  case add_blt_succ: internal_add_built_succ(tmp); break;
2146  case del_blt_succ: internal_del_built_succ(tmp); break;
2147  case add_blt_pred: internal_add_built_pred(tmp); break;
2148  case del_blt_pred: internal_del_built_pred(tmp); break;
2149  case blt_succ_cnt: internal_succ_cnt(tmp); break;
2150  case blt_pred_cnt: internal_pred_cnt(tmp); break;
2151  case blt_succ_cpy: internal_copy_succs(tmp); break;
2152  case blt_pred_cpy: internal_copy_preds(tmp); break;
2153 #endif
2154  }
2155  }
2156 
2157  derived->order();
2158 
2159  if (try_forwarding && !forwarder_busy) {
2160  if(internal::is_graph_active(this->my_graph)) {
2161  forwarder_busy = true;
2162  task *new_task = new(task::allocate_additional_child_of(*(this->my_graph.root_task()))) internal::
2163  forward_task_bypass<class_type>(*this);
2164  // tmp should point to the last item handled by the aggregator. This is the operation
2165  // the handling thread enqueued. So modifying that record will be okay.
2166  // workaround for icc bug
2167  tbb::task *z = tmp->ltask;
2168  graph &g = this->my_graph;
2169  tmp->ltask = combine_tasks(g, z, new_task); // in case the op generated a task
2170  }
2171  }
2172  } // handle_operations
2173 
2174  inline task *grab_forwarding_task( buffer_operation &op_data) {
2175  return op_data.ltask;
2176  }
2177 
2178  inline bool enqueue_forwarding_task(buffer_operation &op_data) {
2179  task *ft = grab_forwarding_task(op_data);
2180  if(ft) {
2182  return true;
2183  }
2184  return false;
2185  }
2186 
2188  virtual task *forward_task() {
2189  buffer_operation op_data(try_fwd_task);
2190  task *last_task = NULL;
2191  do {
2192  op_data.status = internal::WAIT;
2193  op_data.ltask = NULL;
2194  my_aggregator.execute(&op_data);
2195 
2196  // workaround for icc bug
2197  tbb::task *xtask = op_data.ltask;
2198  graph& g = this->my_graph;
2199  last_task = combine_tasks(g, last_task, xtask);
2200  } while (op_data.status ==internal::SUCCEEDED);
2201  return last_task;
2202  }
2203 
2205  virtual void internal_reg_succ(buffer_operation *op) {
2206  my_successors.register_successor(*(op->r));
2208  }
2209 
2211  virtual void internal_rem_succ(buffer_operation *op) {
2212  my_successors.remove_successor(*(op->r));
2214  }
2215 
2216 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
2217  typedef typename sender<T>::built_successors_type built_successors_type;
2218 
2219  built_successors_type &built_successors() __TBB_override { return my_successors.built_successors(); }
2220 
2221  virtual void internal_add_built_succ(buffer_operation *op) {
2222  my_successors.internal_add_built_successor(*(op->r));
2224  }
2225 
2226  virtual void internal_del_built_succ(buffer_operation *op) {
2227  my_successors.internal_delete_built_successor(*(op->r));
2229  }
2230 
2231  typedef typename receiver<T>::built_predecessors_type built_predecessors_type;
2232 
2233  built_predecessors_type &built_predecessors() __TBB_override { return my_built_predecessors; }
2234 
2235  virtual void internal_add_built_pred(buffer_operation *op) {
2236  my_built_predecessors.add_edge(*(op->p));
2238  }
2239 
2240  virtual void internal_del_built_pred(buffer_operation *op) {
2241  my_built_predecessors.delete_edge(*(op->p));
2243  }
2244 
2245  virtual void internal_succ_cnt(buffer_operation *op) {
2246  op->cnt_val = my_successors.successor_count();
2248  }
2249 
2250  virtual void internal_pred_cnt(buffer_operation *op) {
2251  op->cnt_val = my_built_predecessors.edge_count();
2253  }
2254 
2255  virtual void internal_copy_succs(buffer_operation *op) {
2256  my_successors.copy_successors(*(op->svec));
2258  }
2259 
2260  virtual void internal_copy_preds(buffer_operation *op) {
2261  my_built_predecessors.copy_edges(*(op->pvec));
2263  }
2264 
2265 #endif /* TBB_DEPRECATED_FLOW_NODE_EXTRACTION */
2266 
2267 private:
2268  void order() {}
2269 
2270  bool is_item_valid() {
2271  return this->my_item_valid(this->my_tail - 1);
2272  }
2273 
2274  void try_put_and_add_task(task*& last_task) {
2275  task *new_task = my_successors.try_put_task(this->back());
2276  if (new_task) {
2277  // workaround for icc bug
2278  graph& g = this->my_graph;
2279  last_task = combine_tasks(g, last_task, new_task);
2280  this->destroy_back();
2281  }
2282  }
2283 
2284 protected:
2286  virtual void internal_forward_task(buffer_operation *op) {
2287  internal_forward_task_impl(op, this);
2288  }
2289 
2290  template<typename derived_type>
2291  void internal_forward_task_impl(buffer_operation *op, derived_type* derived) {
2292  __TBB_ASSERT(static_cast<class_type*>(derived) == this, "'this' is not a base class for derived");
2293 
2294  if (this->my_reserved || !derived->is_item_valid()) {
2296  this->forwarder_busy = false;
2297  return;
2298  }
2299  // Try forwarding, giving each successor a chance
2300  task * last_task = NULL;
2301  size_type counter = my_successors.size();
2302  for (; counter > 0 && derived->is_item_valid(); --counter)
2303  derived->try_put_and_add_task(last_task);
2304 
2305  op->ltask = last_task; // return task
2306  if (last_task && !counter) {
2308  }
2309  else {
2311  forwarder_busy = false;
2312  }
2313  }
2314 
2315  virtual bool internal_push(buffer_operation *op) {
2316  this->push_back(*(op->elem));
2318  return true;
2319  }
2320 
2321  virtual void internal_pop(buffer_operation *op) {
2322  if(this->pop_back(*(op->elem))) {
2324  }
2325  else {
2327  }
2328  }
2329 
2330  virtual void internal_reserve(buffer_operation *op) {
2331  if(this->reserve_front(*(op->elem))) {
2333  }
2334  else {
2336  }
2337  }
2338 
2339  virtual void internal_consume(buffer_operation *op) {
2340  this->consume_front();
2342  }
2343 
2344  virtual void internal_release(buffer_operation *op) {
2345  this->release_front();
2347  }
2348 
2349 public:
2353  sender<T>(), forwarder_busy(false)
2354  {
2355  my_successors.set_owner(this);
2356  my_aggregator.initialize_handler(handler_type(this));
2357  tbb::internal::fgt_node( CODEPTR(), tbb::internal::FLOW_BUFFER_NODE, &this->my_graph,
2358  static_cast<receiver<input_type> *>(this), static_cast<sender<output_type> *>(this) );
2359  }
2360 
2361 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
2362  template <typename... Args>
2363  buffer_node(const node_set<Args...>& nodes) : buffer_node(nodes.graph_reference()) {
2364  make_edges_in_order(nodes, *this);
2365  }
2366 #endif
2367 
2371  receiver<T>(), sender<T>(), forwarder_busy(false)
2372  {
2373  my_successors.set_owner(this);
2374  my_aggregator.initialize_handler(handler_type(this));
2375  tbb::internal::fgt_node( CODEPTR(), tbb::internal::FLOW_BUFFER_NODE, &this->my_graph,
2376  static_cast<receiver<input_type> *>(this), static_cast<sender<output_type> *>(this) );
2377  }
2378 
2379 #if TBB_PREVIEW_FLOW_GRAPH_TRACE
2380  void set_name( const char *name ) __TBB_override {
2382  }
2383 #endif
2384 
2385  //
2386  // message sender implementation
2387  //
2388 
2390 
2392  buffer_operation op_data(reg_succ);
2393  op_data.r = &r;
2394  my_aggregator.execute(&op_data);
2395  (void)enqueue_forwarding_task(op_data);
2396  return true;
2397  }
2398 
2399 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
2400  void internal_add_built_successor( successor_type &r) __TBB_override {
2401  buffer_operation op_data(add_blt_succ);
2402  op_data.r = &r;
2403  my_aggregator.execute(&op_data);
2404  }
2405 
2406  void internal_delete_built_successor( successor_type &r) __TBB_override {
2407  buffer_operation op_data(del_blt_succ);
2408  op_data.r = &r;
2409  my_aggregator.execute(&op_data);
2410  }
2411 
2412  void internal_add_built_predecessor( predecessor_type &p) __TBB_override {
2413  buffer_operation op_data(add_blt_pred);
2414  op_data.p = &p;
2415  my_aggregator.execute(&op_data);
2416  }
2417 
2418  void internal_delete_built_predecessor( predecessor_type &p) __TBB_override {
2419  buffer_operation op_data(del_blt_pred);
2420  op_data.p = &p;
2421  my_aggregator.execute(&op_data);
2422  }
2423 
2424  size_t predecessor_count() __TBB_override {
2425  buffer_operation op_data(blt_pred_cnt);
2426  my_aggregator.execute(&op_data);
2427  return op_data.cnt_val;
2428  }
2429 
2430  size_t successor_count() __TBB_override {
2431  buffer_operation op_data(blt_succ_cnt);
2432  my_aggregator.execute(&op_data);
2433  return op_data.cnt_val;
2434  }
2435 
2436  void copy_predecessors( predecessor_list_type &v ) __TBB_override {
2437  buffer_operation op_data(blt_pred_cpy);
2438  op_data.pvec = &v;
2439  my_aggregator.execute(&op_data);
2440  }
2441 
2442  void copy_successors( successor_list_type &v ) __TBB_override {
2443  buffer_operation op_data(blt_succ_cpy);
2444  op_data.svec = &v;
2445  my_aggregator.execute(&op_data);
2446  }
2447 
2448 #endif /* TBB_DEPRECATED_FLOW_NODE_EXTRACTION */
2449 
2451 
2454  r.remove_predecessor(*this);
2455  buffer_operation op_data(rem_succ);
2456  op_data.r = &r;
2457  my_aggregator.execute(&op_data);
2458  // even though this operation does not cause a forward, if we are the handler, and
2459  // a forward is scheduled, we may be the first to reach this point after the aggregator,
2460  // and so should check for the task.
2461  (void)enqueue_forwarding_task(op_data);
2462  return true;
2463  }
2464 
2466 
2468  bool try_get( T &v ) __TBB_override {
2469  buffer_operation op_data(req_item);
2470  op_data.elem = &v;
2471  my_aggregator.execute(&op_data);
2472  (void)enqueue_forwarding_task(op_data);
2473  return (op_data.status==internal::SUCCEEDED);
2474  }
2475 
2477 
2480  buffer_operation op_data(res_item);
2481  op_data.elem = &v;
2482  my_aggregator.execute(&op_data);
2483  (void)enqueue_forwarding_task(op_data);
2484  return (op_data.status==internal::SUCCEEDED);
2485  }
2486 
2488 
2490  buffer_operation op_data(rel_res);
2491  my_aggregator.execute(&op_data);
2492  (void)enqueue_forwarding_task(op_data);
2493  return true;
2494  }
2495 
2497 
2499  buffer_operation op_data(con_res);
2500  my_aggregator.execute(&op_data);
2501  (void)enqueue_forwarding_task(op_data);
2502  return true;
2503  }
2504 
2505 protected:
2506 
2507  template< typename R, typename B > friend class run_and_put_task;
2508  template<typename X, typename Y> friend class internal::broadcast_cache;
2509  template<typename X, typename Y> friend class internal::round_robin_cache;
2512  buffer_operation op_data(t, put_item);
2513  my_aggregator.execute(&op_data);
2514  task *ft = grab_forwarding_task(op_data);
2515  // sequencer_nodes can return failure (if an item has been previously inserted)
2516  // We have to spawn the returned task if our own operation fails.
2517 
2518  if(ft && op_data.status ==internal::FAILED) {
2519  // we haven't succeeded queueing the item, but for some reason the
2520  // call returned a task (if another request resulted in a successful
2521  // forward this could happen.) Queue the task and reset the pointer.
2523  }
2524  else if(!ft && op_data.status ==internal::SUCCEEDED) {
2525  ft = SUCCESSFULLY_ENQUEUED;
2526  }
2527  return ft;
2528  }
2529 
2531  return my_graph;
2532  }
2533 
2535 
2536 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
2537 public:
2538  void extract() __TBB_override {
2539  my_built_predecessors.receiver_extract(*this);
2540  my_successors.built_successors().sender_extract(*this);
2541  }
2542 #endif
2543 
2544 protected:
2547  // TODO: just clear structures
2548  if (f&rf_clear_edges) {
2549  my_successors.clear();
2550 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
2551  my_built_predecessors.clear();
2552 #endif
2553  }
2554  forwarder_busy = false;
2555  }
2556 }; // buffer_node
2557 
2559 template <typename T, typename Allocator=__TBB_DEFAULT_NODE_ALLOCATOR(T) >
2560 class queue_node : public buffer_node<T, Allocator> {
2561 #if !TBB_DEPRECATED_FLOW_NODE_ALLOCATOR
2564  "Allocator template parameter for flow graph nodes is deprecated and will be removed. "
2565  "Specify TBB_DEPRECATED_FLOW_NODE_ALLOCATOR to temporary enable the deprecated interface."
2566  );
2567 #endif
2568 protected:
2571  typedef typename base_type::buffer_operation queue_operation;
2573 
2574 private:
2575  template<typename, typename> friend class buffer_node;
2576 
2577  bool is_item_valid() {
2578  return this->my_item_valid(this->my_head);
2579  }
2580 
2581  void try_put_and_add_task(task*& last_task) {
2582  task *new_task = this->my_successors.try_put_task(this->front());
2583  if (new_task) {
2584  // workaround for icc bug
2585  graph& graph_ref = this->graph_reference();
2586  last_task = combine_tasks(graph_ref, last_task, new_task);
2587  this->destroy_front();
2588  }
2589  }
2590 
2591 protected:
2592  void internal_forward_task(queue_operation *op) __TBB_override {
2593  this->internal_forward_task_impl(op, this);
2594  }
2595 
2597  if ( this->my_reserved || !this->my_item_valid(this->my_head)){
2599  }
2600  else {
2601  this->pop_front(*(op->elem));
2603  }
2604  }
2606  if (this->my_reserved || !this->my_item_valid(this->my_head)) {
2608  }
2609  else {
2610  this->reserve_front(*(op->elem));
2612  }
2613  }
2615  this->consume_front();
2617  }
2618 
2619 public:
2620  typedef T input_type;
2621  typedef T output_type;
2624 
2627  tbb::internal::fgt_node( CODEPTR(), tbb::internal::FLOW_QUEUE_NODE, &(this->my_graph),
2628  static_cast<receiver<input_type> *>(this),
2629  static_cast<sender<output_type> *>(this) );
2630  }
2631 
2632 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
2633  template <typename... Args>
2634  queue_node( const node_set<Args...>& nodes) : queue_node(nodes.graph_reference()) {
2635  make_edges_in_order(nodes, *this);
2636  }
2637 #endif
2638 
2641  tbb::internal::fgt_node( CODEPTR(), tbb::internal::FLOW_QUEUE_NODE, &(this->my_graph),
2642  static_cast<receiver<input_type> *>(this),
2643  static_cast<sender<output_type> *>(this) );
2644  }
2645 
2646 #if TBB_PREVIEW_FLOW_GRAPH_TRACE
2647  void set_name( const char *name ) __TBB_override {
2649  }
2650 #endif
2651 
2652 protected:
2655  }
2656 }; // queue_node
2657 
2659 template< typename T, typename Allocator=__TBB_DEFAULT_NODE_ALLOCATOR(T) >
2660 class sequencer_node : public queue_node<T, Allocator> {
2662  // my_sequencer should be a benign function and must be callable
2663  // from a parallel context. Does this mean it needn't be reset?
2664 public:
2665 #if !TBB_DEPRECATED_FLOW_NODE_ALLOCATOR
2668  "Allocator template parameter for flow graph nodes is deprecated and will be removed. "
2669  "Specify TBB_DEPRECATED_FLOW_NODE_ALLOCATOR to temporary enable the deprecated interface."
2670  );
2671 #endif
2672  typedef T input_type;
2673  typedef T output_type;
2676 
2678  template< typename Sequencer >
2679  __TBB_NOINLINE_SYM sequencer_node( graph &g, const Sequencer& s ) : queue_node<T, Allocator>(g),
2680  my_sequencer(new internal::function_body_leaf< T, size_t, Sequencer>(s) ) {
2681  tbb::internal::fgt_node( CODEPTR(), tbb::internal::FLOW_SEQUENCER_NODE, &(this->my_graph),
2682  static_cast<receiver<input_type> *>(this),
2683  static_cast<sender<output_type> *>(this) );
2684  }
2685 
2686 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
2687  template <typename Sequencer, typename... Args>
2688  sequencer_node( const node_set<Args...>& nodes, const Sequencer& s)
2689  : sequencer_node(nodes.graph_reference(), s) {
2690  make_edges_in_order(nodes, *this);
2691  }
2692 #endif
2693 
2695  __TBB_NOINLINE_SYM sequencer_node( const sequencer_node& src ) : queue_node<T, Allocator>(src),
2696  my_sequencer( src.my_sequencer->clone() ) {
2697  tbb::internal::fgt_node( CODEPTR(), tbb::internal::FLOW_SEQUENCER_NODE, &(this->my_graph),
2698  static_cast<receiver<input_type> *>(this),
2699  static_cast<sender<output_type> *>(this) );
2700  }
2701 
2704 
2705 #if TBB_PREVIEW_FLOW_GRAPH_TRACE
2706  void set_name( const char *name ) __TBB_override {
2708  }
2709 #endif
2710 
2711 protected:
2714 
2715 private:
2717  size_type tag = (*my_sequencer)(*(op->elem));
2718 #if !TBB_DEPRECATED_SEQUENCER_DUPLICATES
2719  if (tag < this->my_head) {
2720  // have already emitted a message with this tag
2722  return false;
2723  }
2724 #endif
2725  // cannot modify this->my_tail now; the buffer would be inconsistent.
2726  size_t new_tail = (tag+1 > this->my_tail) ? tag+1 : this->my_tail;
2727 
2728  if (this->size(new_tail) > this->capacity()) {
2729  this->grow_my_array(this->size(new_tail));
2730  }
2731  this->my_tail = new_tail;
2732 
2733  const internal::op_stat res = this->place_item(tag, *(op->elem)) ? internal::SUCCEEDED : internal::FAILED;
2734  __TBB_store_with_release(op->status, res);
2735  return res ==internal::SUCCEEDED;
2736  }
2737 }; // sequencer_node
2738 
2740 template<typename T, typename Compare = std::less<T>, typename Allocator=__TBB_DEFAULT_NODE_ALLOCATOR(T)>
2741 class priority_queue_node : public buffer_node<T, Allocator> {
2742 public:
2743 #if !TBB_DEPRECATED_FLOW_NODE_ALLOCATOR
2746  "Allocator template parameter for flow graph nodes is deprecated and will removed in the future. "
2747  "To temporary enable the deprecated interface specify TBB_ENABLE_DEPRECATED_NODE_ALLOCATOR."
2748  );
2749 #endif
2750  typedef T input_type;
2751  typedef T output_type;
2756 
2758  __TBB_NOINLINE_SYM explicit priority_queue_node( graph &g, const Compare& comp = Compare() )
2759  : buffer_node<T, Allocator>(g), compare(comp), mark(0) {
2760  tbb::internal::fgt_node( CODEPTR(), tbb::internal::FLOW_PRIORITY_QUEUE_NODE, &(this->my_graph),
2761  static_cast<receiver<input_type> *>(this),
2762  static_cast<sender<output_type> *>(this) );
2763  }
2764 
2765 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
2766  template <typename... Args>
2767  priority_queue_node(const node_set<Args...>& nodes, const Compare& comp = Compare())
2768  : priority_queue_node(nodes.graph_reference(), comp) {
2769  make_edges_in_order(nodes, *this);
2770  }
2771 #endif
2772 
2775  : buffer_node<T, Allocator>(src), mark(0)
2776  {
2777  tbb::internal::fgt_node( CODEPTR(), tbb::internal::FLOW_PRIORITY_QUEUE_NODE, &(this->my_graph),
2778  static_cast<receiver<input_type> *>(this),
2779  static_cast<sender<output_type> *>(this) );
2780  }
2781 
2782 #if TBB_PREVIEW_FLOW_GRAPH_TRACE
2783  void set_name( const char *name ) __TBB_override {
2785  }
2786 #endif
2787 
2788 protected:
2789 
2791  mark = 0;
2793  }
2794 
2798 
2801  this->internal_forward_task_impl(op, this);
2802  }
2803 
2805  this->handle_operations_impl(op_list, this);
2806  }
2807 
2809  prio_push(*(op->elem));
2811  return true;
2812  }
2813 
2815  // if empty or already reserved, don't pop
2816  if ( this->my_reserved == true || this->my_tail == 0 ) {
2818  return;
2819  }
2820 
2821  *(op->elem) = prio();
2823  prio_pop();
2824 
2825  }
2826 
2827  // pops the highest-priority item, saves copy
2829  if (this->my_reserved == true || this->my_tail == 0) {
2831  return;
2832  }
2833  this->my_reserved = true;
2834  *(op->elem) = prio();
2835  reserved_item = *(op->elem);
2837  prio_pop();
2838  }
2839 
2842  this->my_reserved = false;
2844  }
2845 
2846  void internal_release(prio_operation *op) __TBB_override {
2849  this->my_reserved = false;
2851  }
2852 
2853 private:
2854  template<typename, typename> friend class buffer_node;
2855 
2856  void order() {
2857  if (mark < this->my_tail) heapify();
2858  __TBB_ASSERT(mark == this->my_tail, "mark unequal after heapify");
2859  }
2860 
2861  bool is_item_valid() {
2862  return this->my_tail > 0;
2863  }
2864 
2865  void try_put_and_add_task(task*& last_task) {
2866  task * new_task = this->my_successors.try_put_task(this->prio());
2867  if (new_task) {
2868  // workaround for icc bug
2869  graph& graph_ref = this->graph_reference();
2870  last_task = combine_tasks(graph_ref, last_task, new_task);
2871  prio_pop();
2872  }
2873  }
2874 
2875 private:
2876  Compare compare;
2878 
2880 
2881  // in case a reheap has not been done after a push, check if the mark item is higher than the 0'th item
2882  bool prio_use_tail() {
2883  __TBB_ASSERT(mark <= this->my_tail, "mark outside bounds before test");
2884  return mark < this->my_tail && compare(this->get_my_item(0), this->get_my_item(this->my_tail - 1));
2885  }
2886 
2887  // prio_push: checks that the item will fit, expand array if necessary, put at end
2888  void prio_push(const T &src) {
2889  if ( this->my_tail >= this->my_array_size )
2890  this->grow_my_array( this->my_tail + 1 );
2891  (void) this->place_item(this->my_tail, src);
2892  ++(this->my_tail);
2893  __TBB_ASSERT(mark < this->my_tail, "mark outside bounds after push");
2894  }
2895 
2896  // prio_pop: deletes highest priority item from the array, and if it is item
2897  // 0, move last item to 0 and reheap. If end of array, just destroy and decrement tail
2898  // and mark. Assumes the array has already been tested for emptiness; no failure.
2899  void prio_pop() {
2900  if (prio_use_tail()) {
2901  // there are newly pushed elements; last one higher than top
2902  // copy the data
2903  this->destroy_item(this->my_tail-1);
2904  --(this->my_tail);
2905  __TBB_ASSERT(mark <= this->my_tail, "mark outside bounds after pop");
2906  return;
2907  }
2908  this->destroy_item(0);
2909  if(this->my_tail > 1) {
2910  // push the last element down heap
2911  __TBB_ASSERT(this->my_item_valid(this->my_tail - 1), NULL);
2912  this->move_item(0,this->my_tail - 1);
2913  }
2914  --(this->my_tail);
2915  if(mark > this->my_tail) --mark;
2916  if (this->my_tail > 1) // don't reheap for heap of size 1
2917  reheap();
2918  __TBB_ASSERT(mark <= this->my_tail, "mark outside bounds after pop");
2919  }
2920 
2921  const T& prio() {
2922  return this->get_my_item(prio_use_tail() ? this->my_tail-1 : 0);
2923  }
2924 
2925  // turn array into heap
2926  void heapify() {
2927  if(this->my_tail == 0) {
2928  mark = 0;
2929  return;
2930  }
2931  if (!mark) mark = 1;
2932  for (; mark<this->my_tail; ++mark) { // for each unheaped element
2933  size_type cur_pos = mark;
2934  input_type to_place;
2935  this->fetch_item(mark,to_place);
2936  do { // push to_place up the heap
2937  size_type parent = (cur_pos-1)>>1;
2938  if (!compare(this->get_my_item(parent), to_place))
2939  break;
2940  this->move_item(cur_pos, parent);
2941  cur_pos = parent;
2942  } while( cur_pos );
2943  (void) this->place_item(cur_pos, to_place);
2944  }
2945  }
2946 
2947  // otherwise heapified array with new root element; rearrange to heap
2948  void reheap() {
2949  size_type cur_pos=0, child=1;
2950  while (child < mark) {
2951  size_type target = child;
2952  if (child+1<mark &&
2953  compare(this->get_my_item(child),
2954  this->get_my_item(child+1)))
2955  ++target;
2956  // target now has the higher priority child
2957  if (compare(this->get_my_item(target),
2958  this->get_my_item(cur_pos)))
2959  break;
2960  // swap
2961  this->swap_items(cur_pos, target);
2962  cur_pos = target;
2963  child = (cur_pos<<1)+1;
2964  }
2965  }
2966 }; // priority_queue_node
2967 
2968 } // interfaceX
2969 
2970 namespace interface11 {
2971 
2973 
2976 template< typename T, typename DecrementType=continue_msg >
2977 class limiter_node : public graph_node, public receiver< T >, public sender< T > {
2978 public:
2979  typedef T input_type;
2980  typedef T output_type;
2983 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
2984  typedef typename receiver<input_type>::built_predecessors_type built_predecessors_type;
2985  typedef typename sender<output_type>::built_successors_type built_successors_type;
2986  typedef typename receiver<input_type>::predecessor_list_type predecessor_list_type;
2987  typedef typename sender<output_type>::successor_list_type successor_list_type;
2988 #endif
2989  //TODO: There is a lack of predefined types for its controlling "decrementer" port. It should be fixed later.
2990 
2991 private:
2993  size_t my_count; //number of successful puts
2994  size_t my_tries; //number of active put attempts
2998  __TBB_DEPRECATED_LIMITER_EXPR( int init_decrement_predecessors; )
2999 
3001 
3002  // Let decrementer call decrement_counter()
3003  friend class internal::decrementer< limiter_node<T,DecrementType>, DecrementType >;
3004 
3005  bool check_conditions() { // always called under lock
3006  return ( my_count + my_tries < my_threshold && !my_predecessors.empty() && !my_successors.empty() );
3007  }
3008 
3009  // only returns a valid task pointer or NULL, never SUCCESSFULLY_ENQUEUED
3011  input_type v;
3012  task *rval = NULL;
3013  bool reserved = false;
3014  {
3016  if ( check_conditions() )
3017  ++my_tries;
3018  else
3019  return NULL;
3020  }
3021 
3022  //SUCCESS
3023  // if we can reserve and can put, we consume the reservation
3024  // we increment the count and decrement the tries
3025  if ( (my_predecessors.try_reserve(v)) == true ){
3026  reserved=true;
3027  if ( (rval = my_successors.try_put_task(v)) != NULL ){
3028  {
3030  ++my_count;
3031  --my_tries;
3032  my_predecessors.try_consume();
3033  if ( check_conditions() ) {
3034  if ( internal::is_graph_active(this->my_graph) ) {
3035  task *rtask = new ( task::allocate_additional_child_of( *(this->my_graph.root_task()) ) )
3038  }
3039  }
3040  }
3041  return rval;
3042  }
3043  }
3044  //FAILURE
3045  //if we can't reserve, we decrement the tries
3046  //if we can reserve but can't put, we decrement the tries and release the reservation
3047  {
3049  --my_tries;
3050  if (reserved) my_predecessors.try_release();
3051  if ( check_conditions() ) {
3052  if ( internal::is_graph_active(this->my_graph) ) {
3053  task *rtask = new ( task::allocate_additional_child_of( *(this->my_graph.root_task()) ) )
3055  __TBB_ASSERT(!rval, "Have two tasks to handle");
3056  return rtask;
3057  }
3058  }
3059  return rval;
3060  }
3061  }
3062 
3063  void forward() {
3064  __TBB_ASSERT(false, "Should never be called");
3065  return;
3066  }
3067 
3068  task* decrement_counter( long long delta ) {
3069  {
3071  if( delta > 0 && size_t(delta) > my_count )
3072  my_count = 0;
3073  else if( delta < 0 && size_t(delta) > my_threshold - my_count )
3075  else
3076  my_count -= size_t(delta); // absolute value of delta is sufficiently small
3077  }
3078  return forward_task();
3079  }
3080 
3081  void initialize() {
3082  my_predecessors.set_owner(this);
3083  my_successors.set_owner(this);
3084  decrement.set_owner(this);
3086  CODEPTR(), tbb::internal::FLOW_LIMITER_NODE, &this->my_graph,
3087  static_cast<receiver<input_type> *>(this), static_cast<receiver<DecrementType> *>(&decrement),
3088  static_cast<sender<output_type> *>(this)
3089  );
3090  }
3091 public:
3094 
3095 #if TBB_DEPRECATED_LIMITER_NODE_CONSTRUCTOR
3097  "Deprecated interface of the limiter node can be used only in conjunction "
3098  "with continue_msg as the type of DecrementType template parameter." );
3099 #endif // Check for incompatible interface
3100 
3103  __TBB_DEPRECATED_LIMITER_ARG2(size_t threshold, int num_decrement_predecessors=0))
3104  : graph_node(g), my_threshold(threshold), my_count(0),
3106  my_tries(0), decrement(),
3107  init_decrement_predecessors(num_decrement_predecessors),
3108  decrement(num_decrement_predecessors)) {
3109  initialize();
3110  }
3111 
3112 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
3113  template <typename... Args>
3114  limiter_node(const node_set<Args...>& nodes, size_t threshold)
3115  : limiter_node(nodes.graph_reference(), threshold) {
3116  make_edges_in_order(nodes, *this);
3117  }
3118 #endif
3119 
3121  limiter_node( const limiter_node& src ) :
3122  graph_node(src.my_graph), receiver<T>(), sender<T>(),
3125  my_tries(0), decrement(),
3126  init_decrement_predecessors(src.init_decrement_predecessors),
3127  decrement(src.init_decrement_predecessors)) {
3128  initialize();
3129  }
3130 
3131 #if TBB_PREVIEW_FLOW_GRAPH_TRACE
3132  void set_name( const char *name ) __TBB_override {
3134  }
3135 #endif
3136 
3140  bool was_empty = my_successors.empty();
3141  my_successors.register_successor(r);
3142  //spawn a forward task if this is the only successor
3143  if ( was_empty && !my_predecessors.empty() && my_count + my_tries < my_threshold ) {
3144  if ( internal::is_graph_active(this->my_graph) ) {
3145  task* task = new ( task::allocate_additional_child_of( *(this->my_graph.root_task()) ) )
3148  }
3149  }
3150  return true;
3151  }
3152 
3154 
3156  r.remove_predecessor(*this);
3157  my_successors.remove_successor(r);
3158  return true;
3159  }
3160 
3161 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
3162  built_successors_type &built_successors() __TBB_override { return my_successors.built_successors(); }
3163  built_predecessors_type &built_predecessors() __TBB_override { return my_predecessors.built_predecessors(); }
3164 
3165  void internal_add_built_successor(successor_type &src) __TBB_override {
3166  my_successors.internal_add_built_successor(src);
3167  }
3168 
3169  void internal_delete_built_successor(successor_type &src) __TBB_override {
3170  my_successors.internal_delete_built_successor(src);
3171  }
3172 
3173  size_t successor_count() __TBB_override { return my_successors.successor_count(); }
3174 
3175  void copy_successors(successor_list_type &v) __TBB_override {
3176  my_successors.copy_successors(v);
3177  }
3178 
3179  void internal_add_built_predecessor(predecessor_type &src) __TBB_override {
3180  my_predecessors.internal_add_built_predecessor(src);
3181  }
3182 
3183  void internal_delete_built_predecessor(predecessor_type &src) __TBB_override {
3184  my_predecessors.internal_delete_built_predecessor(src);
3185  }
3186 
3187  size_t predecessor_count() __TBB_override { return my_predecessors.predecessor_count(); }
3188 
3189  void copy_predecessors(predecessor_list_type &v) __TBB_override {
3190  my_predecessors.copy_predecessors(v);
3191  }
3192 
3193  void extract() __TBB_override {
3194  my_count = 0;
3195  my_successors.built_successors().sender_extract(*this);
3196  my_predecessors.built_predecessors().receiver_extract(*this);
3197  decrement.built_predecessors().receiver_extract(decrement);
3198  }
3199 #endif /* TBB_DEPRECATED_FLOW_NODE_EXTRACTION */
3200 
3204  my_predecessors.add( src );
3205  if ( my_count + my_tries < my_threshold && !my_successors.empty() && internal::is_graph_active(this->my_graph) ) {
3206  task* task = new ( task::allocate_additional_child_of( *(this->my_graph.root_task()) ) )
3209  }
3210  return true;
3211  }
3212 
3215  my_predecessors.remove( src );
3216  return true;
3217  }
3218 
3219 protected:
3220 
3221  template< typename R, typename B > friend class run_and_put_task;
3222  template<typename X, typename Y> friend class internal::broadcast_cache;
3223  template<typename X, typename Y> friend class internal::round_robin_cache;
3226  {
3228  if ( my_count + my_tries >= my_threshold )
3229  return NULL;
3230  else
3231  ++my_tries;
3232  }
3233 
3234  task * rtask = my_successors.try_put_task(t);
3235 
3236  if ( !rtask ) { // try_put_task failed.
3238  --my_tries;
3239  if (check_conditions() && internal::is_graph_active(this->my_graph)) {
3240  rtask = new ( task::allocate_additional_child_of( *(this->my_graph.root_task()) ) )
3242  }
3243  }
3244  else {
3246  ++my_count;
3247  --my_tries;
3248  }
3249  return rtask;
3250  }
3251 
3252  graph& graph_reference() const __TBB_override { return my_graph; }
3253 
3255  __TBB_ASSERT(false,NULL); // should never be called
3256  }
3257 
3259  my_count = 0;
3260  if(f & rf_clear_edges) {
3261  my_predecessors.clear();
3262  my_successors.clear();
3263  }
3264  else
3265  {
3266  my_predecessors.reset( );
3267  }
3268  decrement.reset_receiver(f);
3269  }
3270 }; // limiter_node
3271 
3273 
3277 using internal::input_port;
3278 using internal::tag_value;
3279 
3280 template<typename OutputTuple, typename JP=queueing> class join_node;
3281 
3282 template<typename OutputTuple>
3283 class join_node<OutputTuple,reserving>: public internal::unfolded_join_node<tbb::flow::tuple_size<OutputTuple>::value, reserving_port, OutputTuple, reserving> {
3284 private:
3287 public:
3288  typedef OutputTuple output_type;
3291  tbb::internal::fgt_multiinput_node<N>( CODEPTR(), tbb::internal::FLOW_JOIN_NODE_RESERVING, &this->my_graph,
3292  this->input_ports(), static_cast< sender< output_type > *>(this) );
3293  }
3294 
3295 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
3296  template <typename... Args>
3297  __TBB_NOINLINE_SYM join_node(const node_set<Args...>& nodes, reserving = reserving()) : join_node(nodes.graph_reference()) {
3298  make_edges_in_order(nodes, *this);
3299  }
3300 #endif
3301 
3303  tbb::internal::fgt_multiinput_node<N>( CODEPTR(), tbb::internal::FLOW_JOIN_NODE_RESERVING, &this->my_graph,
3304  this->input_ports(), static_cast< sender< output_type > *>(this) );
3305  }
3306 
3307 #if TBB_PREVIEW_FLOW_GRAPH_TRACE
3308  void set_name( const char *name ) __TBB_override {
3310  }
3311 #endif
3312 
3313 };
3314 
3315 template<typename OutputTuple>
3316 class join_node<OutputTuple,queueing>: public internal::unfolded_join_node<tbb::flow::tuple_size<OutputTuple>::value, queueing_port, OutputTuple, queueing> {
3317 private:
3320 public:
3321  typedef OutputTuple output_type;
3324  tbb::internal::fgt_multiinput_node<N>( CODEPTR(), tbb::internal::FLOW_JOIN_NODE_QUEUEING, &this->my_graph,
3325  this->input_ports(), static_cast< sender< output_type > *>(this) );
3326  }
3327 
3328 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
3329  template <typename... Args>
3330  __TBB_NOINLINE_SYM join_node(const node_set<Args...>& nodes, queueing = queueing()) : join_node(nodes.graph_reference()) {
3331  make_edges_in_order(nodes, *this);
3332  }
3333 #endif
3334 
3336  tbb::internal::fgt_multiinput_node<N>( CODEPTR(), tbb::internal::FLOW_JOIN_NODE_QUEUEING, &this->my_graph,
3337  this->input_ports(), static_cast< sender< output_type > *>(this) );
3338  }
3339 
3340 #if TBB_PREVIEW_FLOW_GRAPH_TRACE
3341  void set_name( const char *name ) __TBB_override {
3343  }
3344 #endif
3345 
3346 };
3347 
3348 // template for key_matching join_node
3349 // tag_matching join_node is a specialization of key_matching, and is source-compatible.
3350 template<typename OutputTuple, typename K, typename KHash>
3351 class join_node<OutputTuple, key_matching<K, KHash> > : public internal::unfolded_join_node<tbb::flow::tuple_size<OutputTuple>::value,
3352  key_matching_port, OutputTuple, key_matching<K,KHash> > {
3353 private:
3356 public:
3357  typedef OutputTuple output_type;
3359 
3360 #if __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING
3362 
3363 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
3364  template <typename... Args>
3365  join_node(const node_set<Args...>& nodes, key_matching<K, KHash> = key_matching<K, KHash>())
3366  : join_node(nodes.graph_reference()) {
3367  make_edges_in_order(nodes, *this);
3368  }
3369 #endif
3370 
3371 #endif /* __TBB_PREVIEW_MESSAGE_BASED_KEY_MATCHING */
3372 
3373  template<typename __TBB_B0, typename __TBB_B1>
3374  __TBB_NOINLINE_SYM join_node(graph &g, __TBB_B0 b0, __TBB_B1 b1) : unfolded_type(g, b0, b1) {
3375  tbb::internal::fgt_multiinput_node<N>( CODEPTR(), tbb::internal::FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph,
3376  this->input_ports(), static_cast< sender< output_type > *>(this) );
3377  }
3378  template<typename __TBB_B0, typename __TBB_B1, typename __TBB_B2>
3379  __TBB_NOINLINE_SYM join_node(graph &g, __TBB_B0 b0, __TBB_B1 b1, __TBB_B2 b2) : unfolded_type(g, b0, b1, b2) {
3380  tbb::internal::fgt_multiinput_node<N>( CODEPTR(), tbb::internal::FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph,
3381  this->input_ports(), static_cast< sender< output_type > *>(this) );
3382  }
3383  template<typename __TBB_B0, typename __TBB_B1, typename __TBB_B2, typename __TBB_B3>
3384  __TBB_NOINLINE_SYM join_node(graph &g, __TBB_B0 b0, __TBB_B1 b1, __TBB_B2 b2, __TBB_B3 b3) : unfolded_type(g, b0, b1, b2, b3) {
3385  tbb::internal::fgt_multiinput_node<N>( CODEPTR(), tbb::internal::FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph,
3386  this->input_ports(), static_cast< sender< output_type > *>(this) );
3387  }
3388  template<typename __TBB_B0, typename __TBB_B1, typename __TBB_B2, typename __TBB_B3, typename __TBB_B4>
3389  __TBB_NOINLINE_SYM join_node(graph &g, __TBB_B0 b0, __TBB_B1 b1, __TBB_B2 b2, __TBB_B3 b3, __TBB_B4 b4) :
3390  unfolded_type(g, b0, b1, b2, b3, b4) {
3391  tbb::internal::fgt_multiinput_node<N>( CODEPTR(), tbb::internal::FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph,
3392  this->input_ports(), static_cast< sender< output_type > *>(this) );
3393  }
3394 #if __TBB_VARIADIC_MAX >= 6
3395  template<typename __TBB_B0, typename __TBB_B1, typename __TBB_B2, typename __TBB_B3, typename __TBB_B4,
3396  typename __TBB_B5>
3397  __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) :
3398  unfolded_type(g, b0, b1, b2, b3, b4, b5) {
3399  tbb::internal::fgt_multiinput_node<N>( CODEPTR(), tbb::internal::FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph,
3400  this->input_ports(), static_cast< sender< output_type > *>(this) );
3401  }
3402 #endif
3403 #if __TBB_VARIADIC_MAX >= 7
3404  template<typename __TBB_B0, typename __TBB_B1, typename __TBB_B2, typename __TBB_B3, typename __TBB_B4,
3405  typename __TBB_B5, typename __TBB_B6>
3406  __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) :
3407  unfolded_type(g, b0, b1, b2, b3, b4, b5, b6) {
3408  tbb::internal::fgt_multiinput_node<N>( CODEPTR(), tbb::internal::FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph,
3409  this->input_ports(), static_cast< sender< output_type > *>(this) );
3410  }
3411 #endif
3412 #if __TBB_VARIADIC_MAX >= 8
3413  template<typename __TBB_B0, typename __TBB_B1, typename __TBB_B2, typename __TBB_B3, typename __TBB_B4,
3414  typename __TBB_B5, typename __TBB_B6, typename __TBB_B7>
3415  __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,
3416  __TBB_B7 b7) : unfolded_type(g, b0, b1, b2, b3, b4, b5, b6, b7) {
3417  tbb::internal::fgt_multiinput_node<N>( CODEPTR(), tbb::internal::FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph,
3418  this->input_ports(), static_cast< sender< output_type > *>(this) );
3419  }
3420 #endif
3421 #if __TBB_VARIADIC_MAX >= 9
3422  template<typename __TBB_B0, typename __TBB_B1, typename __TBB_B2, typename __TBB_B3, typename __TBB_B4,
3423  typename __TBB_B5, typename __TBB_B6, typename __TBB_B7, typename __TBB_B8>
3424  __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,
3425  __TBB_B7 b7, __TBB_B8 b8) : unfolded_type(g, b0, b1, b2, b3, b4, b5, b6, b7, b8) {
3426  tbb::internal::fgt_multiinput_node<N>( CODEPTR(), tbb::internal::FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph,
3427  this->input_ports(), static_cast< sender< output_type > *>(this) );
3428  }
3429 #endif
3430 #if __TBB_VARIADIC_MAX >= 10
3431  template<typename __TBB_B0, typename __TBB_B1, typename __TBB_B2, typename __TBB_B3, typename __TBB_B4,
3432  typename __TBB_B5, typename __TBB_B6, typename __TBB_B7, typename __TBB_B8, typename __TBB_B9>
3433  __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,
3434  __TBB_B7 b7, __TBB_B8 b8, __TBB_B9 b9) : unfolded_type(g, b0, b1, b2, b3, b4, b5, b6, b7, b8, b9) {
3435  tbb::internal::fgt_multiinput_node<N>( CODEPTR(), tbb::internal::FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph,
3436  this->input_ports(), static_cast< sender< output_type > *>(this) );
3437  }
3438 #endif
3439 
3440 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
3441  template <typename... Args, typename... Bodies>
3442  __TBB_NOINLINE_SYM join_node(const node_set<Args...>& nodes, Bodies... bodies)
3443  : join_node(nodes.graph_reference(), bodies...) {
3444  make_edges_in_order(nodes, *this);
3445  }
3446 #endif
3447 
3449  tbb::internal::fgt_multiinput_node<N>( CODEPTR(), tbb::internal::FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph,
3450  this->input_ports(), static_cast< sender< output_type > *>(this) );
3451  }
3452 
3453 #if TBB_PREVIEW_FLOW_GRAPH_TRACE
3454  void set_name( const char *name ) __TBB_override {
3456  }
3457 #endif
3458 
3459 };
3460 
3461 // indexer node
3463 
3464 // TODO: Implement interface with variadic template or tuple
3465 template<typename T0, typename T1=null_type, typename T2=null_type, typename T3=null_type,
3466  typename T4=null_type, typename T5=null_type, typename T6=null_type,
3467  typename T7=null_type, typename T8=null_type, typename T9=null_type> class indexer_node;
3468 
3469 //indexer node specializations
3470 template<typename T0>
3471 class indexer_node<T0> : public internal::unfolded_indexer_node<tuple<T0> > {
3472 private:
3473  static const int N = 1;
3474 public:
3475  typedef tuple<T0> InputTuple;
3479  tbb::internal::fgt_multiinput_node<N>( CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
3480  this->input_ports(), static_cast< sender< output_type > *>(this) );
3481  }
3482 
3483 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
3484  template <typename... Args>
3485  indexer_node(const node_set<Args...>& nodes) : indexer_node(nodes.graph_reference()) {
3486  make_edges_in_order(nodes, *this);
3487  }
3488 #endif
3489 
3490  // Copy constructor
3492  tbb::internal::fgt_multiinput_node<N>( CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
3493  this->input_ports(), static_cast< sender< output_type > *>(this) );
3494  }
3495 
3496 #if TBB_PREVIEW_FLOW_GRAPH_TRACE
3497  void set_name( const char *name ) __TBB_override {
3499  }
3500 #endif
3501 };
3502 
3503 template<typename T0, typename T1>
3504 class indexer_node<T0, T1> : public internal::unfolded_indexer_node<tuple<T0, T1> > {
3505 private:
3506  static const int N = 2;
3507 public:
3508  typedef tuple<T0, T1> InputTuple;
3512  tbb::internal::fgt_multiinput_node<N>( CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
3513  this->input_ports(), static_cast< sender< output_type > *>(this) );
3514  }
3515 
3516 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
3517  template <typename... Args>
3518  indexer_node(const node_set<Args...>& nodes) : indexer_node(nodes.graph_reference()) {
3519  make_edges_in_order(nodes, *this);
3520  }
3521 #endif
3522 
3523  // Copy constructor
3525  tbb::internal::fgt_multiinput_node<N>( CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
3526  this->input_ports(), static_cast< sender< output_type > *>(this) );
3527  }
3528 
3529 #if TBB_PREVIEW_FLOW_GRAPH_TRACE
3530  void set_name( const char *name ) __TBB_override {
3532  }
3533 #endif
3534 };
3535 
3536 template<typename T0, typename T1, typename T2>
3537 class indexer_node<T0, T1, T2> : public internal::unfolded_indexer_node<tuple<T0, T1, T2> > {
3538 private:
3539  static const int N = 3;
3540 public:
3541  typedef tuple<T0, T1, T2> InputTuple;
3545  tbb::internal::fgt_multiinput_node<N>( CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
3546  this->input_ports(), static_cast< sender< output_type > *>(this) );
3547  }
3548 
3549 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
3550  template <typename... Args>
3551  indexer_node(const node_set<Args...>& nodes) : indexer_node(nodes.graph_reference()) {
3552  make_edges_in_order(nodes, *this);
3553  }
3554 #endif
3555 
3556  // Copy constructor
3558  tbb::internal::fgt_multiinput_node<N>( CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
3559  this->input_ports(), static_cast< sender< output_type > *>(this) );
3560  }
3561 
3562 #if TBB_PREVIEW_FLOW_GRAPH_TRACE
3563  void set_name( const char *name ) __TBB_override {
3565  }
3566 #endif
3567 };
3568 
3569 template<typename T0, typename T1, typename T2, typename T3>
3570 class indexer_node<T0, T1, T2, T3> : public internal::unfolded_indexer_node<tuple<T0, T1, T2, T3> > {
3571 private:
3572  static const int N = 4;
3573 public:
3574  typedef tuple<T0, T1, T2, T3> InputTuple;
3578  tbb::internal::fgt_multiinput_node<N>( CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
3579  this->input_ports(), static_cast< sender< output_type > *>(this) );
3580  }
3581 
3582 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
3583  template <typename... Args>
3584  indexer_node(const node_set<Args...>& nodes) : indexer_node(nodes.graph_reference()) {
3585  make_edges_in_order(nodes, *this);
3586  }
3587 #endif
3588 
3589  // Copy constructor
3591  tbb::internal::fgt_multiinput_node<N>( CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
3592  this->input_ports(), static_cast< sender< output_type > *>(this) );
3593  }
3594 
3595 #if TBB_PREVIEW_FLOW_GRAPH_TRACE
3596  void set_name( const char *name ) __TBB_override {
3598  }
3599 #endif
3600 };
3601 
3602 template<typename T0, typename T1, typename T2, typename T3, typename T4>
3603 class indexer_node<T0, T1, T2, T3, T4> : public internal::unfolded_indexer_node<tuple<T0, T1, T2, T3, T4> > {
3604 private:
3605  static const int N = 5;
3606 public:
3607  typedef tuple<T0, T1, T2, T3, T4> InputTuple;
3611  tbb::internal::fgt_multiinput_node<N>( CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
3612  this->input_ports(), static_cast< sender< output_type > *>(this) );
3613  }
3614 
3615 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
3616  template <typename... Args>
3617  indexer_node(const node_set<Args...>& nodes) : indexer_node(nodes.graph_reference()) {
3618  make_edges_in_order(nodes, *this);
3619  }
3620 #endif
3621 
3622  // Copy constructor
3624  tbb::internal::fgt_multiinput_node<N>( CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
3625  this->input_ports(), static_cast< sender< output_type > *>(this) );
3626  }
3627 
3628 #if TBB_PREVIEW_FLOW_GRAPH_TRACE
3629  void set_name( const char *name ) __TBB_override {
3631  }
3632 #endif
3633 };
3634 
3635 #if __TBB_VARIADIC_MAX >= 6
3636 template<typename T0, typename T1, typename T2, typename T3, typename T4, typename T5>
3637 class indexer_node<T0, T1, T2, T3, T4, T5> : public internal::unfolded_indexer_node<tuple<T0, T1, T2, T3, T4, T5> > {
3638 private:
3639  static const int N = 6;
3640 public:
3641  typedef tuple<T0, T1, T2, T3, T4, T5> InputTuple;
3645  tbb::internal::fgt_multiinput_node<N>( CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
3646  this->input_ports(), static_cast< sender< output_type > *>(this) );
3647  }
3648 
3649 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
3650  template <typename... Args>
3651  indexer_node(const node_set<Args...>& nodes) : indexer_node(nodes.graph_reference()) {
3652  make_edges_in_order(nodes, *this);
3653  }
3654 #endif
3655 
3656  // Copy constructor
3658  tbb::internal::fgt_multiinput_node<N>( CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
3659  this->input_ports(), static_cast< sender< output_type > *>(this) );
3660  }
3661 
3662 #if TBB_PREVIEW_FLOW_GRAPH_TRACE
3663  void set_name( const char *name ) __TBB_override {
3665  }
3666 #endif
3667 };
3668 #endif //variadic max 6
3669 
3670 #if __TBB_VARIADIC_MAX >= 7
3671 template<typename T0, typename T1, typename T2, typename T3, typename T4, typename T5,
3672  typename T6>
3673 class indexer_node<T0, T1, T2, T3, T4, T5, T6> : public internal::unfolded_indexer_node<tuple<T0, T1, T2, T3, T4, T5, T6> > {
3674 private:
3675  static const int N = 7;
3676 public:
3677  typedef tuple<T0, T1, T2, T3, T4, T5, T6> InputTuple;
3681  tbb::internal::fgt_multiinput_node<N>( CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
3682  this->input_ports(), static_cast< sender< output_type > *>(this) );
3683  }
3684 
3685 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
3686  template <typename... Args>
3687  indexer_node(const node_set<Args...>& nodes) : indexer_node(nodes.graph_reference()) {
3688  make_edges_in_order(nodes, *this);
3689  }
3690 #endif
3691 
3692  // Copy constructor
3694  tbb::internal::fgt_multiinput_node<N>( CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
3695  this->input_ports(), static_cast< sender< output_type > *>(this) );
3696  }
3697 
3698 #if TBB_PREVIEW_FLOW_GRAPH_TRACE
3699  void set_name( const char *name ) __TBB_override {
3701  }
3702 #endif
3703 };
3704 #endif //variadic max 7
3705 
3706 #if __TBB_VARIADIC_MAX >= 8
3707 template<typename T0, typename T1, typename T2, typename T3, typename T4, typename T5,
3708  typename T6, typename T7>
3709 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> > {
3710 private:
3711  static const int N = 8;
3712 public:
3713  typedef tuple<T0, T1, T2, T3, T4, T5, T6, T7> InputTuple;
3717  tbb::internal::fgt_multiinput_node<N>( CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
3718  this->input_ports(), static_cast< sender< output_type > *>(this) );
3719  }
3720 
3721 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
3722  template <typename... Args>
3723  indexer_node(const node_set<Args...>& nodes) : indexer_node(nodes.graph_reference()) {
3724  make_edges_in_order(nodes, *this);
3725  }
3726 #endif
3727 
3728  // Copy constructor
3729  indexer_node( const indexer_node& other ) : unfolded_type(other) {
3730  tbb::internal::fgt_multiinput_node<N>( CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
3731  this->input_ports(), static_cast< sender< output_type > *>(this) );
3732  }
3733 
3734 #if TBB_PREVIEW_FLOW_GRAPH_TRACE
3735  void set_name( const char *name ) __TBB_override {
3737  }
3738 #endif
3739 };
3740 #endif //variadic max 8
3741 
3742 #if __TBB_VARIADIC_MAX >= 9
3743 template<typename T0, typename T1, typename T2, typename T3, typename T4, typename T5,
3744  typename T6, typename T7, typename T8>
3745 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> > {
3746 private:
3747  static const int N = 9;
3748 public:
3749  typedef tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8> InputTuple;
3753  tbb::internal::fgt_multiinput_node<N>( CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
3754  this->input_ports(), static_cast< sender< output_type > *>(this) );
3755  }
3756 
3757 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
3758  template <typename... Args>
3759  indexer_node(const node_set<Args...>& nodes) : indexer_node(nodes.graph_reference()) {
3760  make_edges_in_order(nodes, *this);
3761  }
3762 #endif
3763 
3764  // Copy constructor
3766  tbb::internal::fgt_multiinput_node<N>( CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
3767  this->input_ports(), static_cast< sender< output_type > *>(this) );
3768  }
3769 
3770 #if TBB_PREVIEW_FLOW_GRAPH_TRACE
3771  void set_name( const char *name ) __TBB_override {
3773  }
3774 #endif
3775 };
3776 #endif //variadic max 9
3777 
3778 #if __TBB_VARIADIC_MAX >= 10
3779 template<typename T0, typename T1, typename T2, typename T3, typename T4, typename T5,
3780  typename T6, typename T7, typename T8, typename T9>
3781 class indexer_node/*default*/ : public internal::unfolded_indexer_node<tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> > {
3782 private:
3783  static const int N = 10;
3784 public:
3785  typedef tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> InputTuple;
3789  tbb::internal::fgt_multiinput_node<N>( CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
3790  this->input_ports(), static_cast< sender< output_type > *>(this) );
3791  }
3792 
3793 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
3794  template <typename... Args>
3795  indexer_node(const node_set<Args...>& nodes) : indexer_node(nodes.graph_reference()) {
3796  make_edges_in_order(nodes, *this);
3797  }
3798 #endif
3799 
3800  // Copy constructor
3802  tbb::internal::fgt_multiinput_node<N>( CODEPTR(), tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
3803  this->input_ports(), static_cast< sender< output_type > *>(this) );
3804  }
3805 
3806 #if TBB_PREVIEW_FLOW_GRAPH_TRACE
3807  void set_name( const char *name ) __TBB_override {
3809  }
3810 #endif
3811 };
3812 #endif //variadic max 10
3813 
3814 #if __TBB_PREVIEW_ASYNC_MSG
3815 inline void internal_make_edge( internal::untyped_sender &p, internal::untyped_receiver &s ) {
3816 #else
3817 template< typename T >
3819 #endif
3820 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
3821  s.internal_add_built_predecessor(p);
3822  p.internal_add_built_successor(s);
3823 #endif
3824  p.register_successor( s );
3826 }
3827 
3829 template< typename T >
3830 inline void make_edge( sender<T> &p, receiver<T> &s ) {
3831  internal_make_edge( p, s );
3832 }
3833 
3834 #if __TBB_PREVIEW_ASYNC_MSG
3835 template< typename TS, typename TR,
3838 inline void make_edge( TS &p, TR &s ) {
3839  internal_make_edge( p, s );
3840 }
3841 
3842 template< typename T >
3843 inline void make_edge( sender<T> &p, receiver<typename T::async_msg_data_type> &s ) {
3844  internal_make_edge( p, s );
3845 }
3846 
3847 template< typename T >
3848 inline void make_edge( sender<typename T::async_msg_data_type> &p, receiver<T> &s ) {
3849  internal_make_edge( p, s );
3850 }
3851 
3852 #endif // __TBB_PREVIEW_ASYNC_MSG
3853 
3854 #if __TBB_FLOW_GRAPH_CPP11_FEATURES
3855 //Makes an edge from port 0 of a multi-output predecessor to port 0 of a multi-input successor.
3856 template< typename T, typename V,
3857  typename = typename T::output_ports_type, typename = typename V::input_ports_type >
3858 inline void make_edge( T& output, V& input) {
3859  make_edge(get<0>(output.output_ports()), get<0>(input.input_ports()));
3860 }
3861 
3862 //Makes an edge from port 0 of a multi-output predecessor to a receiver.
3863 template< typename T, typename R,
3864  typename = typename T::output_ports_type >
3865 inline void make_edge( T& output, receiver<R>& input) {
3866  make_edge(get<0>(output.output_ports()), input);
3867 }
3868 
3869 //Makes an edge from a sender to port 0 of a multi-input successor.
3870 template< typename S, typename V,
3871  typename = typename V::input_ports_type >
3872 inline void make_edge( sender<S>& output, V& input) {
3873  make_edge(output, get<0>(input.input_ports()));
3874 }
3875 #endif
3876 
3877 #if __TBB_PREVIEW_ASYNC_MSG
3878 inline void internal_remove_edge( internal::untyped_sender &p, internal::untyped_receiver &s ) {
3879 #else
3880 template< typename T >
3882 #endif
3883  p.remove_successor( s );
3884 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
3885  // TODO: should we try to remove p from the predecessor list of s, in case the edge is reversed?
3886  p.internal_delete_built_successor(s);
3887  s.internal_delete_built_predecessor(p);
3888 #endif
3890 }
3891 
3893 template< typename T >
3894 inline void remove_edge( sender<T> &p, receiver<T> &s ) {
3895  internal_remove_edge( p, s );
3896 }
3897 
3898 #if __TBB_PREVIEW_ASYNC_MSG
3899 template< typename TS, typename TR,
3902 inline void remove_edge( TS &p, TR &s ) {
3903  internal_remove_edge( p, s );
3904 }
3905 
3906 template< typename T >
3907 inline void remove_edge( sender<T> &p, receiver<typename T::async_msg_data_type> &s ) {
3908  internal_remove_edge( p, s );
3909 }
3910 
3911 template< typename T >
3912 inline void remove_edge( sender<typename T::async_msg_data_type> &p, receiver<T> &s ) {
3913  internal_remove_edge( p, s );
3914 }
3915 #endif // __TBB_PREVIEW_ASYNC_MSG
3916 
3917 #if __TBB_FLOW_GRAPH_CPP11_FEATURES
3918 //Removes an edge between port 0 of a multi-output predecessor and port 0 of a multi-input successor.
3919 template< typename T, typename V,
3920  typename = typename T::output_ports_type, typename = typename V::input_ports_type >
3921 inline void remove_edge( T& output, V& input) {
3922  remove_edge(get<0>(output.output_ports()), get<0>(input.input_ports()));
3923 }
3924 
3925 //Removes an edge between port 0 of a multi-output predecessor and a receiver.
3926 template< typename T, typename R,
3927  typename = typename T::output_ports_type >
3928 inline void remove_edge( T& output, receiver<R>& input) {
3929  remove_edge(get<0>(output.output_ports()), input);
3930 }
3931 //Removes an edge between a sender and port 0 of a multi-input successor.
3932 template< typename S, typename V,
3933  typename = typename V::input_ports_type >
3934 inline void remove_edge( sender<S>& output, V& input) {
3935  remove_edge(output, get<0>(input.input_ports()));
3936 }
3937 #endif
3938 
3939 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
3940 template<typename C >
3941 template< typename S >
3942 void internal::edge_container<C>::sender_extract( S &s ) {
3943  edge_list_type e = built_edges;
3944  for ( typename edge_list_type::iterator i = e.begin(); i != e.end(); ++i ) {
3945  remove_edge(s, **i);
3946  }
3947 }
3948 
3949 template<typename C >
3950 template< typename R >
3951 void internal::edge_container<C>::receiver_extract( R &r ) {
3952  edge_list_type e = built_edges;
3953  for ( typename edge_list_type::iterator i = e.begin(); i != e.end(); ++i ) {
3954  remove_edge(**i, r);
3955  }
3956 }
3957 #endif /* TBB_DEPRECATED_FLOW_NODE_EXTRACTION */
3958 
3960 template< typename Body, typename Node >
3961 Body copy_body( Node &n ) {
3962  return n.template copy_function_object<Body>();
3963 }
3964 
3965 #if __TBB_FLOW_GRAPH_CPP11_FEATURES
3966 
3967 //composite_node
3968 template< typename InputTuple, typename OutputTuple > class composite_node;
3969 
3970 template< typename... InputTypes, typename... OutputTypes>
3971 class composite_node <tbb::flow::tuple<InputTypes...>, tbb::flow::tuple<OutputTypes...> > : public graph_node{
3972 
3973 public:
3974  typedef tbb::flow::tuple< receiver<InputTypes>&... > input_ports_type;
3975  typedef tbb::flow::tuple< sender<OutputTypes>&... > output_ports_type;
3976 
3977 private:
3978  std::unique_ptr<input_ports_type> my_input_ports;
3979  std::unique_ptr<output_ports_type> my_output_ports;
3980 
3981  static const size_t NUM_INPUTS = sizeof...(InputTypes);
3982  static const size_t NUM_OUTPUTS = sizeof...(OutputTypes);
3983 
3984 protected:
3986 
3987 public:
3988 #if TBB_PREVIEW_FLOW_GRAPH_TRACE
3989  composite_node( graph &g, const char *type_name = "composite_node" ) : graph_node(g) {
3990  tbb::internal::fgt_multiinput_multioutput_node( CODEPTR(), tbb::internal::FLOW_COMPOSITE_NODE, this, &this->my_graph );
3992  }
3993 #else
3995  tbb::internal::fgt_multiinput_multioutput_node( CODEPTR(), tbb::internal::FLOW_COMPOSITE_NODE, this, &this->my_graph );
3996  }
3997 #endif
3998 
3999  template<typename T1, typename T2>
4000  void set_external_ports(T1&& input_ports_tuple, T2&& output_ports_tuple) {
4001  __TBB_STATIC_ASSERT(NUM_INPUTS == tbb::flow::tuple_size<input_ports_type>::value, "number of arguments does not match number of input ports");
4002  __TBB_STATIC_ASSERT(NUM_OUTPUTS == tbb::flow::tuple_size<output_ports_type>::value, "number of arguments does not match number of output ports");
4003  my_input_ports = tbb::internal::make_unique<input_ports_type>(std::forward<T1>(input_ports_tuple));
4004  my_output_ports = tbb::internal::make_unique<output_ports_type>(std::forward<T2>(output_ports_tuple));
4005 
4008  }
4009 
4010  template< typename... NodeTypes >
4011  void add_visible_nodes(const NodeTypes&... n) { internal::add_nodes_impl(this, true, n...); }
4012 
4013  template< typename... NodeTypes >
4014  void add_nodes(const NodeTypes&... n) { internal::add_nodes_impl(this, false, n...); }
4015 
4016 #if TBB_PREVIEW_FLOW_GRAPH_TRACE
4017  void set_name( const char *name ) __TBB_override {
4019  }
4020 #endif
4021 
4023  __TBB_ASSERT(my_input_ports, "input ports not set, call set_external_ports to set input ports");
4024  return *my_input_ports;
4025  }
4026 
4028  __TBB_ASSERT(my_output_ports, "output ports not set, call set_external_ports to set output ports");
4029  return *my_output_ports;
4030  }
4031 
4032 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
4033  void extract() __TBB_override {
4034  __TBB_ASSERT(false, "Current composite_node implementation does not support extract");
4035  }
4036 #endif
4037 }; // class composite_node
4038 
4039 //composite_node with only input ports
4040 template< typename... InputTypes>
4041 class composite_node <tbb::flow::tuple<InputTypes...>, tbb::flow::tuple<> > : public graph_node {
4042 public:
4043  typedef tbb::flow::tuple< receiver<InputTypes>&... > input_ports_type;
4044 
4045 private:
4046  std::unique_ptr<input_ports_type> my_input_ports;
4047  static const size_t NUM_INPUTS = sizeof...(InputTypes);
4048 
4049 protected:
4051 
4052 public:
4053 #if TBB_PREVIEW_FLOW_GRAPH_TRACE
4054  composite_node( graph &g, const char *type_name = "composite_node") : graph_node(g) {
4055  tbb::internal::fgt_composite( CODEPTR(), this, &g );
4057  }
4058 #else
4060  tbb::internal::fgt_composite( CODEPTR(), this, &g );
4061  }
4062 #endif
4063 
4064  template<typename T>
4065  void set_external_ports(T&& input_ports_tuple) {
4066  __TBB_STATIC_ASSERT(NUM_INPUTS == tbb::flow::tuple_size<input_ports_type>::value, "number of arguments does not match number of input ports");
4067 
4068  my_input_ports = tbb::internal::make_unique<input_ports_type>(std::forward<T>(input_ports_tuple));
4069 
4070  tbb::internal::fgt_internal_input_alias_helper<T, NUM_INPUTS>::alias_port( this, std::forward<T>(input_ports_tuple));
4071  }
4072 
4073  template< typename... NodeTypes >
4074  void add_visible_nodes(const NodeTypes&... n) { internal::add_nodes_impl(this, true, n...); }
4075 
4076  template< typename... NodeTypes >
4077  void add_nodes( const NodeTypes&... n) { internal::add_nodes_impl(this, false, n...); }
4078 
4079 #if TBB_PREVIEW_FLOW_GRAPH_TRACE
4080  void set_name( const char *name ) __TBB_override {
4082  }
4083 #endif
4084 
4086  __TBB_ASSERT(my_input_ports, "input ports not set, call set_external_ports to set input ports");
4087  return *my_input_ports;
4088  }
4089 
4090 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
4091  void extract() __TBB_override {
4092  __TBB_ASSERT(false, "Current composite_node implementation does not support extract");
4093  }
4094 #endif
4095 
4096 }; // class composite_node
4097 
4098 //composite_nodes with only output_ports
4099 template<typename... OutputTypes>
4100 class composite_node <tbb::flow::tuple<>, tbb::flow::tuple<OutputTypes...> > : public graph_node {
4101 public:
4102  typedef tbb::flow::tuple< sender<OutputTypes>&... > output_ports_type;
4103 
4104 private:
4105  std::unique_ptr<output_ports_type> my_output_ports;
4106  static const size_t NUM_OUTPUTS = sizeof...(OutputTypes);
4107 
4108 protected:
4110 
4111 public:
4112 #if TBB_PREVIEW_FLOW_GRAPH_TRACE
4113  __TBB_NOINLINE_SYM composite_node( graph &g, const char *type_name = "composite_node") : graph_node(g) {
4114  tbb::internal::fgt_composite( CODEPTR(), this, &g );
4116  }
4117 #else
4119  tbb::internal::fgt_composite( CODEPTR(), this, &g );
4120  }
4121 #endif
4122 
4123  template<typename T>
4124  void set_external_ports(T&& output_ports_tuple) {
4125  __TBB_STATIC_ASSERT(NUM_OUTPUTS == tbb::flow::tuple_size<output_ports_type>::value, "number of arguments does not match number of output ports");
4126 
4127  my_output_ports = tbb::internal::make_unique<output_ports_type>(std::forward<T>(output_ports_tuple));
4128 
4129  tbb::internal::fgt_internal_output_alias_helper<T, NUM_OUTPUTS>::alias_port( this, std::forward<T>(output_ports_tuple));
4130  }
4131 
4132  template<typename... NodeTypes >
4133  void add_visible_nodes(const NodeTypes&... n) { internal::add_nodes_impl(this, true, n...); }
4134 
4135  template<typename... NodeTypes >
4136  void add_nodes(const NodeTypes&... n) { internal::add_nodes_impl(this, false, n...); }
4137 
4138 #if TBB_PREVIEW_FLOW_GRAPH_TRACE
4139  void set_name( const char *name ) __TBB_override {
4141  }
4142 #endif
4143 
4145  __TBB_ASSERT(my_output_ports, "output ports not set, call set_external_ports to set output ports");
4146  return *my_output_ports;
4147  }
4148 
4149 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
4150  void extract() __TBB_override {
4151  __TBB_ASSERT(false, "Current composite_node implementation does not support extract");
4152  }
4153 #endif
4154 
4155 }; // class composite_node
4156 
4157 #endif // __TBB_FLOW_GRAPH_CPP11_FEATURES
4158 
4159 namespace internal {
4160 
4161 template<typename Gateway>
4163 public:
4164  typedef Gateway gateway_type;
4165 
4166  async_body_base(gateway_type *gateway): my_gateway(gateway) { }
4167  void set_gateway(gateway_type *gateway) {
4168  my_gateway = gateway;
4169  }
4170 
4171 protected:
4173 };
4174 
4175 template<typename Input, typename Ports, typename Gateway, typename Body>
4176 class async_body: public async_body_base<Gateway> {
4177 public:
4179  typedef Gateway gateway_type;
4180 
4181  async_body(const Body &body, gateway_type *gateway)
4182  : base_type(gateway), my_body(body) { }
4183 
4184  void operator()( const Input &v, Ports & ) {
4185  my_body(v, *this->my_gateway);
4186  }
4187 
4188  Body get_body() { return my_body; }
4189 
4190 private:
4191  Body my_body;
4192 };
4193 
4194 } // namespace internal
4195 
4196 } // namespace interfaceX
4197 namespace interface11 {
4198 
4200 template < typename Input, typename Output,
4201  typename Policy = queueing_lightweight,
4202  typename Allocator=__TBB_DEFAULT_NODE_ALLOCATOR(Input) >
4204  : public multifunction_node< Input, tuple< Output >, Policy, Allocator >, public sender< Output >
4205 {
4206 #if !TBB_DEPRECATED_FLOW_NODE_ALLOCATOR
4209  "Allocator template parameter for flow graph nodes is deprecated and will removed in the future. "
4210  "To temporary enable the deprecated interface specify TBB_ENABLE_DEPRECATED_NODE_ALLOCATOR."
4211  );
4212 #endif
4215 
4216 public:
4217  typedef Input input_type;
4218  typedef Output output_type;
4220  typedef typename receiver_type::predecessor_type predecessor_type;
4225 
4226 private:
4230  // TODO: pass value by copy since we do not want to block asynchronous thread.
4231  const Output *value;
4232  bool result;
4233  try_put_functor(output_port_type &p, const Output &v) : port(&p), value(&v), result(false) { }
4234  void operator()() {
4235  result = port->try_put(*value);
4236  }
4237  };
4238 
4239  class receiver_gateway_impl: public receiver_gateway<Output> {
4240  public:
4241  receiver_gateway_impl(async_node* node): my_node(node) {}
4243  tbb::internal::fgt_async_reserve(static_cast<typename async_node::receiver_type *>(my_node), &my_node->my_graph);
4244  my_node->my_graph.reserve_wait();
4245  }
4246 
4248  my_node->my_graph.release_wait();
4249  tbb::internal::fgt_async_commit(static_cast<typename async_node::receiver_type *>(my_node), &my_node->my_graph);
4250  }
4251 
4253  bool try_put(const Output &i) __TBB_override {
4254  return my_node->try_put_impl(i);
4255  }
4256 
4257  private:
4259  } my_gateway;
4260 
4261  //The substitute of 'this' for member construction, to prevent compiler warnings
4262  async_node* self() { return this; }
4263 
4265  bool try_put_impl(const Output &i) {
4266  internal::multifunction_output<Output> &port_0 = internal::output_port<0>(*this);
4267  internal::broadcast_cache<output_type>& port_successors = port_0.successors();
4269  task_list tasks;
4270  bool is_at_least_one_put_successful = port_successors.gather_successful_try_puts(i, tasks);
4271  __TBB_ASSERT( is_at_least_one_put_successful || tasks.empty(),
4272  "Return status is inconsistent with the method operation." );
4273 
4274  while( !tasks.empty() ) {
4275  internal::enqueue_in_graph_arena(this->my_graph, tasks.pop_front());
4276  }
4277  tbb::internal::fgt_async_try_put_end(this, &port_0);
4278  return is_at_least_one_put_successful;
4279  }
4280 
4281 public:
4282  template<typename Body>
4284  graph &g, size_t concurrency,
4286  Body body, __TBB_FLOW_GRAPH_PRIORITY_ARG1(Policy = Policy(), node_priority_t priority = tbb::flow::internal::no_priority)
4287 #else
4289 #endif
4290  ) : base_type(
4291  g, concurrency,
4292  internal::async_body<Input, typename base_type::output_ports_type, gateway_type, Body>
4293  (body, &my_gateway) __TBB_FLOW_GRAPH_PRIORITY_ARG0(priority) ), my_gateway(self()) {
4294  tbb::internal::fgt_multioutput_node_with_body<1>(
4295  CODEPTR(), tbb::internal::FLOW_ASYNC_NODE,
4296  &this->my_graph, static_cast<receiver<input_type> *>(this),
4297  this->output_ports(), this->my_body
4298  );
4299  }
4300 
4301 #if __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES && __TBB_CPP11_PRESENT
4302  template <typename Body, typename... Args>
4303  __TBB_NOINLINE_SYM async_node(graph& g, size_t concurrency, Body body, node_priority_t priority)
4304  : async_node(g, concurrency, body, Policy(), priority) {}
4305 #endif // __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES
4306 
4307 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
4308  template <typename Body, typename... Args>
4310  const node_set<Args...>& nodes, size_t concurrency, Body body,
4312  ) : async_node(nodes.graph_reference(), concurrency, __TBB_FLOW_GRAPH_PRIORITY_ARG1(body, priority)) {
4313  make_edges_in_order(nodes, *this);
4314  }
4315 
4316 #if __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES
4317  template <typename Body, typename... Args>
4318  __TBB_NOINLINE_SYM async_node(const node_set<Args...>& nodes, size_t concurrency, Body body, node_priority_t priority)
4319  : async_node(nodes, concurrency, body, Policy(), priority) {}
4320 #endif // __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES
4321 #endif // __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
4322 
4323  __TBB_NOINLINE_SYM async_node( const async_node &other ) : base_type(other), sender<Output>(), my_gateway(self()) {
4324  static_cast<async_body_base_type*>(this->my_body->get_body_ptr())->set_gateway(&my_gateway);
4325  static_cast<async_body_base_type*>(this->my_init_body->get_body_ptr())->set_gateway(&my_gateway);
4326 
4327  tbb::internal::fgt_multioutput_node_with_body<1>( CODEPTR(), tbb::internal::FLOW_ASYNC_NODE,
4328  &this->my_graph, static_cast<receiver<input_type> *>(this),
4329  this->output_ports(), this->my_body );
4330  }
4331 
4333  return my_gateway;
4334  }
4335 
4336 #if TBB_PREVIEW_FLOW_GRAPH_TRACE
4337  void set_name( const char *name ) __TBB_override {
4339  }
4340 #endif
4341 
4342  // Define sender< Output >
4343 
4346  return internal::output_port<0>(*this).register_successor(r);
4347  }
4348 
4351  return internal::output_port<0>(*this).remove_successor(r);
4352  }
4353 
4354  template<typename Body>
4358  mfn_body_type &body_ref = *this->my_body;
4359  async_body_type ab = *static_cast<async_body_type*>(dynamic_cast< internal::multifunction_body_leaf<input_type, typename base_type::output_ports_type, async_body_type> & >(body_ref).get_body_ptr());
4360  return ab.get_body();
4361  }
4362 
4363 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
4364  typedef typename internal::edge_container<successor_type> built_successors_type;
4366  typedef typename built_successors_type::edge_list_type successor_list_type;
4367  built_successors_type &built_successors() __TBB_override {
4368  return internal::output_port<0>(*this).built_successors();
4369  }
4370 
4371  void internal_add_built_successor( successor_type &r ) __TBB_override {
4372  internal::output_port<0>(*this).internal_add_built_successor(r);
4373  }
4374 
4375  void internal_delete_built_successor( successor_type &r ) __TBB_override {
4376  internal::output_port<0>(*this).internal_delete_built_successor(r);
4377  }
4378 
4379  void copy_successors( successor_list_type &l ) __TBB_override {
4380  internal::output_port<0>(*this).copy_successors(l);
4381  }
4382 
4383  size_t successor_count() __TBB_override {
4384  return internal::output_port<0>(*this).successor_count();
4385  }
4386 #endif /* TBB_DEPRECATED_FLOW_NODE_EXTRACTION */
4387 
4388 protected:
4389 
4391  base_type::reset_node(f);
4392  }
4393 };
4394 
4395 #if __TBB_PREVIEW_STREAMING_NODE
4397 #endif // __TBB_PREVIEW_STREAMING_NODE
4398 
4400 
4401 template< typename T >
4402 class overwrite_node : public graph_node, public receiver<T>, public sender<T> {
4403 public:
4404  typedef T input_type;
4405  typedef T output_type;
4408 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
4409  typedef typename receiver<input_type>::built_predecessors_type built_predecessors_type;
4410  typedef typename sender<output_type>::built_successors_type built_successors_type;
4411  typedef typename receiver<input_type>::predecessor_list_type predecessor_list_type;
4412  typedef typename sender<output_type>::successor_list_type successor_list_type;
4413 #endif
4414 
4415  __TBB_NOINLINE_SYM explicit overwrite_node(graph &g) : graph_node(g), my_buffer_is_valid(false) {
4416  my_successors.set_owner( this );
4417  tbb::internal::fgt_node( CODEPTR(), tbb::internal::FLOW_OVERWRITE_NODE, &this->my_graph,
4418  static_cast<receiver<input_type> *>(this), static_cast<sender<output_type> *>(this) );
4419  }
4420 
4421 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
4422  template <typename... Args>
4423  overwrite_node(const node_set<Args...>& nodes) : overwrite_node(nodes.graph_reference()) {
4424  make_edges_in_order(nodes, *this);
4425  }
4426 #endif
4427 
4430  graph_node(src.my_graph), receiver<T>(), sender<T>(), my_buffer_is_valid(false)
4431  {
4432  my_successors.set_owner( this );
4433  tbb::internal::fgt_node( CODEPTR(), tbb::internal::FLOW_OVERWRITE_NODE, &this->my_graph,
4434  static_cast<receiver<input_type> *>(this), static_cast<sender<output_type> *>(this) );
4435  }
4436 
4438 
4439 #if TBB_PREVIEW_FLOW_GRAPH_TRACE
4440  void set_name( const char *name ) __TBB_override {
4442  }
4443 #endif
4444 
4446  spin_mutex::scoped_lock l( my_mutex );
4447  if (my_buffer_is_valid && internal::is_graph_active( my_graph )) {
4448  // We have a valid value that must be forwarded immediately.
4449  bool ret = s.try_put( my_buffer );
4450  if ( ret ) {
4451  // We add the successor that accepted our put
4452  my_successors.register_successor( s );
4453  } else {
4454  // In case of reservation a race between the moment of reservation and register_successor can appear,
4455  // because failed reserve does not mean that register_successor is not ready to put a message immediately.
4456  // We have some sort of infinite loop: reserving node tries to set pull state for the edge,
4457  // but overwrite_node tries to return push state back. That is why we have to break this loop with task creation.
4458  task *rtask = new ( task::allocate_additional_child_of( *( my_graph.root_task() ) ) )
4459  register_predecessor_task( *this, s );
4460  internal::spawn_in_graph_arena( my_graph, *rtask );
4461  }
4462  } else {
4463  // No valid value yet, just add as successor
4464  my_successors.register_successor( s );
4465  }
4466  return true;
4467  }
4468 
4470  spin_mutex::scoped_lock l( my_mutex );
4471  my_successors.remove_successor(s);
4472  return true;
4473  }
4474 
4475 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
4476  built_predecessors_type &built_predecessors() __TBB_override { return my_built_predecessors; }
4477  built_successors_type &built_successors() __TBB_override { return my_successors.built_successors(); }
4478 
4479  void internal_add_built_successor( successor_type &s) __TBB_override {
4480  spin_mutex::scoped_lock l( my_mutex );
4481  my_successors.internal_add_built_successor(s);
4482  }
4483 
4484  void internal_delete_built_successor( successor_type &s) __TBB_override {
4485  spin_mutex::scoped_lock l( my_mutex );
4486  my_successors.internal_delete_built_successor(s);
4487  }
4488 
4489  size_t successor_count() __TBB_override {
4490  spin_mutex::scoped_lock l( my_mutex );
4491  return my_successors.successor_count();
4492  }
4493 
4494  void copy_successors(successor_list_type &v) __TBB_override {
4495  spin_mutex::scoped_lock l( my_mutex );
4496  my_successors.copy_successors(v);
4497  }
4498 
4499  void internal_add_built_predecessor( predecessor_type &p) __TBB_override {
4500  spin_mutex::scoped_lock l( my_mutex );
4501  my_built_predecessors.add_edge(p);
4502  }
4503 
4504  void internal_delete_built_predecessor( predecessor_type &p) __TBB_override {
4505  spin_mutex::scoped_lock l( my_mutex );
4506  my_built_predecessors.delete_edge(p);
4507  }
4508 
4509  size_t predecessor_count() __TBB_override {
4510  spin_mutex::scoped_lock l( my_mutex );
4511  return my_built_predecessors.edge_count();
4512  }
4513 
4514  void copy_predecessors( predecessor_list_type &v ) __TBB_override {
4515  spin_mutex::scoped_lock l( my_mutex );
4516  my_built_predecessors.copy_edges(v);
4517  }
4518 
4519  void extract() __TBB_override {
4520  my_buffer_is_valid = false;
4521  built_successors().sender_extract(*this);
4522  built_predecessors().receiver_extract(*this);
4523  }
4524 
4525 #endif /* TBB_DEPRECATED_FLOW_NODE_EXTRACTION */
4526 
4528  spin_mutex::scoped_lock l( my_mutex );
4529  if ( my_buffer_is_valid ) {
4530  v = my_buffer;
4531  return true;
4532  }
4533  return false;
4534  }
4535 
4538  return try_get(v);
4539  }
4540 
4542  bool try_release() __TBB_override { return true; }
4543 
4545  bool try_consume() __TBB_override { return true; }
4546 
4547  bool is_valid() {
4548  spin_mutex::scoped_lock l( my_mutex );
4549  return my_buffer_is_valid;
4550  }
4551 
4552  void clear() {
4553  spin_mutex::scoped_lock l( my_mutex );
4554  my_buffer_is_valid = false;
4555  }
4556 
4557 protected:
4558 
4559  template< typename R, typename B > friend class run_and_put_task;
4560  template<typename X, typename Y> friend class internal::broadcast_cache;
4561  template<typename X, typename Y> friend class internal::round_robin_cache;
4564  return try_put_task_impl(v);
4565  }
4566 
4568  my_buffer = v;
4569  my_buffer_is_valid = true;
4570  task * rtask = my_successors.try_put_task(v);
4571  if (!rtask) rtask = SUCCESSFULLY_ENQUEUED;
4572  return rtask;
4573  }
4574 
4576  return my_graph;
4577  }
4578 
4581 
4583  o(owner), s(succ) {};
4584 
4586  if (!s.register_predecessor(o)) {
4587  o.register_successor(s);
4588  }
4589  return NULL;
4590  }
4591 
4594  };
4595 
4598 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
4599  internal::edge_container<predecessor_type> my_built_predecessors;
4600 #endif
4604 
4606  my_buffer_is_valid = false;
4607  if (f&rf_clear_edges) {
4608  my_successors.clear();
4609  }
4610  }
4611 }; // overwrite_node
4612 
4613 template< typename T >
4614 class write_once_node : public overwrite_node<T> {
4615 public:
4616  typedef T input_type;
4617  typedef T output_type;
4621 
4624  tbb::internal::fgt_node( CODEPTR(), tbb::internal::FLOW_WRITE_ONCE_NODE, &(this->my_graph),
4625  static_cast<receiver<input_type> *>(this),
4626  static_cast<sender<output_type> *>(this) );
4627  }
4628 
4629 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
4630  template <typename... Args>
4631  write_once_node(const node_set<Args...>& nodes) : write_once_node(nodes.graph_reference()) {
4632  make_edges_in_order(nodes, *this);
4633  }
4634 #endif
4635 
4638  tbb::internal::fgt_node( CODEPTR(), tbb::internal::FLOW_WRITE_ONCE_NODE, &(this->my_graph),
4639  static_cast<receiver<input_type> *>(this),
4640  static_cast<sender<output_type> *>(this) );
4641  }
4642 
4643 #if TBB_PREVIEW_FLOW_GRAPH_TRACE
4644  void set_name( const char *name ) __TBB_override {
4646  }
4647 #endif
4648 
4649 protected:
4650  template< typename R, typename B > friend class run_and_put_task;
4651  template<typename X, typename Y> friend class internal::broadcast_cache;
4652  template<typename X, typename Y> friend class internal::round_robin_cache;
4654  spin_mutex::scoped_lock l( this->my_mutex );
4655  return this->my_buffer_is_valid ? NULL : this->try_put_task_impl(v);
4656  }
4657 };
4658 
4659 } // interfaceX
4660 
4665 
4666  using interface11::graph;
4667  using interface11::graph_node;
4668  using interface11::continue_msg;
4669  using interface11::source_node;
4670  using interface11::input_node;
4671  using interface11::function_node;
4672  using interface11::multifunction_node;
4673  using interface11::split_node;
4675  using interface11::indexer_node;
4676  using interface11::internal::tagged_msg;
4679  using interface11::continue_node;
4680  using interface11::overwrite_node;
4681  using interface11::write_once_node;
4682  using interface11::broadcast_node;
4683  using interface11::buffer_node;
4684  using interface11::queue_node;
4685  using interface11::sequencer_node;
4686  using interface11::priority_queue_node;
4687  using interface11::limiter_node;
4688  using namespace interface11::internal::graph_policy_namespace;
4689  using interface11::join_node;
4691  using interface11::copy_body;
4692  using interface11::make_edge;
4695 #if __TBB_FLOW_GRAPH_CPP11_FEATURES
4696  using interface11::composite_node;
4697 #endif
4698  using interface11::async_node;
4699 #if __TBB_PREVIEW_ASYNC_MSG
4700  using interface11::async_msg;
4701 #endif
4702 #if __TBB_PREVIEW_STREAMING_NODE
4703  using interface11::port_ref;
4705 #endif // __TBB_PREVIEW_STREAMING_NODE
4706 #if __TBB_PREVIEW_FLOW_GRAPH_PRIORITIES
4708  using internal::no_priority;
4709 #endif
4710 
4711 #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET
4712  using interface11::internal::follows;
4713  using interface11::internal::precedes;
4714  using interface11::internal::make_node_set;
4715  using interface11::internal::make_edges;
4716 #endif
4717 
4718 } // flow
4719 } // tbb
4720 
4721 // Include deduction guides for node classes
4723 
4724 #undef __TBB_PFG_RESET_ARG
4725 #undef __TBB_COMMA
4726 #undef __TBB_DEFAULT_NODE_ALLOCATOR
4727 
4729 #undef __TBB_flow_graph_H_include_area
4730 
4731 #if TBB_USE_THREADING_TOOLS && TBB_PREVIEW_FLOW_GRAPH_TRACE && ( __linux__ || __APPLE__ )
4732  #undef __TBB_NOINLINE_SYM
4733 #endif
4734 
4735 #endif // __TBB_flow_graph_H
tbb::flow::interface11::buffer_node::my_aggregator
internal::aggregator< handler_type, buffer_operation > my_aggregator
Definition: flow_graph.h:2119
tbb::flow::interface11::priority_queue_node::output_type
T output_type
Definition: flow_graph.h:2751
internal::item_buffer< T, cache_aligned_allocator< T > >::move_item
void move_item(size_t to, size_t from)
Definition: _flow_graph_item_buffer_impl.h:97
tbb::flow::interface11::composite_node< tbb::flow::tuple< InputTypes... >, tbb::flow::tuple< OutputTypes... > >::input_ports_type
tbb::flow::tuple< receiver< InputTypes > &... > input_ports_type
Definition: flow_graph.h:3974
tbb::flow::interface11::priority_queue_node::internal_forward_task
void internal_forward_task(prio_operation *op) __TBB_override
Tries to forward valid items to successors.
Definition: flow_graph.h:2800
tbb::flow::interface11::indexer_node< T0, T1, T2, T3, T4 >::unfolded_type
internal::unfolded_indexer_node< InputTuple > unfolded_type
Definition: flow_graph.h:3609
tbb::flow::interface11::queue_node::internal_forward_task
void internal_forward_task(queue_operation *op) __TBB_override
Definition: flow_graph.h:2592
tbb::flow::interface11::sequencer_node::internal_push
bool internal_push(sequencer_operation *op) __TBB_override
Definition: flow_graph.h:2716
tbb::task_list
A list of children.
Definition: task.h:1074
tbb::flow::interface11::limiter_node::reset_receiver
void reset_receiver(reset_flags) __TBB_override
Definition: flow_graph.h:3254
tbb::flow::interface11::split_node::N
static const int N
Definition: flow_graph.h:1674
internal::function_input_base< Input, Policy, A, function_input< Input, Output, Policy, A > >::try_put_task
task * try_put_task(const input_type &t) __TBB_override
Definition: _flow_graph_node_impl.h:117
_flow_graph_indexer_impl.h
tbb::flow::interface11::input_node::my_has_cached_item
bool my_has_cached_item
Definition: flow_graph.h:1105
__TBB_DEPRECATED
#define __TBB_DEPRECATED
Definition: tbb_config.h:636
tbb::flow::interface11::join_node< OutputTuple, queueing >::join_node
__TBB_NOINLINE_SYM join_node(graph &g)
Definition: flow_graph.h:3323
tbb::flow::interface11::continue_node::successor_type
fOutput_type::successor_type successor_type
Definition: flow_graph.h:1781
tbb::flow::interface11::buffer_node::my_successors
internal::round_robin_cache< T, null_rw_mutex > my_successors
Definition: flow_graph.h:2069
internal::item_buffer< T, cache_aligned_allocator< T > >::push_back
bool push_back(item_type &v)
Definition: _flow_graph_item_buffer_impl.h:185
tbb::flow::interface11::function_node::input_type
Input input_type
Definition: flow_graph.h:1470
tbb::flow::interface11::priority_queue_node::is_item_valid
bool is_item_valid()
Definition: flow_graph.h:2861
tbb::flow::interface11::sender::~sender
virtual ~sender()
Definition: flow_graph.h:501
_aggregator_impl.h
tbb::flow::interface11::priority_queue_node::internal_reserve
void internal_reserve(prio_operation *op) __TBB_override
Definition: flow_graph.h:2828
tbb::flow::interface11::split_node::reset_receiver
void reset_receiver(reset_flags) __TBB_override
put receiver back in initial state
Definition: flow_graph.h:1743
internal::item_buffer< T, cache_aligned_allocator< T > >::my_item_valid
bool my_item_valid(size_type i) const
Definition: _flow_graph_item_buffer_impl.h:68
internal::reservable_predecessor_cache::try_release
bool try_release()
Definition: _flow_graph_cache_impl.h:242
tbb::flow::interface10::graph::my_root_task
tbb::task * my_root_task
Definition: _flow_graph_impl.h:408
internal::reservable_item_buffer< T, cache_aligned_allocator< T > >::reserve_front
bool reserve_front(T &v)
Definition: _flow_graph_item_buffer_impl.h:257
tbb::flow::interface11::input_node::my_body
internal::source_body< output_type > * my_body
Definition: flow_graph.h:1101
tbb::flow::interface11::priority_queue_node::size_type
buffer_node< T, Allocator >::size_type size_type
Definition: flow_graph.h:2795
tbb::flow::interface11::split_node::my_output_ports
output_ports_type my_output_ports
Definition: flow_graph.h:1768
tbb::flow::interface11::function_node::internals_allocator
cache_aligned_allocator< Input > internals_allocator
Definition: flow_graph.h:1460
streaming_node
class __TBB_DEPRECATED streaming_node
Definition: _flow_graph_streaming_node.h:302
tbb::flow::interface11::limiter_node::predecessor_type
receiver< input_type >::predecessor_type predecessor_type
Definition: flow_graph.h:2981
spin_mutex.h
tbb::flow::interface11::composite_node< tbb::flow::tuple< InputTypes... >, tbb::flow::tuple<> >::input_ports
input_ports_type & input_ports()
Definition: flow_graph.h:4085
internal::SUCCEEDED
@ SUCCEEDED
Definition: _flow_graph_types_impl.h:719
tbb::flow::interface11::indexer_node< T0 >::InputTuple
tuple< T0 > InputTuple
Definition: flow_graph.h:3475
internal
Definition: _flow_graph_async_msg_impl.h:24
tbb::flow::interface11::buffer_node::reset_receiver
void reset_receiver(reset_flags) __TBB_override
put receiver back in initial state
Definition: flow_graph.h:2534
tbb::flow::interface11::indexer_node
Definition: flow_graph.h:3467
tbb::flow::interface11::indexer_node< T0, T1, T2, T3, T4 >::output_type
internal::tagged_msg< size_t, T0, T1, T2, T3, T4 > output_type
Definition: flow_graph.h:3608
tbb::flow::interface11::receiver
Pure virtual template class that defines a receiver of messages of type T.
Definition: flow_graph.h:117
void
void
Definition: ittnotify_static.h:91
tbb::flow::interface11::buffer_node::grab_forwarding_task
task * grab_forwarding_task(buffer_operation &op_data)
Definition: flow_graph.h:2174
tbb::flow::interface11::continue_node::output_type
Output output_type
Definition: flow_graph.h:1777
tbb::flow::interface11::source_node::try_reserve_apply_body
bool try_reserve_apply_body(output_type &v)
Definition: flow_graph.h:1390
tbb::internal::fgt_remove_edge
static void fgt_remove_edge(void *, void *)
Definition: _flow_graph_trace_impl.h:334
tbb::internal::fgt_async_try_put_end
static void fgt_async_try_put_end(void *, void *)
Definition: _flow_graph_trace_impl.h:340
tbb::flow::interface11::join_node< OutputTuple, key_matching< K, KHash > >::join_node
__TBB_NOINLINE_SYM join_node(const join_node &other)
Definition: flow_graph.h:3448
tbb::internal::fgt_internal_input_alias_helper::alias_port
static void alias_port(void *, PortsTuple &)
Definition: _flow_graph_trace_impl.h:351
tbb::flow::interface11::buffer_node::predecessor_type
receiver< input_type >::predecessor_type predecessor_type
Definition: flow_graph.h:2052
tbb::flow::interface11::indexer_node::InputTuple
tuple< T0, T1, T2, T3, T4, T5, T6, T7, T8, T9 > InputTuple
Definition: flow_graph.h:3785
tbb::flow::interface11::buffer_node::rem_succ
@ rem_succ
Definition: flow_graph.h:2077
tbb::flow::interface11::continue_node::fOutput_type
internal::function_output< output_type > fOutput_type
Definition: flow_graph.h:1779
tbb::flow::interface11::indexer_node< T0, T1, T2, T3, T4, T5 >::indexer_node
__TBB_NOINLINE_SYM indexer_node(const indexer_node &other)
Definition: flow_graph.h:3657
tbb::flow::interface11::internal::is_graph_active
bool is_graph_active(tbb::flow::interface10::graph &g)
Definition: _flow_graph_impl.h:494
tbb::flow::interface11::limiter_node::input_type
T input_type
Definition: flow_graph.h:2979
tbb::flow::interface11::composite_node< tbb::flow::tuple<>, tbb::flow::tuple< OutputTypes... > >::add_visible_nodes
void add_visible_nodes(const NodeTypes &... n)
Definition: flow_graph.h:4133
tbb::flow::interface11::internal::spawn_in_graph_arena
void spawn_in_graph_arena(tbb::flow::interface10::graph &g, tbb::task &arena_task)
Spawns a task inside graph arena.
Definition: _flow_graph_impl.h:521
tbb::flow::interface11::broadcast_node::broadcast_node
__TBB_NOINLINE_SYM broadcast_node(graph &g)
Definition: flow_graph.h:1915
internal::multifunction_input
Implements methods for a function node that takes a type Input as input.
Definition: _flow_graph_node_impl.h:638
tbb::internal::fgt_multioutput_node_desc
static void fgt_multioutput_node_desc(const NodeType *, const char *)
Definition: _flow_graph_trace_impl.h:306
tbb::flow::interface11::async_node::gateway_type
receiver_gateway< output_type > gateway_type
Definition: flow_graph.h:4222
tbb::flow::interface11::queue_node::internal_consume
void internal_consume(queue_operation *op) __TBB_override
Definition: flow_graph.h:2614
internal::key_matching_port
Definition: _flow_graph_join_impl.h:658
tbb::flow::interface11::buffer_node::internal_release
virtual void internal_release(buffer_operation *op)
Definition: flow_graph.h:2344
task_arena.h
tbb::flow::interface11::buffer_node::try_get
bool try_get(T &v) __TBB_override
Request an item from the buffer_node.
Definition: flow_graph.h:2468
tbb::internal::fgt_composite
static void fgt_composite(void *, void *, void *)
Definition: _flow_graph_trace_impl.h:301
tbb::flow::interface11::priority_queue_node::internal_release
void internal_release(prio_operation *op) __TBB_override
Definition: flow_graph.h:2846
CODEPTR
#define CODEPTR()
Definition: _flow_graph_trace_impl.h:297
tbb::flow::interface11::overwrite_node::remove_successor
bool remove_successor(successor_type &s) __TBB_override
Definition: flow_graph.h:4469
tbb::flow::interface11::composite_node< tbb::flow::tuple< InputTypes... >, tbb::flow::tuple< OutputTypes... > >::set_external_ports
void set_external_ports(T1 &&input_ports_tuple, T2 &&output_ports_tuple)
Definition: flow_graph.h:4000
tbb::flow::interface11::function_node::output_type
Output output_type
Definition: flow_graph.h:1471
tbb::flow::interface11::graph_node::prev
graph_node * prev
Definition: _flow_graph_impl.h:465
tbb::flow::interface11::internal::broadcast_cache
Definition: flow_graph.h:127
tbb::flow::interface11::overwrite_node::overwrite_node
__TBB_NOINLINE_SYM overwrite_node(const overwrite_node &src)
Copy constructor; doesn't take anything from src; default won't work.
Definition: flow_graph.h:4429
internal::multifunction_input< Input, internal::wrap_tuple_elements< tbb::flow::tuple_size< Output >::value, internal::multifunction_output, Output >::type, queueing, cache_aligned_allocator< Input > >::my_body
multifunction_body_type * my_body
Definition: _flow_graph_node_impl.h:711
tbb::task_group_context
Used to form groups of tasks.
Definition: task.h:358
tbb::internal::fgt_multiinput_multioutput_node
static void fgt_multiinput_multioutput_node(void *, string_index, void *, void *)
Definition: _flow_graph_trace_impl.h:324
tbb::flow::interface11::buffer_node::handle_operations_impl
void handle_operations_impl(buffer_operation *op_list, derived_type *derived)
Definition: flow_graph.h:2126
tbb::flow::interface11::buffer_node< T, __TBB_DEFAULT_NODE_ALLOCATOR(T) >::op_type
op_type
Definition: flow_graph.h:2077
tbb::flow::interface11::continue_node::continue_node
__TBB_NOINLINE_SYM continue_node(const continue_node &src)
Copy constructor.
Definition: flow_graph.h:1860
tbb::flow::interface11::async_node::try_put_functor::result
bool result
Definition: flow_graph.h:4232
tbb::flow::interface11::indexer_node< T0, T1, T2, T3, T4, T5, T6, T7, T8 >::indexer_node
__TBB_NOINLINE_SYM indexer_node(const indexer_node &other)
Definition: flow_graph.h:3765
tbb::internal::fgt_make_edge
static void fgt_make_edge(void *, void *)
Definition: _flow_graph_trace_impl.h:333
tbb::flow::interface11::indexer_node< T0, T1, T2, T3, T4, T5, T6, T7 >::indexer_node
indexer_node(const indexer_node &other)
Definition: flow_graph.h:3729
async_msg::finalize
virtual void finalize() const
Definition: _flow_graph_async_msg_impl.h:146
tbb::internal::enable_if
Enables one or the other code branches.
Definition: _template_helpers.h:34
tbb::flow::interface10::graph::remove_node
void remove_node(tbb::flow::interface11::graph_node *n)
Definition: flow_graph.h:830
tbb::flow::interface11::function_node::reset_node
void reset_node(reset_flags f) __TBB_override
Definition: flow_graph.h:1551
tbb::flow::interface11::async_node::try_put_functor::try_put_functor
try_put_functor(output_port_type &p, const Output &v)
Definition: flow_graph.h:4233
tbb::flow::interface11::source_node::apply_body_bypass
task * apply_body_bypass()
Applies the body. Returning SUCCESSFULLY_ENQUEUED okay; forward_task_bypass will handle it.
Definition: flow_graph.h:1430
tbb::flow::interface11::broadcast_node::remove_successor
bool remove_successor(successor_type &r) __TBB_override
Removes s as a successor.
Definition: flow_graph.h:1950
__TBB_ASSERT
#define __TBB_ASSERT(predicate, comment)
No-op version of __TBB_ASSERT.
Definition: tbb_stddef.h:165
tbb::flow::interface10::graph::prepare_task_arena
void prepare_task_arena(bool reinit=false)
Definition: _flow_graph_impl.h:265
internal::graph_policy_namespace::key_matching
field of type K being used for matching.
Definition: _flow_graph_body_impl.h:77
internal::item_buffer< T, cache_aligned_allocator< T > >::pop_front
bool pop_front(item_type &v)
Definition: _flow_graph_item_buffer_impl.h:203
tbb::flow::interface11::reset_flags
reset_flags
Definition: _flow_graph_impl.h:158
tbb::flow::interface11::internal::add_task_to_graph_reset_list
void add_task_to_graph_reset_list(tbb::flow::interface10::graph &g, tbb::task *tp)
Definition: _flow_graph_impl.h:537
tbb::flow::interface11::graph_node::my_graph
graph & my_graph
Definition: _flow_graph_impl.h:464
tbb::flow::interface11::join_node< OutputTuple, reserving >::unfolded_type
internal::unfolded_join_node< N, reserving_port, OutputTuple, reserving > unfolded_type
Definition: flow_graph.h:3286
internal::function_output
Implements methods for both executable and function nodes that puts Output to its successors.
Definition: _flow_graph_node_impl.h:854
tbb::flow::interface11::join_node< OutputTuple, key_matching< K, KHash > >::join_node
join_node(graph &g)
Definition: flow_graph.h:3361
tbb::flow::unlimited
@ unlimited
Definition: flow_graph.h:105
tbb::flow::interface11::continue_receiver::try_put_task
task * try_put_task(const input_type &) __TBB_override
Definition: flow_graph.h:671
tbb::flow::interface11::composite_node< tbb::flow::tuple< InputTypes... >, tbb::flow::tuple< OutputTypes... > >::composite_node
composite_node(graph &g)
Definition: flow_graph.h:3994
tbb::internal::no_assign
Base class for types that should not be assigned.
Definition: tbb_stddef.h:322
tbb::flow::interface11::indexer_node< T0, T1, T2, T3, T4, T5 >::indexer_node
__TBB_NOINLINE_SYM indexer_node(graph &g)
Definition: flow_graph.h:3644
tbb::flow::interface11::limiter_node::forward
void forward()
Definition: flow_graph.h:3063
tbb::flow::interface11::continue_receiver::reset_receiver
void reset_receiver(reset_flags f) __TBB_override
put receiver back in initial state
Definition: flow_graph.h:697
tbb::flow::interface11::async_node::try_put_functor::output_port_type
internal::multifunction_output< Output > output_port_type
Definition: flow_graph.h:4228
tbb::internal::fgt_multiinput_multioutput_node_desc
void fgt_multiinput_multioutput_node_desc(const NodeType *, const char *)
Definition: _flow_graph_trace_impl.h:347
tbb::flow::interface11::multifunction_node::multifunction_node
__TBB_NOINLINE_SYM multifunction_node(const multifunction_node &other)
Definition: flow_graph.h:1646
tbb::flow::interface11::sequencer_node::output_type
T output_type
Definition: flow_graph.h:2673
internal::item_buffer< T, cache_aligned_allocator< T > >::grow_my_array
void grow_my_array(size_t minimum_size)
Grows the internal array.
Definition: _flow_graph_item_buffer_impl.h:158
tbb::flow::interface11::source_node::copy_function_object
Body copy_function_object()
Definition: flow_graph.h:1345
tbb::flow::interface11::buffer_node::handler_type
internal::aggregating_functor< class_type, buffer_operation > handler_type
Definition: flow_graph.h:2117
tbb::flow::interface11::continue_node::continue_node
__TBB_NOINLINE_SYM continue_node(graph &g, int number_of_predecessors,)
Constructor for executable node with continue_msg -> Output.
Definition: flow_graph.h:1822
internal::successor_cache< T, spin_rw_mutex >::my_successors
successors_type my_successors
Definition: _flow_graph_cache_impl.h:292
tbb::flow::interface11::overwrite_node::my_buffer_is_valid
bool my_buffer_is_valid
Definition: flow_graph.h:4602
tbb::flow::interface10::graph::release_wait
void release_wait() __TBB_override
Deregisters an external entity that may have interacted with the graph.
Definition: flow_graph.h:812
internal::item_buffer< T, cache_aligned_allocator< T > >::swap_items
void swap_items(size_t i, size_t j)
Definition: _flow_graph_item_buffer_impl.h:115
tbb::internal::fgt_node_with_body
static void fgt_node_with_body(void *, string_index, void *, void *, void *)
Definition: _flow_graph_trace_impl.h:330
tbb::task_group_context::reset
void __TBB_EXPORTED_METHOD reset()
Forcefully reinitializes the context after the task tree it was associated with is completed.
tbb::flow::interface11::internal_remove_edge
void internal_remove_edge(sender< T > &p, receiver< T > &s)
Definition: flow_graph.h:3881
tbb::flow::interface11::input_node::register_successor
bool register_successor(successor_type &r) __TBB_override
Add a new successor to this node.
Definition: flow_graph.h:962
_flow_graph_join_impl.h
tbb::flow::interface11::priority_queue_node
Forwards messages in priority order.
Definition: flow_graph.h:2741
tbb::flow::interface11::buffer_node::buffer_operation::r
successor_type * r
Definition: flow_graph.h:2103
internal::reservable_item_buffer< T, cache_aligned_allocator< T > >::consume_front
void consume_front()
Definition: _flow_graph_item_buffer_impl.h:266
tbb::flow::interface11::multifunction_node::N
static const int N
Definition: flow_graph.h:1598
tbb::flow::interface11::buffer_node::con_res
@ con_res
Definition: flow_graph.h:2077
tbb::flow::interface11::source_node::try_release
bool try_release() __TBB_override
Release a reserved item.
Definition: flow_graph.h:1315
tbb::flow::interface11::indexer_node< T0, T1 >::indexer_node
__TBB_NOINLINE_SYM indexer_node(graph &g)
Definition: flow_graph.h:3511
tbb::flow::interface11::indexer_node< T0, T1, T2, T3 >::output_type
internal::tagged_msg< size_t, T0, T1, T2, T3 > output_type
Definition: flow_graph.h:3575
tbb::flow::interface11::overwrite_node::register_predecessor_task
Breaks an infinite loop between the node reservation and register_successor call.
Definition: flow_graph.h:4580
tbb::flow::interface11::graph_node::~graph_node
virtual ~graph_node()
Definition: flow_graph.h:891
tbb::flow::interface11::write_once_node::write_once_node
__TBB_NOINLINE_SYM write_once_node(const write_once_node &src)
Copy constructor: call base class copy constructor.
Definition: flow_graph.h:4637
tbb::flow::interface11::input_node::input_node
__TBB_NOINLINE_SYM input_node(const input_node &src)
Copy constructor.
Definition: flow_graph.h:941
tbb::flow::interface11::queue_node::base_type
buffer_node< T, Allocator > base_type
Definition: flow_graph.h:2569
__TBB_FLOW_GRAPH_PRIORITY_EXPR
#define __TBB_FLOW_GRAPH_PRIORITY_EXPR(expr)
Definition: _flow_graph_impl.h:38
tbb::flow::interface11::buffer_node::try_put_and_add_task
void try_put_and_add_task(task *&last_task)
Definition: flow_graph.h:2274
tbb::flow::interface11::queue_node::queue_operation
base_type::buffer_operation queue_operation
Definition: flow_graph.h:2571
tbb::flow::interface11::join_node< OutputTuple, queueing >::unfolded_type
internal::unfolded_join_node< N, queueing_port, OutputTuple, queueing > unfolded_type
Definition: flow_graph.h:3319
_flow_graph_cache_impl.h
internal::source_task_bypass
A task that calls a node's apply_body_bypass function with no input.
Definition: _flow_graph_body_impl.h:320
internal::item_buffer< T, cache_aligned_allocator< T > >::destroy_front
void destroy_front()
Definition: _flow_graph_item_buffer_impl.h:146
tbb::flow::interface11::run_and_put_task
Definition: flow_graph.h:122
tbb::flow::interface11::overwrite_node::predecessor_type
receiver< input_type >::predecessor_type predecessor_type
Definition: flow_graph.h:4406
tbb::flow::interface10::graph::reset
void reset(tbb::flow::interface11::reset_flags f=tbb::flow::interface11::rf_reset_protocol)
Definition: flow_graph.h:842
tbb::task::increment_ref_count
void increment_ref_count()
Atomically increment reference count.
Definition: task.h:771
tbb::flow::interface11::queue_node::reset_node
void reset_node(reset_flags f) __TBB_override
Definition: flow_graph.h:2653
tbb::flow::interface11::continue_receiver::continue_receiver
__TBB_DEPRECATED continue_receiver(__TBB_FLOW_GRAPH_PRIORITY_ARG1(int number_of_predecessors, node_priority_t priority))
Constructor.
Definition: flow_graph.h:608
tbb::flow::interface11::indexer_node::unfolded_type
internal::unfolded_indexer_node< InputTuple > unfolded_type
Definition: flow_graph.h:3787
tbb::flow::interface11::function_node::predecessor_type
input_impl_type::predecessor_type predecessor_type
Definition: flow_graph.h:1475
tbb::interface6::internal::aggregating_functor
Definition: _aggregator_impl.h:160
tbb::flow::interface11::buffer_node
Forwards messages in arbitrary order.
Definition: flow_graph.h:2036
__TBB_FLOW_GRAPH_PRIORITY_ARG1
#define __TBB_FLOW_GRAPH_PRIORITY_ARG1(arg1, priority)
Definition: _flow_graph_impl.h:40
tbb::flow::interface11::queue_node::output_type
T output_type
Definition: flow_graph.h:2621
internal::function_output::successors
broadcast_cache_type & successors()
Definition: _flow_graph_node_impl.h:916
tbb::flow::interface11::input_node::try_reserve_apply_body
bool try_reserve_apply_body(output_type &v)
Definition: flow_graph.h:1109
tbb::flow::interface11::overwrite_node::reset_node
void reset_node(reset_flags f) __TBB_override
Definition: flow_graph.h:4605
tbb::flow::interface11::queue_node::try_put_and_add_task
void try_put_and_add_task(task *&last_task)
Definition: flow_graph.h:2581
internal::reservable_predecessor_cache
An cache of predecessors that supports requests and reservations.
Definition: _flow_graph_cache_impl.h:197
tbb::flow::interface11::sender
Forward declaration section.
Definition: flow_graph.h:116
internal::graph_policy_namespace::queueing
Definition: _flow_graph_body_impl.h:70
tbb::flow::interface11::async_node
Implements async node.
Definition: flow_graph.h:4203
tbb::internal::fgt_async_reserve
static void fgt_async_reserve(void *, void *)
Definition: _flow_graph_trace_impl.h:341
tbb::flow::interface11::async_node::register_successor
bool register_successor(successor_type &r) __TBB_override
Add a new successor to this node.
Definition: flow_graph.h:4345
cache_aligned_allocator.h
tbb::flow::interface11::source_node::register_successor
bool register_successor(successor_type &r) __TBB_override
Add a new successor to this node.
Definition: flow_graph.h:1240
tbb::flow::interface11::sequencer_node::size_type
buffer_node< T, Allocator >::size_type size_type
Definition: flow_graph.h:2712
tbb::flow::interface11::indexer_node< T0, T1, T2, T3, T4 >::indexer_node
__TBB_NOINLINE_SYM indexer_node(const indexer_node &other)
Definition: flow_graph.h:3623
tbb::flow::interface11::graph_node
The base of all graph nodes.
Definition: _flow_graph_impl.h:454
tbb::interface6::internal::aggregated_operation
aggregated_operation base class
Definition: _aggregator_impl.h:33
tbb::flow::interface11::split_node
split_node: accepts a tuple as input, forwards each element of the tuple to its
Definition: flow_graph.h:1673
tbb::flow::interface10::graph::my_reset_task_list
task_list_type my_reset_task_list
Definition: _flow_graph_impl.h:416
tbb::flow::interface10::graph::cancelled
bool cancelled
Definition: _flow_graph_impl.h:413
tbb
The graph class.
Definition: serial/tbb/parallel_for.h:46
tbb::flow::interface11::composite_node< tbb::flow::tuple< InputTypes... >, tbb::flow::tuple< OutputTypes... > >::output_ports_type
tbb::flow::tuple< sender< OutputTypes > &... > output_ports_type
Definition: flow_graph.h:3975
tbb::flow::interface11::internal::async_body::gateway_type
Gateway gateway_type
Definition: flow_graph.h:4179
tbb::cache_aligned_allocator
Meets "allocator" requirements of ISO C++ Standard, Section 20.1.5.
Definition: cache_aligned_allocator.h:60
tbb::flow::interface11::composite_node< tbb::flow::tuple< InputTypes... >, tbb::flow::tuple<> >::reset_node
void reset_node(reset_flags) __TBB_override
Definition: flow_graph.h:4050
tbb::flow::interface11::combine_tasks
static tbb::task * combine_tasks(graph &g, tbb::task *left, tbb::task *right)
Definition: flow_graph.h:198
tbb::task::decrement_ref_count
int decrement_ref_count()
Atomically decrement reference count and returns its new value.
Definition: task.h:788
tbb::flow::interface10::graph::root_task
tbb::task * root_task()
Returns the root task of the graph.
Definition: _flow_graph_impl.h:374
internal::wrap_tuple_elements
Definition: _flow_graph_types_impl.h:49
tbb::task
Base class for user-defined tasks.
Definition: task.h:615
tbb::flow::interface11::broadcast_node::graph_reference
graph & graph_reference() const __TBB_override
Definition: flow_graph.h:2017
tbb::flow::interface11::continue_node::continue_node
__TBB_NOINLINE_SYM continue_node(graph &g,)
Constructor for executable node with continue_msg -> Output.
Definition: flow_graph.h:1785
tbb::flow::interface10::graph::my_context
tbb::task_group_context * my_context
Definition: _flow_graph_impl.h:410
internal::multifunction_body_leaf
leaf for multifunction. OutputSet can be a std::tuple or a vector.
Definition: _flow_graph_body_impl.h:202
tbb::flow::interface11::source_node::input_type
null_type input_type
Definition: flow_graph.h:1190
_flow_graph_async_msg_impl.h
__TBB_CPP11_PRESENT
#define __TBB_CPP11_PRESENT
Definition: tbb_config.h:149
tbb::flow::interface11::multifunction_node::reset_node
void reset_node(reset_flags f) __TBB_override
Definition: flow_graph.h:1667
tbb::flow::interface10::graph::iterator
tbb::flow::interface11::graph_iterator< graph, tbb::flow::interface11::graph_node > iterator
Definition: _flow_graph_impl.h:383
tbb::flow::interface11::indexer_node< T0 >::indexer_node
__TBB_NOINLINE_SYM indexer_node(graph &g)
Definition: flow_graph.h:3478
tbb::flow::interface11::buffer_node::internal_rem_succ
virtual void internal_rem_succ(buffer_operation *op)
Remove successor.
Definition: flow_graph.h:2211
tbb::flow::interface11::broadcast_node::reset_node
void reset_node(reset_flags f) __TBB_override
Definition: flow_graph.h:2023
tbb::flow::interface11::composite_node< tbb::flow::tuple< InputTypes... >, tbb::flow::tuple< OutputTypes... > >::reset_node
void reset_node(reset_flags) __TBB_override
Definition: flow_graph.h:3985
internal::reservable_item_buffer
item_buffer with reservable front-end. NOTE: if reserving, do not
Definition: _flow_graph_item_buffer_impl.h:247
tbb::flow::interface11::queue_node::queue_node
__TBB_NOINLINE_SYM queue_node(graph &g)
Constructor.
Definition: flow_graph.h:2626
tbb::flow::interface11::buffer_node::internals_allocator
cache_aligned_allocator< T > internals_allocator
Definition: flow_graph.h:2047
tbb::task::allocate_root
static internal::allocate_root_proxy allocate_root()
Returns proxy for overloaded new that allocates a root task.
Definition: task.h:663
tbb::flow::interface11::continue_receiver::my_current_count
int my_current_count
Definition: flow_graph.h:690
tbb::flow::interface11::priority_queue_node::class_type
priority_queue_node class_type
Definition: flow_graph.h:2753
tbb::flow::interface11::internal::async_body_base::async_body_base
async_body_base(gateway_type *gateway)
Definition: flow_graph.h:4166
tbb::flow::interface11::source_node::try_reserve
bool try_reserve(output_type &v) __TBB_override
Reserves an item.
Definition: flow_graph.h:1298
tbb::flow::interface11::source_node::my_body
internal::source_body< output_type > * my_body
Definition: flow_graph.h:1382
spin_rw_mutex.h
tbb::flow::interface11::function_node::__TBB_STATIC_ASSERT
__TBB_STATIC_ASSERT((tbb::internal::is_same_type< Allocator, null_type >::value), "Allocator template parameter for flow graph nodes is deprecated and will be removed. " "Specify TBB_DEPRECATED_FLOW_NODE_ALLOCATOR to temporary enable the deprecated interface.")
internal::item_buffer< T, cache_aligned_allocator< T > >::get_my_item
const item_type & get_my_item(size_t i) const
Definition: _flow_graph_item_buffer_impl.h:72
tbb::flow::interface11::queue_node::internal_reserve
void internal_reserve(queue_operation *op) __TBB_override
Definition: flow_graph.h:2605
__TBB_DEPRECATED_LIMITER_ARG4
#define __TBB_DEPRECATED_LIMITER_ARG4(arg1, arg2, arg3, arg4)
Definition: _flow_graph_impl.h:54
internal::item_buffer< T, cache_aligned_allocator< T > >::my_array_size
size_type my_array_size
Definition: _flow_graph_item_buffer_impl.h:49
internal::item_buffer< T, cache_aligned_allocator< T > >::capacity
size_type capacity()
Definition: _flow_graph_item_buffer_impl.h:152
tbb::flow::interface11::source_node::my_has_cached_item
bool my_has_cached_item
Definition: flow_graph.h:1386
tbb::flow::interface11::receiver::graph_reference
virtual graph & graph_reference() const =0
tbb::flow::interface11::input_node::my_successors
internal::broadcast_cache< output_type > my_successors
Definition: flow_graph.h:1103
tbb::flow::interface11::buffer_node::buffer_operation::type
char type
Definition: flow_graph.h:2089
tbb::internal::allocator_type
Class for determining type of std::allocator<T>::value_type.
Definition: tbb_stddef.h:471
tbb::flow::interface11::async_node::output_ports_type
base_type::output_ports_type output_ports_type
Definition: flow_graph.h:4224
tbb::flow::interface10::graph::my_nodes_last
tbb::flow::interface11::graph_node * my_nodes_last
Definition: _flow_graph_impl.h:418
tbb::flow::interface11::buffer_node::try_put_task
task * try_put_task(const T &t) __TBB_override
receive an item, return a task *if possible
Definition: flow_graph.h:2511
tbb::flow::interface11::null_type
A generic null type.
Definition: flow_graph.h:110
tbb::flow::interface11::async_node::output_type
Output output_type
Definition: flow_graph.h:4218
begin
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
Definition: ittnotify_static.h:182
tbb::flow::interface11::buffer_node::internal_reserve
virtual void internal_reserve(buffer_operation *op)
Definition: flow_graph.h:2330
tbb::flow::interface11::join_node< OutputTuple, key_matching< K, KHash > >::join_node
__TBB_NOINLINE_SYM join_node(graph &g, __TBB_B0 b0, __TBB_B1 b1)
Definition: flow_graph.h:3374
internal::input_port
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
Definition: _flow_graph_join_impl.h:1996
tbb::flow::interface11::sender::try_get
virtual bool try_get(T &)
Request an item from the sender.
Definition: flow_graph.h:512
tbb::flow::interface11::priority_queue_node::prio
const T & prio()
Definition: flow_graph.h:2921
tbb::flow::interface11::buffer_node::try_reserve
bool try_reserve(T &v) __TBB_override
Reserves an item.
Definition: flow_graph.h:2479
tbb::flow::interface11::function_node
Implements a function node that supports Input -> Output.
Definition: flow_graph.h:1448
tbb::flow::interface11::buffer_node::rel_res
@ rel_res
Definition: flow_graph.h:2077
tbb::flow::interface11::join_node< OutputTuple, reserving >::join_node
__TBB_NOINLINE_SYM join_node(graph &g)
Definition: flow_graph.h:3290
tbb::flow::interface11::indexer_node< T0, T1 >::indexer_node
__TBB_NOINLINE_SYM indexer_node(const indexer_node &other)
Definition: flow_graph.h:3524
tbb::flow::interface11::continue_receiver::is_continue_receiver
bool is_continue_receiver() __TBB_override
Definition: flow_graph.h:712
tbb::flow::interface11::join_node< OutputTuple, key_matching< K, KHash > >::join_node
__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)
Definition: flow_graph.h:3397
tbb::flow::interface11::sequencer_node
Forwards messages in sequence order.
Definition: flow_graph.h:2660
internal::decrementer
Definition: _flow_graph_body_impl.h:344
tbb::flow::interface11::source_node::reset_node
void reset_node(reset_flags f) __TBB_override
resets the source_node to its initial state
Definition: flow_graph.h:1362
tbb::__TBB_DEPRECATED_MSG
class __TBB_DEPRECATED_MSG("tbb::tbb_hash is deprecated, use std::hash") tbb_hash
Definition: _tbb_hash_compare_impl.h:86
tbb::flow::interface11::async_node::receiver_gateway_impl::reserve_wait
void reserve_wait() __TBB_override
Inform a graph that messages may come from outside, to prevent premature graph completion.
Definition: flow_graph.h:4242
tbb::flow::interface11::async_node::predecessor_type
receiver_type::predecessor_type predecessor_type
Definition: flow_graph.h:4220
tbb::flow::interface10::graph::wait_for_all
void wait_for_all()
Wait until graph is idle and decrement_wait_count calls equals increment_wait_count calls.
Definition: _flow_graph_impl.h:338
_flow_graph_nodes_deduction.h
tbb::flow::interface11::receiver::proxy_dependency_receiver
friend class proxy_dependency_receiver
Definition: flow_graph.h:590
internal::clear_element
Definition: _flow_graph_node_impl.h:525
tbb::flow::interface11::source_node::source_node
__TBB_NOINLINE_SYM source_node(const source_node &src)
Copy constructor.
Definition: flow_graph.h:1219
tbb::flow::interface11::overwrite_node
Definition: flow_graph.h:4402
tbb::flow::interface10::graph
The graph class.
Definition: _flow_graph_impl.h:211
tbb::flow::interface11::write_once_node::predecessor_type
receiver< input_type >::predecessor_type predecessor_type
Definition: flow_graph.h:4619
tbb::flow::interface11::continue_receiver
Base class for receivers of completion messages.
Definition: flow_graph.h:598
tbb::flow::interface11::indexer_node< T0, T1, T2 >::indexer_node
__TBB_NOINLINE_SYM indexer_node(const indexer_node &other)
Definition: flow_graph.h:3557
tbb::flow::interface11::limiter_node::register_predecessor
bool register_predecessor(predecessor_type &src) __TBB_override
Adds src to the list of cached predecessors.
Definition: flow_graph.h:3202
__TBB_FLOW_GRAPH_PRIORITY_ARG0
#define __TBB_FLOW_GRAPH_PRIORITY_ARG0(priority)
Definition: _flow_graph_impl.h:39
tbb::flow::interface11::indexer_node< T0, T1 >::InputTuple
tuple< T0, T1 > InputTuple
Definition: flow_graph.h:3508
internal::continue_input< Output, internal::Policy< void > >::my_body
function_body_type * my_body
Definition: _flow_graph_node_impl.h:809
async_msg
Definition: _flow_graph_async_msg_impl.h:121
tbb::flow::interface11::input_node::try_release
bool try_release() __TBB_override
Release a reserved item.
Definition: flow_graph.h:1038
internal::unfolded_indexer_node
Definition: _flow_graph_indexer_impl.h:466
internal::op_stat
op_stat
Definition: _flow_graph_types_impl.h:719
tbb::flow::interface11::sender::output_type
__TBB_DEPRECATED typedef T output_type
The output type of this sender.
Definition: flow_graph.h:496
tbb::flow::interface11::broadcast_node::output_type
T output_type
Definition: flow_graph.h:1900
tbb::flow::internal::SUCCESSFULLY_ENQUEUED
static tbb::task *const SUCCESSFULLY_ENQUEUED
Definition: _flow_graph_impl.h:61
tbb::flow::interface11::sender::register_successor
virtual __TBB_DEPRECATED bool register_successor(successor_type &r)=0
Add a new successor to this node.
tbb::flow::interface11::join_node< OutputTuple, key_matching< K, KHash > >::join_node
__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)
Definition: flow_graph.h:3433
tbb::flow::interface11::graph_iterator
Definition: _flow_graph_impl.h:91
tbb::flow::interface11::write_once_node::output_type
T output_type
Definition: flow_graph.h:4617
tbb::spin_mutex::scoped_lock
Represents acquisition of a mutex.
Definition: spin_mutex.h:53
tbb::flow::interface11::function_node::function_node
__TBB_NOINLINE_SYM function_node(graph &g, size_t concurrency, __TBB_FLOW_GRAPH_PRIORITY_ARG1(Body body, node_priority_t priority=tbb::flow::internal::no_priority))
Constructor.
Definition: flow_graph.h:1488
tbb::flow::interface11::input_node::reset_node
void reset_node(reset_flags f) __TBB_override
resets the source_node to its initial state
Definition: flow_graph.h:1085
tbb::flow::interface11::limiter_node::check_conditions
bool check_conditions()
Definition: flow_graph.h:3005
tbb::flow::interface11::overwrite_node::~overwrite_node
~overwrite_node()
Definition: flow_graph.h:4437
tbb::flow::interface11::sequencer_node::__TBB_STATIC_ASSERT
__TBB_STATIC_ASSERT((tbb::internal::is_same_type< Allocator, null_type >::value), "Allocator template parameter for flow graph nodes is deprecated and will be removed. " "Specify TBB_DEPRECATED_FLOW_NODE_ALLOCATOR to temporary enable the deprecated interface.")
tbb::flow::interface11::limiter_node::reset_node
void reset_node(reset_flags f) __TBB_override
Definition: flow_graph.h:3258
tbb::flow::interface11::overwrite_node::try_reserve
bool try_reserve(T &v) __TBB_override
Reserves an item.
Definition: flow_graph.h:4537
tbb::flow::interface11::function_node::input_queue_type
internal::function_input_queue< input_type, internals_allocator > input_queue_type
Definition: flow_graph.h:1473
tbb::flow::interface11::composite_node< tbb::flow::tuple< InputTypes... >, tbb::flow::tuple< OutputTypes... > >::output_ports
output_ports_type & output_ports()
Definition: flow_graph.h:4027
tbb::flow::interface11::limiter_node::my_successors
internal::broadcast_cache< T > my_successors
Definition: flow_graph.h:2997
tbb::flow::interface11::multifunction_node::input_type
Input input_type
Definition: flow_graph.h:1600
internal::item_buffer< T, cache_aligned_allocator< T > >::my_tail
size_type my_tail
Definition: _flow_graph_item_buffer_impl.h:52
tbb::flow::interface11::overwrite_node::graph_reference
graph & graph_reference() const __TBB_override
Definition: flow_graph.h:4575
tbb::flow::interface11::buffer_node::internal_reg_succ
virtual void internal_reg_succ(buffer_operation *op)
Register successor.
Definition: flow_graph.h:2205
tbb::flow::interface11::indexer_node::output_type
internal::tagged_msg< size_t, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9 > output_type
Definition: flow_graph.h:3786
tbb::flow::interface11::buffer_node::input_type
T input_type
Definition: flow_graph.h:2050
tbb::flow::interface11::sender::try_reserve
virtual bool try_reserve(T &)
Reserves an item in the sender.
Definition: flow_graph.h:515
internal::function_output< continue_msg >::graph_reference
graph & graph_reference() const
Definition: _flow_graph_node_impl.h:918
tbb::flow::interface11::buffer_node::buffer_node
__TBB_NOINLINE_SYM buffer_node(graph &g)
Constructor.
Definition: flow_graph.h:2351
tbb::flow::interface11::queue_node::queue_node
__TBB_NOINLINE_SYM queue_node(const queue_node &src)
Copy constructor.
Definition: flow_graph.h:2640
_flow_graph_node_impl.h
tbb_profiling.h
tbb::internal::fgt_begin_body
static void fgt_begin_body(void *)
Definition: _flow_graph_trace_impl.h:336
_template_helpers.h
tbb::flow::interface11::internal_make_edge
void internal_make_edge(sender< T > &p, receiver< T > &s)
Definition: flow_graph.h:3818
tbb::flow::interface11::indexer_node< T0, T1, T2, T3, T4, T5, T6 >::output_type
internal::tagged_msg< size_t, T0, T1, T2, T3, T4, T5, T6 > output_type
Definition: flow_graph.h:3678
tbb::flow::interface11::indexer_node< T0, T1, T2, T3, T4, T5, T6, T7 >::InputTuple
tuple< T0, T1, T2, T3, T4, T5, T6, T7 > InputTuple
Definition: flow_graph.h:3713
tbb::flow::interface11::receiver::~receiver
virtual ~receiver()
Destructor.
Definition: flow_graph.h:546
tbb::flow::interface11::buffer_node::buffer_operation::buffer_operation
buffer_operation(const T &e, op_type t)
Definition: flow_graph.h:2105
tbb::flow::interface11::function_node::successor_type
fOutput_type::successor_type successor_type
Definition: flow_graph.h:1476
tbb::flow::interface11::composite_node< tbb::flow::tuple<>, tbb::flow::tuple< OutputTypes... > >::output_ports
output_ports_type & output_ports()
Definition: flow_graph.h:4144
tbb::flow::interface11::input_node::output_type
Output output_type
The type of the output message, which is complete.
Definition: flow_graph.h:906
tbb::flow::interface11::indexer_node< T0, T1, T2, T3, T4, T5 >::InputTuple
tuple< T0, T1, T2, T3, T4, T5 > InputTuple
Definition: flow_graph.h:3641
tbb::flow::interface11::buffer_node::remove_successor
bool remove_successor(successor_type &r) __TBB_override
Removes a successor.
Definition: flow_graph.h:2453
tbb::flow::interface11::split_node::split_node
__TBB_NOINLINE_SYM split_node(const split_node &other)
Definition: flow_graph.h:1715
tbb::flow::interface11::source_node::my_mutex
spin_mutex my_mutex
Definition: flow_graph.h:1379
tbb::flow::interface11::buffer_node::forwarder_busy
bool forwarder_busy
Definition: flow_graph.h:2116
_flow_graph_impl.h
tbb::flow::interface11::indexer_node< T0 >::unfolded_type
internal::unfolded_indexer_node< InputTuple > unfolded_type
Definition: flow_graph.h:3477
internal::item_buffer< T, cache_aligned_allocator< T > >::destroy_back
void destroy_back()
Definition: _flow_graph_item_buffer_impl.h:147
internal::multifunction_input< Input, internal::wrap_tuple_elements< tbb::flow::tuple_size< Output >::value, internal::multifunction_output, Output >::type, queueing, cache_aligned_allocator< Input > >::output_ports
output_ports_type & output_ports()
Definition: _flow_graph_node_impl.h:691
tbb::flow::interface10::graph::nodelist_mutex
tbb::spin_mutex nodelist_mutex
Definition: _flow_graph_impl.h:420
tbb::flow::interface11::composite_node< tbb::flow::tuple< InputTypes... >, tbb::flow::tuple<> >::input_ports_type
tbb::flow::tuple< receiver< InputTypes > &... > input_ports_type
Definition: flow_graph.h:4043
tbb::flow::interface11::join_node< OutputTuple, reserving >::output_type
OutputTuple output_type
Definition: flow_graph.h:3288
_tbb_hash_compare_impl.h
tbb::flow::interface11::indexer_node< T0, T1, T2 >::output_type
internal::tagged_msg< size_t, T0, T1, T2 > output_type
Definition: flow_graph.h:3542
tbb::flow::interface11::overwrite_node::my_buffer
input_type my_buffer
Definition: flow_graph.h:4601
tbb::flow::interface11::internal::predecessor_cache
Definition: flow_graph.h:129
tbb::flow::interface11::broadcast_node::my_successors
internal::broadcast_cache< input_type > my_successors
Definition: flow_graph.h:1908
tbb::flow::interface11::input_node::try_consume
bool try_consume() __TBB_override
Consumes a reserved item.
Definition: flow_graph.h:1048
tbb::task::set_ref_count
void set_ref_count(int count)
Set reference count.
Definition: task.h:761
internal::clear_element::clear_this
static void clear_this(P &p)
Definition: _flow_graph_node_impl.h:526
tbb::flow::interface11::continue_receiver::input_type
__TBB_DEPRECATED typedef continue_msg input_type
The input type.
Definition: flow_graph.h:602
tbb::flow::interface11::priority_queue_node::internal_push
bool internal_push(prio_operation *op) __TBB_override
Definition: flow_graph.h:2808
tbb::flow::interface11::source_node::init_my_active
bool init_my_active
Definition: flow_graph.h:1381
tbb::flow::interface11::composite_node< tbb::flow::tuple< InputTypes... >, tbb::flow::tuple<> >::composite_node
composite_node(graph &g)
Definition: flow_graph.h:4059
internal::successor_cache< T, spin_rw_mutex >::my_mutex
mutex_type my_mutex
Definition: _flow_graph_cache_impl.h:277
internal::round_robin_cache
A cache of successors that are put in a round-robin fashion.
Definition: _flow_graph_cache_impl.h:546
tbb::flow::interface11::split_node::output_ports
output_ports_type & output_ports()
Definition: flow_graph.h:1729
internal::source_body_leaf
The leaf for source_body.
Definition: _flow_graph_body_impl.h:105
tbb::flow::interface11::buffer_node::internal_push
virtual bool internal_push(buffer_operation *op)
Definition: flow_graph.h:2315
tbb::flow::interface11::indexer_node< T0, T1, T2, T3, T4, T5, T6, T7, T8 >::output_type
internal::tagged_msg< size_t, T0, T1, T2, T3, T4, T5, T6, T7, T8 > output_type
Definition: flow_graph.h:3750
tbb::flow::interface11::continue_node::input_type
continue_msg input_type
Definition: flow_graph.h:1776
tbb::flow::interface11::buffer_node::buffer_node
__TBB_NOINLINE_SYM buffer_node(const buffer_node &src)
Copy constructor.
Definition: flow_graph.h:2369
tbb::flow::interface11::overwrite_node::overwrite_node
__TBB_NOINLINE_SYM overwrite_node(graph &g)
Definition: flow_graph.h:4415
tbb::spin_mutex::scoped_lock
friend class scoped_lock
Definition: spin_mutex.h:179
tbb::flow::interface11::multifunction_node::multifunction_node
__TBB_NOINLINE_SYM multifunction_node(graph &g, size_t concurrency,)
Definition: flow_graph.h:1610
tbb::flow::interface11::input_node::my_mutex
spin_mutex my_mutex
Definition: flow_graph.h:1099
tbb::flow::interface11::limiter_node::remove_successor
bool remove_successor(successor_type &r) __TBB_override
Removes a successor from this node.
Definition: flow_graph.h:3155
tbb::flow::interface11::input_node::my_init_body
internal::source_body< output_type > * my_init_body
Definition: flow_graph.h:1102
internal::tagged_msg
Definition: _flow_graph_types_impl.h:612
internal::function_input_base< Input, Policy, A, function_input< Input, Output, Policy, A > >::predecessor_type
receiver< input_type >::predecessor_type predecessor_type
Definition: _flow_graph_node_impl.h:74
tbb::flow::interface11::async_node::receiver_gateway_impl::my_node
async_node * my_node
Definition: flow_graph.h:4258
tbb::flow::interface11::priority_queue_node::internal_consume
void internal_consume(prio_operation *op) __TBB_override
Definition: flow_graph.h:2840
tbb::flow::interface11::limiter_node::my_tries
size_t my_tries
Definition: flow_graph.h:2994
tbb::flow::interface11::copy_body
Body copy_body(Node &n)
Returns a copy of the body from a function or continue node.
Definition: flow_graph.h:3961
tbb::flow::interface11::overwrite_node::reset_receiver
void reset_receiver(reset_flags) __TBB_override
put receiver back in initial state
Definition: flow_graph.h:4603
tbb::flow::interface11::internal::async_body_base::my_gateway
gateway_type * my_gateway
Definition: flow_graph.h:4172
tbb::flow::interface11::priority_queue_node::predecessor_type
receiver< input_type >::predecessor_type predecessor_type
Definition: flow_graph.h:2754
internal::item_buffer< T, cache_aligned_allocator< T > >::destroy_item
void destroy_item(size_type i)
Definition: _flow_graph_item_buffer_impl.h:122
tbb::flow::interface11::indexer_node< T0, T1, T2, T3 >::indexer_node
__TBB_NOINLINE_SYM indexer_node(graph &g)
Definition: flow_graph.h:3577
task.h
tbb::flow::interface11::receiver::input_type
__TBB_DEPRECATED typedef T input_type
The input type of this receiver.
Definition: flow_graph.h:540
tbb::flow::interface11::priority_queue_node::__TBB_STATIC_ASSERT
__TBB_STATIC_ASSERT((tbb::internal::is_same_type< Allocator, null_type >::value), "Allocator template parameter for flow graph nodes is deprecated and will removed in the future. " "To temporary enable the deprecated interface specify TBB_ENABLE_DEPRECATED_NODE_ALLOCATOR.")
tbb::flow::interface11::input_node::~input_node
~input_node()
The destructor.
Definition: flow_graph.h:953
tbb::flow::interface11::source_node::~source_node
~source_node()
The destructor.
Definition: flow_graph.h:1231
tbb::flow::interface11::limiter_node::limiter_node
limiter_node(const limiter_node &src)
Copy constructor.
Definition: flow_graph.h:3121
tbb::flow::interface11::buffer_node::try_release
bool try_release() __TBB_override
Release a reserved item.
Definition: flow_graph.h:2489
internal::reservable_predecessor_cache::try_reserve
bool try_reserve(output_type &v)
Definition: _flow_graph_cache_impl.h:212
tbb::flow::interface11::broadcast_node::predecessor_type
receiver< input_type >::predecessor_type predecessor_type
Definition: flow_graph.h:1901
tbb::flow::interface11::queue_node::size_type
base_type::size_type size_type
Definition: flow_graph.h:2570
tbb::flow::interface11::buffer_node::reg_succ
@ reg_succ
Definition: flow_graph.h:2077
internal::emit_element::emit_this
static task * emit_this(graph &g, const T &t, P &p)
Definition: _flow_graph_node_impl.h:733
tbb::flow::interface11::write_once_node::successor_type
sender< output_type >::successor_type successor_type
Definition: flow_graph.h:4620
tbb::flow::interface11::continue_node::input_impl_type
internal::continue_input< Output, Policy > input_impl_type
Definition: flow_graph.h:1778
tbb::flow::interface11::buffer_node::forward_task
virtual task * forward_task()
This is executed by an enqueued task, the "forwarder".
Definition: flow_graph.h:2188
tbb::flow::interface11::indexer_node< T0, T1 >::unfolded_type
internal::unfolded_indexer_node< InputTuple > unfolded_type
Definition: flow_graph.h:3510
internal::item_buffer< T, cache_aligned_allocator< T > >::pop_back
bool pop_back(item_type &v)
Definition: _flow_graph_item_buffer_impl.h:194
tbb::flow::interface11::overwrite_node::try_put_task_impl
task * try_put_task_impl(const input_type &v)
Definition: flow_graph.h:4567
tbb::flow::interface11::continue_receiver::my_initial_predecessor_count
int my_initial_predecessor_count
Definition: flow_graph.h:691
internal::multifunction_input::reset
void reset(reset_flags f)
Definition: _flow_graph_node_impl.h:700
tbb::flow::interface11::continue_node::predecessor_type
input_impl_type::predecessor_type predecessor_type
Definition: flow_graph.h:1780
tbb::flow::interface11::graph_node::reset_node
virtual void reset_node(reset_flags f=rf_reset_protocol)=0
tbb::flow::key_from_message
K key_from_message(const T &t)
Definition: flow_graph.h:720
tbb::flow::interface11::internal::async_body::async_body
async_body(const Body &body, gateway_type *gateway)
Definition: flow_graph.h:4181
tbb::internal::fgt_node_desc
static void fgt_node_desc(const NodeType *, const char *)
Definition: _flow_graph_trace_impl.h:309
tbb::flow::interface11::broadcast_node
Forwards messages of type T to all successors.
Definition: flow_graph.h:1897
tbb::flow::interface11::async_node::async_body_base_type
internal::async_body_base< gateway_type > async_body_base_type
Definition: flow_graph.h:4223
tbb::flow::interface11::indexer_node< T0, T1, T2, T3, T4, T5, T6 >::indexer_node
__TBB_NOINLINE_SYM indexer_node(const indexer_node &other)
Definition: flow_graph.h:3693
_flow_graph_streaming_node.h
tbb::flow::interface11::async_node::receiver_type
receiver< input_type > receiver_type
Definition: flow_graph.h:4219
tbb::flow::interface11::indexer_node< T0, T1 >::output_type
internal::tagged_msg< size_t, T0, T1 > output_type
Definition: flow_graph.h:3509
tbb::flow::interface11::internal::async_body
Definition: flow_graph.h:4176
tbb::flow::interface11::join_node< OutputTuple, key_matching< K, KHash > >::join_node
__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)
Definition: flow_graph.h:3406
tbb::flow::interface11::indexer_node::N
static const int N
Definition: flow_graph.h:3783
tbb::flow::interface11::source_node::try_consume
bool try_consume() __TBB_override
Consumes a reserved item.
Definition: flow_graph.h:1325
__TBB_DEFAULT_NODE_ALLOCATOR
#define __TBB_DEFAULT_NODE_ALLOCATOR(T)
Definition: flow_graph.h:70
__TBB_STATIC_ASSERT
#define __TBB_STATIC_ASSERT(condition, msg)
Definition: tbb_stddef.h:553
tbb::flow::interface11::graph_iterator::pointer
GraphNodeType * pointer
Definition: _flow_graph_impl.h:97
tbb::flow::interface11::overwrite_node::input_type
T input_type
Definition: flow_graph.h:4404
tbb::flow::interface11::write_once_node::base_type
overwrite_node< T > base_type
Definition: flow_graph.h:4618
internal::graph_policy_namespace::queueing_lightweight
interface11::internal::Policy< queueing, lightweight > queueing_lightweight
Definition: _flow_graph_body_impl.h:87
tbb::flow::internal::no_priority
static const node_priority_t no_priority
Definition: _flow_graph_impl.h:64
tbb_exception.h
tbb::flow::interface11::composite_node< tbb::flow::tuple<>, tbb::flow::tuple< OutputTypes... > >::set_external_ports
void set_external_ports(T &&output_ports_tuple)
Definition: flow_graph.h:4124
tbb::flow::interface11::receiver::remove_predecessor
virtual __TBB_DEPRECATED bool remove_predecessor(predecessor_type &)
Remove a predecessor from the node.
Definition: flow_graph.h:570
tbb::flow::interface11::source_node::output_type
Output output_type
The type of the output message, which is complete.
Definition: flow_graph.h:1184
tbb::flow::interface11::internal::async_body_base::set_gateway
void set_gateway(gateway_type *gateway)
Definition: flow_graph.h:4167
tbb::flow::interface11::overwrite_node::successor_type
sender< output_type >::successor_type successor_type
Definition: flow_graph.h:4407
tbb::flow::interface11::indexer_node< T0, T1, T2, T3, T4, T5 >::unfolded_type
internal::unfolded_indexer_node< InputTuple > unfolded_type
Definition: flow_graph.h:3643
tbb::internal::fgt_reserve_wait
static void fgt_reserve_wait(void *)
Definition: _flow_graph_trace_impl.h:343
tbb::flow::interface11::buffer_node::output_type
T output_type
Definition: flow_graph.h:2051
tbb::flow::interface11::queue_node::input_type
T input_type
Definition: flow_graph.h:2620
tbb::flow::interface11::composite_node< tbb::flow::tuple< InputTypes... >, tbb::flow::tuple<> >::set_external_ports
void set_external_ports(T &&input_ports_tuple)
Definition: flow_graph.h:4065
tbb::flow::interface11::composite_node< tbb::flow::tuple<>, tbb::flow::tuple< OutputTypes... > >::composite_node
__TBB_NOINLINE_SYM composite_node(graph &g)
Definition: flow_graph.h:4118
tbb::flow::interface11::join_node< OutputTuple, key_matching< K, KHash > >::join_node
__TBB_NOINLINE_SYM join_node(graph &g, __TBB_B0 b0, __TBB_B1 b1, __TBB_B2 b2)
Definition: flow_graph.h:3379
tbb::flow::interface11::continue_node::reset_node
void reset_node(reset_flags f) __TBB_override
Definition: flow_graph.h:1888
tbb::flow::interface11::priority_queue_node::input_type
T input_type
Definition: flow_graph.h:2750
tbb::internal::__TBB_store_with_release
void __TBB_store_with_release(volatile T &location, V value)
Definition: tbb_machine.h:713
tbb::flow::interface11::write_once_node::write_once_node
__TBB_NOINLINE_SYM write_once_node(graph &g)
Constructor.
Definition: flow_graph.h:4623
tbb::flow::interface11::input_node::spawn_put
void spawn_put()
Spawns a task that applies the body.
Definition: flow_graph.h:1137
tbb::flow::interface11::overwrite_node::try_get
bool try_get(input_type &v) __TBB_override
Request an item from the sender.
Definition: flow_graph.h:4527
tbb::flow::interface11::remove_edge
void remove_edge(sender< T > &p, receiver< T > &s)
Removes an edge between a single predecessor and a single successor.
Definition: flow_graph.h:3894
tbb::flow::interface11::overwrite_node::my_successors
internal::broadcast_cache< input_type, null_rw_mutex > my_successors
Definition: flow_graph.h:4597
tbb::flow::interface11::join_node< OutputTuple, key_matching< K, KHash > >::join_node
__TBB_NOINLINE_SYM join_node(graph &g, __TBB_B0 b0, __TBB_B1 b1, __TBB_B2 b2, __TBB_B3 b3)
Definition: flow_graph.h:3384
tbb::flow::interface11::queue_node::internal_pop
void internal_pop(queue_operation *op) __TBB_override
Definition: flow_graph.h:2596
tbb::flow::interface11::async_node::try_put_impl
bool try_put_impl(const Output &i)
Implements gateway_type::try_put for an external activity to submit a message to FG.
Definition: flow_graph.h:4265
tbb::flow::interface11::composite_node< tbb::flow::tuple<>, tbb::flow::tuple< OutputTypes... > >::reset_node
void reset_node(reset_flags) __TBB_override
Definition: flow_graph.h:4109
tbb::flow::interface11::queue_node::predecessor_type
receiver< input_type >::predecessor_type predecessor_type
Definition: flow_graph.h:2622
tbb::flow::interface11::priority_queue_node::compare
Compare compare
Definition: flow_graph.h:2876
tbb::flow::interface11::input_node::my_active
bool my_active
Definition: flow_graph.h:1100
tbb::flow::interface11::priority_queue_node::priority_queue_node
__TBB_NOINLINE_SYM priority_queue_node(const priority_queue_node &src)
Copy constructor.
Definition: flow_graph.h:2774
tbb::flow::concurrency
concurrency
An enumeration the provides the two most common concurrency levels: unlimited and serial.
Definition: flow_graph.h:105
tbb::flow::interface11::graph_node::next
graph_node * next
Definition: _flow_graph_impl.h:465
tbb::flow::interface11::limiter_node::limiter_node
limiter_node(graph &g, __TBB_DEPRECATED_LIMITER_ARG2(size_t threshold, int num_decrement_predecessors=0))
Constructor.
Definition: flow_graph.h:3102
tbb::flow::interface11::overwrite_node::is_valid
bool is_valid()
Definition: flow_graph.h:4547
tbb::flow::interface11::sequencer_node::sequencer_operation
buffer_node< T, Allocator >::buffer_operation sequencer_operation
Definition: flow_graph.h:2713
tbb::flow::interface11::receiver::is_continue_receiver
virtual bool is_continue_receiver()
Definition: flow_graph.h:587
tbb::flow::interface11::split_node::input_type
TupleType input_type
Definition: flow_graph.h:1677
tbb::flow::interface11::internal::async_body::operator()
void operator()(const Input &v, Ports &)
Definition: flow_graph.h:4184
tbb::internal::fgt_graph_desc
static void fgt_graph_desc(void *, const char *)
Definition: _flow_graph_trace_impl.h:311
tbb::flow::interface11::limiter_node::remove_predecessor
bool remove_predecessor(predecessor_type &src) __TBB_override
Removes src from the list of cached predecessors.
Definition: flow_graph.h:3214
tbb::flow::interface11::rf_reset_protocol
@ rf_reset_protocol
Definition: _flow_graph_impl.h:159
tbb::flow::interface11::split_node::output_ports_type
internal::wrap_tuple_elements< N, internal::multifunction_output, TupleType >::type output_ports_type
Definition: flow_graph.h:1698
tbb::flow::interface11::function_node::successors
internal::broadcast_cache< output_type > & successors() __TBB_override
Definition: flow_graph.h:1549
internal::add_nodes_impl
void add_nodes_impl(CompositeType *, bool)
Definition: _flow_graph_node_impl.h:958
tbb::flow::interface11::input_node::remove_successor
bool remove_successor(successor_type &r) __TBB_override
Removes a successor from this node.
Definition: flow_graph.h:971
tbb::flow::interface11::write_once_node::try_put_task
task * try_put_task(const T &v) __TBB_override
Definition: flow_graph.h:4653
tbb::flow::interface11::input_node::apply_body_bypass
task * apply_body_bypass()
Applies the body. Returning SUCCESSFULLY_ENQUEUED okay; forward_task_bypass will handle it.
Definition: flow_graph.h:1145
tbb::flow::interface11::buffer_node::internal_forward_task_impl
void internal_forward_task_impl(buffer_operation *op, derived_type *derived)
Definition: flow_graph.h:2291
tbb::flow::interface11::priority_queue_node::handle_operations
void handle_operations(prio_operation *op_list) __TBB_override
Definition: flow_graph.h:2804
lock
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
Definition: ittnotify_static.h:121
atomic.h
internal::item_buffer< T, cache_aligned_allocator< T > >::my_head
size_type my_head
Definition: _flow_graph_item_buffer_impl.h:51
tbb::flow::interface11::source_node
An executable node that acts as a source, i.e. it has no predecessors.
Definition: flow_graph.h:1179
tbb::flow::interface11::limiter_node::register_successor
bool register_successor(successor_type &r) __TBB_override
Replace the current successor with this new successor.
Definition: flow_graph.h:3138
internal::reservable_item_buffer< T, cache_aligned_allocator< T > >::reservable_item_buffer
reservable_item_buffer()
Definition: _flow_graph_item_buffer_impl.h:253
tbb::internal::fgt_release_wait
static void fgt_release_wait(void *)
Definition: _flow_graph_trace_impl.h:344
tbb::flow::interface11::join_node< OutputTuple, key_matching< K, KHash > >::output_type
OutputTuple output_type
Definition: flow_graph.h:3357
tbb::flow::interface11::source_node::successor_type
sender< output_type >::successor_type successor_type
The type of successors of this node.
Definition: flow_graph.h:1187
tbb::flow::interface11::buffer_node::put_item
@ put_item
Definition: flow_graph.h:2077
tbb::flow::interface11::composite_node
Definition: flow_graph.h:3968
tbb::flow::interface11::broadcast_node::reset_receiver
void reset_receiver(reset_flags) __TBB_override
put receiver back in initial state
Definition: flow_graph.h:2021
tbb::flow::interface11::async_node::copy_function_object
Body copy_function_object()
Definition: flow_graph.h:4355
tbb::flow::interface11::multifunction_node::input_queue_type
internal::function_input_queue< input_type, internals_allocator > input_queue_type
Definition: flow_graph.h:1605
tbb::flow::interface11::buffer_node::buffer_operation::buffer_operation
buffer_operation(op_type t)
Definition: flow_graph.h:2113
internal::WAIT
@ WAIT
Definition: _flow_graph_types_impl.h:719
tbb::flow::interface11::buffer_node::graph_reference
graph & graph_reference() const __TBB_override
Definition: flow_graph.h:2530
tbb::flow::interface11::buffer_node::buffer_operation
Definition: flow_graph.h:2087
tbb::flow::interface11::multifunction_node::__TBB_STATIC_ASSERT
__TBB_STATIC_ASSERT((tbb::internal::is_same_type< Allocator, null_type >::value), "Allocator template parameter for flow graph nodes is deprecated and will be removed. " "Specify TBB_DEPRECATED_FLOW_NODE_ALLOCATOR to temporary enable the deprecated interface.")
tbb::flow::interface11::input_node::create_put_task
task * create_put_task()
Definition: flow_graph.h:1131
tbb::flow::interface11::indexer_node< T0, T1, T2, T3 >::unfolded_type
internal::unfolded_indexer_node< InputTuple > unfolded_type
Definition: flow_graph.h:3576
tbb::flow::interface11::graph_iterator::graph_iterator
graph_iterator()
Default constructor.
Definition: _flow_graph_impl.h:103
tbb::flow::interface11::overwrite_node::register_predecessor_task::s
successor_type & s
Definition: flow_graph.h:4593
tbb::flow::interface11::split_node::try_put_task
task * try_put_task(const TupleType &t) __TBB_override
Definition: flow_graph.h:1732
tbb::flow::interface11::indexer_node< T0, T1, T2 >::unfolded_type
internal::unfolded_indexer_node< InputTuple > unfolded_type
Definition: flow_graph.h:3543
tbb::flow::interface11::source_node::my_active
bool my_active
Definition: flow_graph.h:1380
tbb::flow::interface11::buffer_node::internal_consume
virtual void internal_consume(buffer_operation *op)
Definition: flow_graph.h:2339
tbb::task_list::empty
bool empty() const
True if list is empty; false otherwise.
Definition: task.h:1088
tbb::flow::interface11::async_node::try_put_functor
Definition: flow_graph.h:4227
tbb::flow::interface11::async_node::try_put_functor::operator()
void operator()()
Definition: flow_graph.h:4234
tbb::flow::interface11::make_edge
void make_edge(sender< T > &p, receiver< T > &s)
Makes an edge between a single predecessor and a single successor.
Definition: flow_graph.h:3830
tbb::flow::interface11::function_node::fOutput_type
internal::function_output< output_type > fOutput_type
Definition: flow_graph.h:1474
tbb::flow::interface11::sequencer_node::~sequencer_node
~sequencer_node()
Destructor.
Definition: flow_graph.h:2703
tbb::flow::internal::node_priority_t
unsigned int node_priority_t
Definition: _flow_graph_impl.h:63
tbb::flow::interface11::continue_node
Implements an executable node that supports continue_msg -> Output.
Definition: flow_graph.h:1773
tbb::flow::interface10::graph::begin
iterator begin()
start iterator
Definition: flow_graph.h:865
tbb::flow::interface11::limiter_node::my_predecessors
internal::reservable_predecessor_cache< T, spin_mutex > my_predecessors
Definition: flow_graph.h:2995
tbb::flow::interface11::sender::remove_successor
virtual __TBB_DEPRECATED bool remove_successor(successor_type &r)=0
Removes a successor from this node.
tbb::flow::interface11::receiver::try_put
bool try_put(const T &t)
Put an item to the receiver.
Definition: flow_graph.h:549
tbb::flow::interface11::indexer_node::indexer_node
__TBB_NOINLINE_SYM indexer_node(const indexer_node &other)
Definition: flow_graph.h:3801
tbb::flow::interface11::async_node::async_node
__TBB_NOINLINE_SYM async_node(const async_node &other)
Definition: flow_graph.h:4323
tbb::flow::interface11::input_node::activate
void activate()
Activates a node that was created in the inactive state.
Definition: flow_graph.h:1060
_flow_graph_trace_impl.h
internal::function_input_queue
Definition: _flow_graph_node_impl.h:34
tbb::flow::interface11::indexer_node< T0 >::indexer_node
__TBB_NOINLINE_SYM indexer_node(const indexer_node &other)
Definition: flow_graph.h:3491
tbb::flow::interface11::priority_queue_node::priority_queue_node
__TBB_NOINLINE_SYM priority_queue_node(graph &g, const Compare &comp=Compare())
Constructor.
Definition: flow_graph.h:2758
tbb::flow::interface11::internal::async_body_base
Definition: flow_graph.h:4162
tbb::flow::interface11::overwrite_node::register_predecessor_task::execute
tbb::task * execute() __TBB_override
Should be overridden by derived classes.
Definition: flow_graph.h:4585
tbb::flow::interface11::limiter_node::my_count
size_t my_count
Definition: flow_graph.h:2993
tbb::flow::interface11::buffer_node::handle_operations
virtual void handle_operations(buffer_operation *op_list)
Definition: flow_graph.h:2121
tbb::flow::interface11::priority_queue_node::reserved_item
input_type reserved_item
Definition: flow_graph.h:2879
internal::item_buffer< T, cache_aligned_allocator< T > >::front
const item_type & front() const
Definition: _flow_graph_item_buffer_impl.h:129
tbb::flow::interface11::buffer_node::buffer_operation::elem
T * elem
Definition: flow_graph.h:2101
tbb::flow::interface11::overwrite_node::register_predecessor_task::register_predecessor_task
register_predecessor_task(predecessor_type &owner, successor_type &succ)
Definition: flow_graph.h:4582
tbb::flow::interface11::indexer_node< T0, T1, T2, T3, T4, T5, T6 >::InputTuple
tuple< T0, T1, T2, T3, T4, T5, T6 > InputTuple
Definition: flow_graph.h:3677
parent
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
Definition: ittnotify_static.h:176
tbb::flow::interface11::limiter_node::initialize
void initialize()
Definition: flow_graph.h:3081
internal::function_output::function_output
function_output(graph &g)
Definition: _flow_graph_node_impl.h:866
tbb::flow::interface11::join_node< OutputTuple, key_matching< K, KHash > >::unfolded_type
internal::unfolded_join_node< N, key_matching_port, OutputTuple, key_matching< K, KHash > > unfolded_type
Definition: flow_graph.h:3355
tbb::flow::interface10::graph::~graph
~graph()
Destroys the graph.
Definition: flow_graph.h:797
tbb::flow::interface11::sender::try_consume
virtual bool try_consume()
Consumes the reserved item.
Definition: flow_graph.h:521
tbb::flow::interface11::priority_queue_node::reset_node
void reset_node(reset_flags f) __TBB_override
Definition: flow_graph.h:2790
__TBB_DEPRECATED_LIMITER_EXPR
#define __TBB_DEPRECATED_LIMITER_EXPR(expr)
Definition: _flow_graph_impl.h:52
_warning_suppress_disable_notice.h
tbb::flow::interface11::priority_queue_node::prio_use_tail
bool prio_use_tail()
Definition: flow_graph.h:2882
internal::multifunction_output::try_put
bool try_put(const output_type &i)
Definition: _flow_graph_node_impl.h:934
tbb::flow::interface11::join_node< OutputTuple, queueing >::output_type
OutputTuple output_type
Definition: flow_graph.h:3321
tbb::flow::interface11::source_node::remove_successor
bool remove_successor(successor_type &r) __TBB_override
Removes a successor from this node.
Definition: flow_graph.h:1249
tbb::flow::interface11::input_node::copy_function_object
Body copy_function_object()
Definition: flow_graph.h:1068
__TBB_override
#define __TBB_override
Definition: tbb_stddef.h:240
internal::node_cache::clear
void clear()
Definition: _flow_graph_cache_impl.h:54
tbb::flow::interface11::limiter_node::successor_type
sender< output_type >::successor_type successor_type
Definition: flow_graph.h:2982
tbb::flow::interface11::input_node::try_reserve
bool try_reserve(output_type &v) __TBB_override
Reserves an item.
Definition: flow_graph.h:1021
tbb::flow::interface11::source_node::my_cached_item
output_type my_cached_item
Definition: flow_graph.h:1387
tbb::flow::interface11::indexer_node::indexer_node
__TBB_NOINLINE_SYM indexer_node(graph &g)
Definition: flow_graph.h:3788
tbb::flow::interface11::buffer_node::successor_type
sender< output_type >::successor_type successor_type
Definition: flow_graph.h:2053
tbb::flow::interface11::composite_node< tbb::flow::tuple< InputTypes... >, tbb::flow::tuple< OutputTypes... > >::input_ports
input_ports_type & input_ports()
Definition: flow_graph.h:4022
tbb::flow::interface10::graph::register_node
void register_node(tbb::flow::interface11::graph_node *n)
Definition: flow_graph.h:819
tbb::flow::interface11::priority_queue_node::prio_pop
void prio_pop()
Definition: flow_graph.h:2899
tbb::flow::interface11::sequencer_node::my_sequencer
internal::function_body< T, size_t > * my_sequencer
Definition: flow_graph.h:2661
tbb::flow::interface11::indexer_node< T0, T1, T2 >::InputTuple
tuple< T0, T1, T2 > InputTuple
Definition: flow_graph.h:3541
tbb::flow::interface11::async_node::reset_node
void reset_node(reset_flags f) __TBB_override
Definition: flow_graph.h:4390
_allocator_traits.h
s
void const char const char int ITT_FORMAT __itt_group_sync s
Definition: ittnotify_static.h:91
internal::successor_cache< T, spin_rw_mutex >::empty
bool empty()
Definition: _flow_graph_cache_impl.h:346
tbb::flow::interface11::indexer_node< T0, T1, T2, T3, T4 >::InputTuple
tuple< T0, T1, T2, T3, T4 > InputTuple
Definition: flow_graph.h:3607
tbb::flow::interface11::internal::successor_cache
Definition: flow_graph.h:126
tbb::flow::interface11::limiter_node::try_put_task
task * try_put_task(const T &t) __TBB_override
Puts an item to this receiver.
Definition: flow_graph.h:3225
tbb::internal::fgt_async_commit
static void fgt_async_commit(void *, void *)
Definition: _flow_graph_trace_impl.h:342
tbb::flow::interface10::graph::reserve_wait
void reserve_wait() __TBB_override
Used to register that an external entity may still interact with the graph.
Definition: flow_graph.h:805
tbb::flow::interface11::buffer_node::size_type
size_t size_type
Definition: flow_graph.h:2068
tbb::flow::interface11::multifunction_node
implements a function node that supports Input -> (set of outputs)
Definition: flow_graph.h:1568
internal::reservable_item_buffer< T, cache_aligned_allocator< T > >::release_front
void release_front()
Definition: _flow_graph_item_buffer_impl.h:272
tbb::flow::interface11::composite_node< tbb::flow::tuple< InputTypes... >, tbb::flow::tuple<> >::add_nodes
void add_nodes(const NodeTypes &... n)
Definition: flow_graph.h:4077
tbb::flow::interface11::indexer_node< T0, T1, T2, T3, T4, T5, T6, T7, T8 >::InputTuple
tuple< T0, T1, T2, T3, T4, T5, T6, T7, T8 > InputTuple
Definition: flow_graph.h:3749
tbb::flow::interface11::priority_queue_node::prio_push
void prio_push(const T &src)
Definition: flow_graph.h:2888
tbb::flow::interface11::composite_node< tbb::flow::tuple< InputTypes... >, tbb::flow::tuple< OutputTypes... > >::my_input_ports
std::unique_ptr< input_ports_type > my_input_ports
Definition: flow_graph.h:3978
internal::successor_cache
An abstract cache of successors.
Definition: _flow_graph_cache_impl.h:273
tbb::flow::interface11::buffer_node::order
void order()
Definition: flow_graph.h:2268
tbb::flow::interface11::input_node
An executable node that acts as a source, i.e. it has no predecessors.
Definition: flow_graph.h:903
internal::multifunction_body
function_body that takes an Input and a set of output ports
Definition: _flow_graph_body_impl.h:192
task
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 * task
Definition: ittnotify_static.h:119
tbb::flow::interface11::priority_queue_node::mark
size_type mark
Definition: flow_graph.h:2877
internal::continue_input
Implements methods for an executable node that takes continue_msg as input.
Definition: _flow_graph_node_impl.h:753
tbb::flow::interface11::limiter_node::my_mutex
spin_mutex my_mutex
Definition: flow_graph.h:2996
internal::unfolded_join_node
unfolded_join_node : passes input_ports_type to join_node_base. We build the input port type
Definition: _flow_graph_join_impl.h:1508
tbb::flow::interface11::source_node::activate
void activate()
Activates a node that was created in the inactive state.
Definition: flow_graph.h:1337
tbb::flow::interface11::overwrite_node::my_mutex
spin_mutex my_mutex
Definition: flow_graph.h:4596
tbb::empty_task
task that does nothing. Useful for synchronization.
Definition: task.h:1042
tbb::flow::interface11::overwrite_node::clear
void clear()
Definition: flow_graph.h:4552
tbb::flow::interface11::source_node::my_successors
internal::broadcast_cache< output_type > my_successors
Definition: flow_graph.h:1384
tbb::flow::interface11::graph_node::graph_node
graph_node(graph &g)
Definition: flow_graph.h:887
internal::function_output::my_successors
broadcast_cache_type my_successors
Definition: _flow_graph_node_impl.h:920
tbb::flow::interface11::input_node::my_cached_item
output_type my_cached_item
Definition: flow_graph.h:1106
tbb::flow::interface11::buffer_node::res_item
@ res_item
Definition: flow_graph.h:2077
tbb::flow::interface11::join_node< OutputTuple, key_matching< K, KHash > >::join_node
__TBB_NOINLINE_SYM join_node(graph &g, __TBB_B0 b0, __TBB_B1 b1, __TBB_B2 b2, __TBB_B3 b3, __TBB_B4 b4)
Definition: flow_graph.h:3389
tbb::flow::interface11::rf_clear_edges
@ rf_clear_edges
Definition: _flow_graph_impl.h:161
tbb::flow::interface11::write_once_node::input_type
T input_type
Definition: flow_graph.h:4616
tbb::flow::interface11::buffer_node::internal_pop
virtual void internal_pop(buffer_operation *op)
Definition: flow_graph.h:2321
tbb::flow::interface11::queue_node::is_item_valid
bool is_item_valid()
Definition: flow_graph.h:2577
tbb::flow::interface10::graph::my_is_active
bool my_is_active
Definition: _flow_graph_impl.h:415
tbb::flow::interface11::overwrite_node::try_consume
bool try_consume() __TBB_override
Consumes the reserved item.
Definition: flow_graph.h:4545
tbb::flow::interface11::split_node::split_node
__TBB_NOINLINE_SYM split_node(graph &g)
Definition: flow_graph.h:1700
tbb::flow::interface11::sequencer_node::input_type
T input_type
Definition: flow_graph.h:2672
internal::function_input< Input, continue_msg, queueing, cache_aligned_allocator< Input > >::my_body
function_body_type * my_body
Definition: _flow_graph_node_impl.h:517
tbb::flow::interface11::async_node::successor_type
sender< output_type >::successor_type successor_type
Definition: flow_graph.h:4221
tbb::flow::interface11::async_node::base_type
multifunction_node< Input, tuple< Output >, Policy, Allocator > base_type
Definition: flow_graph.h:4213
tbb::flow::interface11::composite_node< tbb::flow::tuple< InputTypes... >, tbb::flow::tuple<> >::my_input_ports
std::unique_ptr< input_ports_type > my_input_ports
Definition: flow_graph.h:4046
tbb::flow::interface11::async_node::receiver_gateway_impl::release_wait
void release_wait() __TBB_override
Inform a graph that a previous call to reserve_wait is no longer in effect.
Definition: flow_graph.h:4247
tbb::flow::interface11::limiter_node
Forwards messages only if the threshold has not been reached.
Definition: flow_graph.h:120
tbb::flow::interface11::continue_receiver::continue_receiver
__TBB_DEPRECATED continue_receiver(const continue_receiver &src)
Copy constructor.
Definition: flow_graph.h:616
__TBB_NOINLINE_SYM
#define __TBB_NOINLINE_SYM
Definition: flow_graph.h:46
tbb::flow::interface11::multifunction_node::internals_allocator
cache_aligned_allocator< Input > internals_allocator
Definition: flow_graph.h:1588
tbb::flow::interface11::split_node::reset_node
void reset_node(reset_flags f) __TBB_override
Definition: flow_graph.h:1737
tbb::internal::fgt_internal_output_alias_helper::alias_port
static void alias_port(void *, PortsTuple &)
Definition: _flow_graph_trace_impl.h:356
internal::FAILED
@ FAILED
Definition: _flow_graph_types_impl.h:719
tbb::flow::interface11::overwrite_node::register_predecessor_task::o
predecessor_type & o
Definition: flow_graph.h:4592
tbb::flow::interface11::join_node< OutputTuple, queueing >::input_ports_type
unfolded_type::input_ports_type input_ports_type
Definition: flow_graph.h:3322
tbb::flow::interface11::overwrite_node::try_put_task
task * try_put_task(const input_type &v) __TBB_override
Definition: flow_graph.h:4562
tbb::interface6::internal::aggregator
Definition: _aggregator_impl.h:144
tbb::flow::interface11::broadcast_node::register_successor
bool register_successor(successor_type &r) __TBB_override
Adds a successor.
Definition: flow_graph.h:1944
tbb::flow::interface11::queue_node::class_type
queue_node class_type
Definition: flow_graph.h:2572
tbb::flow::interface11::split_node::graph_reference
graph & graph_reference() const __TBB_override
Definition: flow_graph.h:1744
tbb::flow::interface11::internal::async_body::my_body
Body my_body
Definition: flow_graph.h:4191
internal::function_input_base< Input, Policy, A, function_input< Input, Output, Policy, A > >::my_predecessors
predecessor_cache< input_type, null_mutex > my_predecessors
Definition: _flow_graph_node_impl.h:185
tbb::flow::interface11::sequencer_node::sequencer_node
__TBB_NOINLINE_SYM sequencer_node(graph &g, const Sequencer &s)
Constructor.
Definition: flow_graph.h:2679
internal::predecessor_cache
A cache of predecessors that only supports try_get.
Definition: _flow_graph_cache_impl.h:126
tbb::flow::interface11::async_node::receiver_gateway_impl::receiver_gateway_impl
receiver_gateway_impl(async_node *node)
Definition: flow_graph.h:4241
tbb::flow::interface11::continue_msg
An empty class used for messages that mean "I'm done".
Definition: flow_graph.h:113
tbb::flow::interface11::async_node::try_put_functor::port
output_port_type * port
Definition: flow_graph.h:4229
tbb::flow::interface11::queue_node::successor_type
sender< output_type >::successor_type successor_type
Definition: flow_graph.h:2623
internal::graph_policy_namespace::reserving
Definition: _flow_graph_body_impl.h:69
port_ref
__TBB_DEPRECATED internal::port_ref_impl< N1, N2 > port_ref()
Definition: _flow_graph_streaming_node.h:41
tbb::flow::interface10::graph::my_nodes
tbb::flow::interface11::graph_node * my_nodes
Definition: _flow_graph_impl.h:418
tbb::flow::interface11::priority_queue_node::order
void order()
Definition: flow_graph.h:2856
tbb::flow::interface11::internal::reservable_predecessor_cache
Definition: flow_graph.h:130
internal::unfolded_join_node::input_ports_type
wrap_tuple_elements< N, PT, OutputTuple >::type input_ports_type
Definition: _flow_graph_join_impl.h:1510
tbb::flow::interface11::indexer_node< T0 >::output_type
internal::tagged_msg< size_t, T0 > output_type
Definition: flow_graph.h:3476
tbb::flow::interface11::receiver_gateway
Definition: flow_graph_abstractions.h:37
tbb::internal::fgt_node
static void fgt_node(void *, string_index, void *, void *)
Definition: _flow_graph_trace_impl.h:326
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 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
Definition: ittnotify_static.h:192
tbb::flow::interface10::graph::own_context
bool own_context
Definition: _flow_graph_impl.h:412
tbb::flow::interface11::indexer_node< T0, T1, T2, T3 >::InputTuple
tuple< T0, T1, T2, T3 > InputTuple
Definition: flow_graph.h:3574
internal::continue_input::reset_receiver
void reset_receiver(reset_flags f) __TBB_override
Definition: _flow_graph_node_impl.h:797
tbb::flow::interface11::continue_receiver::my_predecessor_count
int my_predecessor_count
Definition: flow_graph.h:689
tbb::flow::interface11::source_node::my_init_body
internal::source_body< output_type > * my_init_body
Definition: flow_graph.h:1383
tbb::internal::is_same_type
Detects whether two given types are the same.
Definition: _template_helpers.h:61
tbb::flow::interface11::receiver::register_predecessor
virtual __TBB_DEPRECATED bool register_predecessor(predecessor_type &)
Add a predecessor to the node.
Definition: flow_graph.h:567
tbb::flow::interface11::split_node::__TBB_STATIC_ASSERT
__TBB_STATIC_ASSERT((tbb::internal::is_same_type< Allocator, null_type >::value), "Allocator template parameter for flow graph nodes is deprecated and will be removed. " "Specify TBB_DEPRECATED_FLOW_NODE_ALLOCATOR to temporary enable the deprecated interface.")
tbb::flow::interface11::graph_task
Base class for tasks generated by graph nodes.
Definition: _flow_graph_impl.h:80
internal::item_buffer< T, cache_aligned_allocator< T > >::size
size_type size(size_t new_tail=0)
Definition: _flow_graph_item_buffer_impl.h:151
internal::function_body< T, size_t >
tbb::flow::interface11::internal::deactivate_graph
void deactivate_graph(tbb::flow::interface10::graph &g)
Definition: _flow_graph_impl.h:490
tbb::flow::interface11::internal::async_body_base::gateway_type
Gateway gateway_type
Definition: flow_graph.h:4164
tbb::flow::interface10::graph::end
iterator end()
end iterator
Definition: flow_graph.h:867
tbb::flow::interface11::priority_queue_node::successor_type
sender< output_type >::successor_type successor_type
Definition: flow_graph.h:2755
tbb::flow::interface11::priority_queue_node::base_type
buffer_node< T, Allocator > base_type
Definition: flow_graph.h:2752
tbb::internal::fgt_async_try_put_begin
static void fgt_async_try_put_begin(void *, void *)
Definition: _flow_graph_trace_impl.h:339
tbb::flow::interface10::graph::const_iterator
tbb::flow::interface11::graph_iterator< const graph, const tbb::flow::interface11::graph_node > const_iterator
Definition: _flow_graph_impl.h:384
tbb::flow::interface11::overwrite_node::try_release
bool try_release() __TBB_override
Releases the reserved item.
Definition: flow_graph.h:4542
_flow_graph_types_impl.h
tbb::flow::interface11::indexer_node< T0, T1, T2, T3 >::indexer_node
__TBB_NOINLINE_SYM indexer_node(const indexer_node &other)
Definition: flow_graph.h:3590
internal::graph_policy_namespace
Definition: _flow_graph_body_impl.h:66
tbb::flow::interface11::broadcast_node::input_type
T input_type
Definition: flow_graph.h:1899
name
void const char const char int ITT_FORMAT __itt_group_sync x void const char * name
Definition: ittnotify_static.h:93
tbb::flow::interface11::async_node::mfn_input_type
internal::multifunction_input< Input, typename base_type::output_ports_type, Policy, Allocator > mfn_input_type
Definition: flow_graph.h:4214
tbb::flow::interface11::input_node::successor_type
sender< output_type >::successor_type successor_type
The type of successors of this node.
Definition: flow_graph.h:909
tbb::flow::interface11::async_node::gateway
gateway_type & gateway()
Definition: flow_graph.h:4332
tbb::flow::interface11::async_node::receiver_gateway_impl::try_put
bool try_put(const Output &i) __TBB_override
Implements gateway_type::try_put for an external activity to submit a message to FG.
Definition: flow_graph.h:4253
tbb::flow::interface11::buffer_node::class_type
buffer_node< T, Allocator > class_type
Definition: flow_graph.h:2054
tbb::internal::fgt_end_body
static void fgt_end_body(void *)
Definition: _flow_graph_trace_impl.h:337
tbb::flow::interface11::async_node::input_type
Input input_type
Definition: flow_graph.h:4217
internal::source_body::clone
virtual source_body * clone()=0
tbb::flow::interface11::internal::activate_graph
void activate_graph(tbb::flow::interface10::graph &g)
Definition: _flow_graph_impl.h:486
tbb::flow::interface11::limiter_node::my_threshold
size_t my_threshold
Definition: flow_graph.h:2992
tbb::flow::interface11::buffer_node::try_consume
bool try_consume() __TBB_override
Consumes a reserved item.
Definition: flow_graph.h:2498
tbb_stddef.h
tbb::flow::interface11::buffer_node::internal_forward_task
virtual void internal_forward_task(buffer_operation *op)
Tries to forward valid items to successors.
Definition: flow_graph.h:2286
tbb::flow::interface11::async_node::remove_successor
bool remove_successor(successor_type &r) __TBB_override
Removes a successor from this node.
Definition: flow_graph.h:4350
tbb::flow::interface11::buffer_node::is_item_valid
bool is_item_valid()
Definition: flow_graph.h:2270
tbb::flow::interface11::priority_queue_node::internal_pop
void internal_pop(prio_operation *op) __TBB_override
Definition: flow_graph.h:2814
tbb::flow::serial
@ serial
Definition: flow_graph.h:105
_warning_suppress_enable_notice.h
tbb::flow::interface11::indexer_node< T0, T1, T2, T3, T4, T5, T6, T7, T8 >::unfolded_type
internal::unfolded_indexer_node< InputTuple > unfolded_type
Definition: flow_graph.h:3751
tbb::flow::interface11::broadcast_node::try_put_task
task * try_put_task(const T &t) __TBB_override
build a task to run the successor if possible. Default is old behavior.
Definition: flow_graph.h:2011
tbb::flow::interface11::internal::async_body::get_body
Body get_body()
Definition: flow_graph.h:4188
p
void const char const char int ITT_FORMAT __itt_group_sync p
Definition: ittnotify_static.h:91
tbb::internal::fgt_graph
static void fgt_graph(void *)
Definition: _flow_graph_trace_impl.h:303
tbb::flow::interface11::internal::async_body::base_type
async_body_base< Gateway > base_type
Definition: flow_graph.h:4178
internal::function_input_base< Input, queueing, cache_aligned_allocator< Input >, multifunction_input< Input, internal::wrap_tuple_elements< tbb::flow::tuple_size< Output >::value, internal::multifunction_output, Output >::type, queueing, cache_aligned_allocator< Input > > >::graph_reference
graph & graph_reference() const __TBB_override
Definition: _flow_graph_node_impl.h:194
tbb::flow::interface11::composite_node< tbb::flow::tuple< InputTypes... >, tbb::flow::tuple< OutputTypes... > >::add_visible_nodes
void add_visible_nodes(const NodeTypes &... n)
Definition: flow_graph.h:4011
tbb::flow::interface11::join_node
Definition: flow_graph.h:3280
tbb::flow::interface11::priority_queue_node::item_type
buffer_node< T, Allocator >::item_type item_type
Definition: flow_graph.h:2796
tbb::flow::interface11::priority_queue_node::reheap
void reheap()
Definition: flow_graph.h:2948
tbb::flow::interface11::graph_iterator::reference
GraphNodeType & reference
Definition: _flow_graph_impl.h:98
tbb::flow::interface11::rf_reset_bodies
@ rf_reset_bodies
Definition: _flow_graph_impl.h:160
tbb::flow::interface11::source_node::try_get
bool try_get(output_type &v) __TBB_override
Request an item from the node.
Definition: flow_graph.h:1281
tbb::flow::interface11::indexer_node< T0, T1, T2, T3, T4, T5, T6 >::indexer_node
__TBB_NOINLINE_SYM indexer_node(graph &g)
Definition: flow_graph.h:3680
tbb::flow::interface11::internal::enqueue_in_graph_arena
void enqueue_in_graph_arena(tbb::flow::interface10::graph &g, tbb::task &arena_task)
Enqueues a task inside graph arena.
Definition: _flow_graph_impl.h:530
internal::item_buffer< T, cache_aligned_allocator< T > >::item_type
T item_type
Definition: _flow_graph_item_buffer_impl.h:42
tbb::flow::interface11::continue_receiver::predecessor_type
__TBB_DEPRECATED typedef receiver< input_type >::predecessor_type predecessor_type
The predecessor type for this node.
Definition: flow_graph.h:605
tbb::flow::interface11::continue_receiver::register_predecessor
__TBB_DEPRECATED bool register_predecessor(predecessor_type &) __TBB_override
Increments the trigger threshold.
Definition: flow_graph.h:623
tbb::flow::interface11::join_node< OutputTuple, key_matching< K, KHash > >::input_ports_type
unfolded_type::input_ports_type input_ports_type
Definition: flow_graph.h:3358
internal::item_buffer< T, cache_aligned_allocator< T > >::place_item
bool place_item(size_t here, const item_type &me)
Definition: _flow_graph_item_buffer_impl.h:106
internal::item_buffer< T, cache_aligned_allocator< T > >::back
const item_type & back() const
Definition: _flow_graph_item_buffer_impl.h:136
tbb::flow::interface11::write_once_node
Definition: flow_graph.h:4614
tbb::flow::interface11::join_node< OutputTuple, reserving >::join_node
__TBB_NOINLINE_SYM join_node(const join_node &other)
Definition: flow_graph.h:3302
tbb::flow::interface11::multifunction_node::output_ports_type
internal::wrap_tuple_elements< N, internal::multifunction_output, Output >::type output_ports_type
Definition: flow_graph.h:1602
internal::item_buffer< T, cache_aligned_allocator< T > >::fetch_item
void fetch_item(size_t i, item_type &o)
Definition: _flow_graph_item_buffer_impl.h:88
tbb::flow::interface11::queue_node::__TBB_STATIC_ASSERT
__TBB_STATIC_ASSERT((tbb::internal::is_same_type< Allocator, null_type >::value), "Allocator template parameter for flow graph nodes is deprecated and will be removed. " "Specify TBB_DEPRECATED_FLOW_NODE_ALLOCATOR to temporary enable the deprecated interface.")
internal::cast_to
const V & cast_to(T const &t)
Definition: _flow_graph_types_impl.h:714
tbb::flow::interface11::input_node::my_reserved
bool my_reserved
Definition: flow_graph.h:1104
_flow_graph_body_impl.h
tbb::flow::interface11::buffer_node::try_fwd_task
@ try_fwd_task
Definition: flow_graph.h:2077
tbb::task_list::pop_front
task & pop_front()
Pop the front task from the list.
Definition: task.h:1109
tbb::flow::interface11::queue_node
Forwards messages in FIFO order.
Definition: flow_graph.h:2560
tbb::flow::interface11::priority_queue_node::try_put_and_add_task
void try_put_and_add_task(task *&last_task)
Definition: flow_graph.h:2865
tbb::flow::interface11::composite_node< tbb::flow::tuple< InputTypes... >, tbb::flow::tuple<> >::add_visible_nodes
void add_visible_nodes(const NodeTypes &... n)
Definition: flow_graph.h:4074
tbb::flow::interface11::broadcast_node::successor_type
sender< output_type >::successor_type successor_type
Definition: flow_graph.h:1902
internal::reservable_item_buffer::reset
void reset()
Definition: _flow_graph_item_buffer_impl.h:254
tbb::flow::interface11::composite_node< tbb::flow::tuple< InputTypes... >, tbb::flow::tuple< OutputTypes... > >::my_output_ports
std::unique_ptr< output_ports_type > my_output_ports
Definition: flow_graph.h:3979
tbb::flow::interface11::continue_receiver::my_mutex
spin_mutex my_mutex
Definition: flow_graph.h:688
internal::function_input
Implements methods for a function node that takes a type Input as input and sends.
Definition: _flow_graph_node_impl.h:421
tbb::flow::interface11::sequencer_node::predecessor_type
receiver< input_type >::predecessor_type predecessor_type
Definition: flow_graph.h:2674
internal::queueing_port
queueing join_port
Definition: _flow_graph_join_impl.h:430
tbb::flow::interface11::join_node< OutputTuple, key_matching< K, KHash > >::join_node
__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)
Definition: flow_graph.h:3415
tbb::flow::interface11::async_node::receiver_gateway_impl
Definition: flow_graph.h:4239
tbb::flow::interface11::input_node::input_node
__TBB_NOINLINE_SYM input_node(graph &g, Body body)
Constructor for a node with a successor.
Definition: flow_graph.h:921
internal::node_cache::empty
bool empty()
Definition: _flow_graph_cache_impl.h:35
tbb::flow::interface11::source_node::my_reserved
bool my_reserved
Definition: flow_graph.h:1385
tbb::flow::interface11::receiver::predecessor_type
__TBB_DEPRECATED typedef sender< T > predecessor_type
The predecessor type for this node.
Definition: flow_graph.h:543
async_msg::my_storage
async_storage_ptr my_storage
Definition: _flow_graph_async_msg_impl.h:150
tbb::flow::interface11::join_node< OutputTuple, reserving >::input_ports_type
unfolded_type::input_ports_type input_ports_type
Definition: flow_graph.h:3289
null_mutex.h
internal::forward_task_bypass
A task that calls a node's forward_task function.
Definition: _flow_graph_body_impl.h:270
internal::async_storage
Definition: _flow_graph_async_msg_impl.h:27
internal::reservable_item_buffer< T, cache_aligned_allocator< T > >::my_reserved
bool my_reserved
Definition: _flow_graph_item_buffer_impl.h:278
tbb::flow::interface11::source_node::source_node
__TBB_NOINLINE_SYM source_node(graph &g, Body body, bool is_active=true)
Constructor for a node with a successor.
Definition: flow_graph.h:1199
tbb::flow::interface11::broadcast_node::broadcast_node
__TBB_NOINLINE_SYM broadcast_node(const broadcast_node &src)
Definition: flow_graph.h:1929
tbb::flow::interface11::buffer_node::buffer_operation::ltask
task * ltask
Definition: flow_graph.h:2102
tbb::flow::interface11::indexer_node< T0, T1, T2, T3, T4, T5, T6 >::unfolded_type
internal::unfolded_indexer_node< InputTuple > unfolded_type
Definition: flow_graph.h:3679
tbb::flow::interface11::priority_queue_node::prio_operation
buffer_node< T, Allocator >::buffer_operation prio_operation
Definition: flow_graph.h:2797
internal::output_port
tbb::flow::tuple_element< N, typename MOP::output_ports_type >::type & output_port(MOP &op)
Definition: _flow_graph_node_impl.h:719
tbb::flow::interface11::receiver::try_put_task
virtual task * try_put_task(const T &t)=0
internal::reserving_port
The two-phase join port.
Definition: _flow_graph_join_impl.h:209
tbb::flow::interface11::indexer_node< T0, T1, T2, T3, T4, T5, T6, T7, T8 >::indexer_node
__TBB_NOINLINE_SYM indexer_node(graph &g)
Definition: flow_graph.h:3752
tbb::flow::interface11::indexer_node< T0, T1, T2, T3, T4, T5, T6, T7 >::output_type
internal::tagged_msg< size_t, T0, T1, T2, T3, T4, T5, T6, T7 > output_type
Definition: flow_graph.h:3714
tbb::flow::interface11::graph_node::graph
friend class graph
Definition: _flow_graph_impl.h:455
tbb::flow::interface11::continue_receiver::remove_predecessor
__TBB_DEPRECATED bool remove_predecessor(predecessor_type &) __TBB_override
Decrements the trigger threshold.
Definition: flow_graph.h:633
tbb::spin_mutex
A lock that occupies a single byte.
Definition: spin_mutex.h:39
tbb::flow::interface11::limiter_node::output_type
T output_type
Definition: flow_graph.h:2980
tbb::flow::interface11::source_node::spawn_put
void spawn_put()
Spawns a task that applies the body.
Definition: flow_graph.h:1422
tbb::flow::interface11::split_node::base_type
receiver< TupleType > base_type
Definition: flow_graph.h:1675
S
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
Definition: ittnotify_static.h:212
tbb::flow::interface11::multifunction_node::input_impl_type
internal::multifunction_input< input_type, output_ports_type, Policy, internals_allocator > input_impl_type
Definition: flow_graph.h:1604
tbb::flow::interface11::join_node< OutputTuple, queueing >::join_node
__TBB_NOINLINE_SYM join_node(const join_node &other)
Definition: flow_graph.h:3335
tbb::flow::interface11::continue_node::successors
internal::broadcast_cache< output_type > & successors() __TBB_override
Definition: flow_graph.h:1886
tbb::flow::interface11::limiter_node::forward_task
task * forward_task()
Definition: flow_graph.h:3010
tbb::flow::interface10::graph::my_task_arena
tbb::task_arena * my_task_arena
Definition: _flow_graph_impl.h:424
tbb::flow::interface11::limiter_node::decrement
internal::decrementer< limiter_node< T, DecrementType >, DecrementType > decrement
The internal receiver< DecrementType > that decrements the count.
Definition: flow_graph.h:3093
internal::function_output::successor_type
sender< output_type >::successor_type successor_type
Definition: _flow_graph_node_impl.h:859
tbb::flow::interface11::overwrite_node::output_type
T output_type
Definition: flow_graph.h:4405
tbb::flow::interface11::source_node::create_put_task
task * create_put_task()
Definition: flow_graph.h:1416
internal::function_input::reset_function_input
void reset_function_input(reset_flags f)
Definition: _flow_graph_node_impl.h:508
tbb::flow::interface11::composite_node< tbb::flow::tuple<>, tbb::flow::tuple< OutputTypes... > >::my_output_ports
std::unique_ptr< output_ports_type > my_output_ports
Definition: flow_graph.h:4105
tbb::flow::interface11::buffer_node::__TBB_STATIC_ASSERT
__TBB_STATIC_ASSERT((tbb::internal::is_same_type< Allocator, null_type >::value), "Allocator template parameter for flow graph nodes is deprecated and will be removed. " "Specify TBB_DEPRECATED_FLOW_NODE_ALLOCATOR to temporary enable the deprecated interface.")
tbb::flow::interface11::indexer_node< T0, T1, T2, T3, T4, T5 >::output_type
internal::tagged_msg< size_t, T0, T1, T2, T3, T4, T5 > output_type
Definition: flow_graph.h:3642
__TBB_DEPRECATED_LIMITER_ARG2
#define __TBB_DEPRECATED_LIMITER_ARG2(arg1, arg2)
Definition: _flow_graph_impl.h:53
tbb::flow::interface11::priority_queue_node::heapify
void heapify()
Definition: flow_graph.h:2926
tbb::flow::interface11::async_node::async_node
__TBB_NOINLINE_SYM async_node(graph &g, size_t concurrency,)
Definition: flow_graph.h:4283
internal::is_a
bool is_a(T const &t)
Definition: _flow_graph_types_impl.h:717
tbb::flow::interface11::limiter_node::graph_reference
graph & graph_reference() const __TBB_override
Definition: flow_graph.h:3252
tbb::flow::interface11::multifunction_node::output_type
null_type output_type
Definition: flow_graph.h:1601
tbb::flow::interface11::input_node::input_type
null_type input_type
Definition: flow_graph.h:912
tbb::flow::interface11::composite_node< tbb::flow::tuple< InputTypes... >, tbb::flow::tuple< OutputTypes... > >::add_nodes
void add_nodes(const NodeTypes &... n)
Definition: flow_graph.h:4014
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 type
Definition: ittnotify_static.h:198
tbb::flow::interface11::sender::try_release
virtual bool try_release()
Releases the reserved item.
Definition: flow_graph.h:518
tbb::flow::interface11::function_node::input_impl_type
internal::function_input< input_type, output_type, Policy, internals_allocator > input_impl_type
Definition: flow_graph.h:1472
tbb::flow::interface11::buffer_node::register_successor
bool register_successor(successor_type &r) __TBB_override
Adds a new successor.
Definition: flow_graph.h:2391
tbb::flow::interface11::sender::successor_type
__TBB_DEPRECATED typedef receiver< T > successor_type
The successor type for this node.
Definition: flow_graph.h:499
tbb::flow::interface11::input_node::try_get
bool try_get(output_type &v) __TBB_override
Request an item from the node.
Definition: flow_graph.h:1003
internal::tag_value
tbb::internal::uint64_t tag_value
Definition: _flow_graph_body_impl.h:28
internal::reservable_predecessor_cache::successor_type
receiver< T > successor_type
Definition: _flow_graph_cache_impl.h:206
tbb::flow::interface11::function_node::function_node
__TBB_NOINLINE_SYM function_node(const function_node &src)
Copy constructor.
Definition: flow_graph.h:1522
tbb::flow::interface11::indexer_node< T0, T1, T2, T3, T4, T5, T6, T7 >::indexer_node
indexer_node(graph &g)
Definition: flow_graph.h:3716
tbb::flow::interface11::internal::round_robin_cache
Definition: flow_graph.h:128
null_rw_mutex.h
tbb::flow::interface11::buffer_node::reset_node
void reset_node(reset_flags f) __TBB_override
Definition: flow_graph.h:2545
tbb::flow::interface11::overwrite_node::register_successor
bool register_successor(successor_type &s) __TBB_override
Definition: flow_graph.h:4445
internal::reservable_predecessor_cache::try_consume
bool try_consume()
Definition: _flow_graph_cache_impl.h:249
tbb::flow::interface10::graph::caught_exception
bool caught_exception
Definition: _flow_graph_impl.h:414
tbb::flow::interface11::indexer_node< T0, T1, T2, T3, T4 >::indexer_node
__TBB_NOINLINE_SYM indexer_node(graph &g)
Definition: flow_graph.h:3610
tbb::flow::interface10::graph::graph
graph()
Constructs a graph with isolated task_group_context.
Definition: flow_graph.h:773
tbb::flow::interface11::receiver::reset_receiver
virtual void reset_receiver(reset_flags f=rf_reset_protocol)=0
put receiver back in initial state
internal::broadcast_cache
A cache of successors that are broadcast to.
Definition: _flow_graph_cache_impl.h:465
internal::source_body< output_type >
tbb::flow::interface11::composite_node< tbb::flow::tuple<>, tbb::flow::tuple< OutputTypes... > >::output_ports_type
tbb::flow::tuple< sender< OutputTypes > &... > output_ports_type
Definition: flow_graph.h:4102
tbb::flow::interface11::sequencer_node::successor_type
sender< output_type >::successor_type successor_type
Definition: flow_graph.h:2675
tbb::flow::interface11::continue_receiver::execute
virtual task * execute()=0
Does whatever should happen when the threshold is reached.
tbb::flow::interface11::indexer_node< T0, T1, T2, T3, T4, T5, T6, T7 >::unfolded_type
internal::unfolded_indexer_node< InputTuple > unfolded_type
Definition: flow_graph.h:3715
tbb::flow::interface11::buffer_node::req_item
@ req_item
Definition: flow_graph.h:2077
tbb::flow::interface10::graph::cbegin
const_iterator cbegin() const
start const iterator
Definition: flow_graph.h:873
tbb::flow::interface11::async_node::try_put_functor::value
const Output * value
Definition: flow_graph.h:4231
tbb::flow::interface11::buffer_node::enqueue_forwarding_task
bool enqueue_forwarding_task(buffer_operation &op_data)
Definition: flow_graph.h:2178
tbb::flow::interface10::graph::cend
const_iterator cend() const
end const iterator
Definition: flow_graph.h:875
tbb::flow::interface11::indexer_node< T0, T1, T2 >::indexer_node
__TBB_NOINLINE_SYM indexer_node(graph &g)
Definition: flow_graph.h:3544
internal::multifunction_output
Definition: _flow_graph_node_impl.h:925
tbb::flow::interface11::limiter_node::decrement_counter
task * decrement_counter(long long delta)
Definition: flow_graph.h:3068
tbb::flow::interface11::join_node< OutputTuple, key_matching< K, KHash > >::join_node
__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)
Definition: flow_graph.h:3424
tbb::flow::interface11::sequencer_node::sequencer_node
__TBB_NOINLINE_SYM sequencer_node(const sequencer_node &src)
Copy constructor.
Definition: flow_graph.h:2695
tbb::flow::interface11::composite_node< tbb::flow::tuple<>, tbb::flow::tuple< OutputTypes... > >::add_nodes
void add_nodes(const NodeTypes &... n)
Definition: flow_graph.h:4136
_flow_graph_node_set_impl.h

Copyright © 2005-2020 Intel Corporation. All Rights Reserved.

Intel, Pentium, Intel Xeon, Itanium, Intel XScale and VTune are registered trademarks or trademarks of Intel Corporation or its subsidiaries in the United States and other countries.

* Other names and brands may be claimed as the property of others.