Intel(R) Threading Building Blocks Doxygen Documentation  version 4.2.3
_flow_graph_impl.h
Go to the documentation of this file.
1 /*
2  Copyright (c) 2005-2018 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 
18 
19 */
20 
21 #ifndef __TBB_flow_graph_impl_H
22 #define __TBB_flow_graph_impl_H
23 
24 #include "../tbb_stddef.h"
25 #include "../task.h"
26 #include "../task_arena.h"
27 #include "../flow_graph_abstractions.h"
28 
29 #include <list>
30 
31 #if TBB_DEPRECATED_FLOW_ENQUEUE
32 #define FLOW_SPAWN(a) tbb::task::enqueue((a))
33 #else
34 #define FLOW_SPAWN(a) tbb::task::spawn((a))
35 #endif
36 
37 namespace tbb {
38 namespace flow {
39 
40 namespace internal {
41 static tbb::task * const SUCCESSFULLY_ENQUEUED = (task *)-1;
42 }
43 
44 namespace interface10 {
45 
47 
48 class graph;
49 class graph_node;
50 
51 template <typename GraphContainerType, typename GraphNodeType>
53  friend class graph;
54  friend class graph_node;
55 public:
56  typedef size_t size_type;
57  typedef GraphNodeType value_type;
58  typedef GraphNodeType* pointer;
59  typedef GraphNodeType& reference;
60  typedef const GraphNodeType& const_reference;
61  typedef std::forward_iterator_tag iterator_category;
62 
64  graph_iterator() : my_graph(NULL), current_node(NULL) {}
65 
69  {}
70 
73  if (this != &other) {
74  my_graph = other.my_graph;
75  current_node = other.current_node;
76  }
77  return *this;
78  }
79 
81  reference operator*() const;
82 
84  pointer operator->() const;
85 
87  bool operator==(const graph_iterator& other) const {
88  return ((my_graph == other.my_graph) && (current_node == other.current_node));
89  }
90 
92  bool operator!=(const graph_iterator& other) const { return !(operator==(other)); }
93 
97  return *this;
98  }
99 
102  graph_iterator result = *this;
103  operator++();
104  return result;
105  }
106 
107 private:
108  // the graph over which we are iterating
109  GraphContainerType *my_graph;
110  // pointer into my_graph's my_nodes list
112 
114  graph_iterator(GraphContainerType *g, bool begin);
115  void internal_forward();
116 }; // class graph_iterator
117 
118 // flags to modify the behavior of the graph reset(). Can be combined.
121  rf_reset_bodies = 1 << 0, // delete the current node body, reset to a copy of the initial node body.
122  rf_clear_edges = 1 << 1 // delete edges
123 };
124 
125 namespace internal {
126 
127 void activate_graph(graph& g);
128 void deactivate_graph(graph& g);
129 bool is_graph_active(graph& g);
130 void spawn_in_graph_arena(graph& g, tbb::task& arena_task);
132 template<typename F> void execute_in_graph_arena(graph& g, F& f);
133 
134 }
135 
137 
139  friend class graph_node;
140 
141  template< typename Body >
142  class run_task : public task {
143  public:
144  run_task(Body& body) : my_body(body) {}
146  my_body();
147  return NULL;
148  }
149  private:
150  Body my_body;
151  };
152 
153  template< typename Receiver, typename Body >
154  class run_and_put_task : public task {
155  public:
156  run_and_put_task(Receiver &r, Body& body) : my_receiver(r), my_body(body) {}
158  tbb::task *res = my_receiver.try_put_task(my_body());
159  if (res == SUCCESSFULLY_ENQUEUED) res = NULL;
160  return res;
161  }
162  private:
163  Receiver &my_receiver;
164  Body my_body;
165  };
166  typedef std::list<tbb::task *> task_list_type;
167 
168  class wait_functor {
170  public:
173  };
174 
178  public:
180  void operator()() const {
182  }
183  };
184 
185  void prepare_task_arena(bool reinit = false) {
186  if (reinit) {
187  __TBB_ASSERT(my_task_arena, "task arena is NULL");
190  }
191  else {
192  __TBB_ASSERT(my_task_arena == NULL, "task arena is not NULL");
194  }
195  if (!my_task_arena->is_active()) // failed to attach
196  my_task_arena->initialize(); // create a new, default-initialized arena
197  __TBB_ASSERT(my_task_arena->is_active(), "task arena is not active");
198  }
199 
200 public:
202  graph();
203 
205  explicit graph(tbb::task_group_context& use_this_context);
206 
208 
209  ~graph();
210 
211 #if TBB_PREVIEW_FLOW_GRAPH_TRACE
212  void set_name(const char *name);
213 #endif
214 
216  reserve_wait();
217  }
218 
220  release_wait();
221  }
222 
224 
227 
229 
232 
234 
236  template< typename Receiver, typename Body >
237  void run(Receiver &r, Body body) {
238  if (internal::is_graph_active(*this)) {
239  task* rtask = new (task::allocate_additional_child_of(*root_task()))
242  }
243  }
244 
246 
248  template< typename Body >
249  void run(Body body) {
250  if (internal::is_graph_active(*this)) {
251  task* rtask = new (task::allocate_additional_child_of(*root_task())) run_task< Body >(body);
253  }
254  }
255 
257 
258  void wait_for_all() {
259  cancelled = false;
260  caught_exception = false;
261  if (my_root_task) {
262 #if TBB_USE_EXCEPTIONS
263  try {
264 #endif
267 #if TBB_USE_EXCEPTIONS
268  }
269  catch (...) {
271  my_context->reset();
272  caught_exception = true;
273  cancelled = true;
274  throw;
275  }
276 #endif
277  // TODO: the "if" condition below is just a work-around to support the concurrent wait
278  // mode. The cancellation and exception mechanisms are still broken in this mode.
279  // Consider using task group not to re-implement the same functionality.
281  my_context->reset(); // consistent with behavior in catch()
283  }
284  }
285  }
286 
289  return my_root_task;
290  }
291 
292  // ITERATORS
293  template<typename C, typename N>
294  friend class graph_iterator;
295 
296  // Graph iterator typedefs
299 
300  // Graph iterator constructors
302  iterator begin();
304  iterator end();
306  const_iterator begin() const;
308  const_iterator end() const;
310  const_iterator cbegin() const;
312  const_iterator cend() const;
313 
315  bool is_cancelled() { return cancelled; }
317 
318  // thread-unsafe state reset.
320 
321 private:
325  bool cancelled;
329 
331 
333  void register_node(graph_node *n);
334  void remove_node(graph_node *n);
335 
337 
338  friend void internal::activate_graph(graph& g);
339  friend void internal::deactivate_graph(graph& g);
340  friend bool internal::is_graph_active(graph& g);
341  friend void internal::spawn_in_graph_arena(graph& g, tbb::task& arena_task);
343  template<typename F> friend void internal::execute_in_graph_arena(graph& g, F& f);
344 
346 
347 }; // class graph
348 
351  friend class graph;
352  template<typename C, typename N>
353  friend class graph_iterator;
354 protected:
357 public:
358  explicit graph_node(graph& g);
359 
360  virtual ~graph_node();
361 
362 #if TBB_PREVIEW_FLOW_GRAPH_TRACE
363  virtual void set_name(const char *name) = 0;
364 #endif
365 
366 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION
367  virtual void extract() = 0;
368 #endif
369 
370 protected:
371  // performs the reset on an individual node.
372  virtual void reset_node(reset_flags f = rf_reset_protocol) = 0;
373 }; // class graph_node
374 
375 namespace internal {
376 
377 inline void activate_graph(graph& g) {
378  g.my_is_active = true;
379 }
380 
381 inline void deactivate_graph(graph& g) {
382  g.my_is_active = false;
383 }
384 
385 inline bool is_graph_active(graph& g) {
386  return g.my_is_active;
387 }
388 
390 template<typename F>
391 inline void execute_in_graph_arena(graph& g, F& f) {
392  if (is_graph_active(g)) {
394  g.my_task_arena->execute(f);
395  }
396 }
397 
399 inline void spawn_in_graph_arena(graph& g, tbb::task& arena_task) {
400  graph::spawn_functor s_fn(arena_task);
401  execute_in_graph_arena(g, s_fn);
402 }
403 
405  g.my_reset_task_list.push_back(tp);
406 }
407 
408 } // namespace internal
409 
410 } // namespace interface10
411 } // namespace flow
412 } // namespace tbb
413 
414 #endif // __TBB_flow_graph_impl_H
void run(Body body)
Spawns a task that runs a function object.
tbb::task * execute() __TBB_override
Should be overridden by derived classes.
void set_ref_count(int count)
Set reference count.
Definition: task.h:718
graph()
Constructs a graph with isolated task_group_context.
Definition: flow_graph.h:741
std::list< tbb::task * > task_list_type
void spawn_in_graph_arena(graph &g, tbb::task &arena_task)
Spawns a task inside graph arena.
void reserve_wait() __TBB_override
Used to register that an external entity may still interact with the graph.
Definition: flow_graph.h:771
Base class for user-defined tasks.
Definition: task.h:576
bool is_cancelled()
return status of graph execution
Pure virtual template classes that define interfaces for async communication.
bool operator==(const graph_iterator &other) const
Equality.
A lock that occupies a single byte.
Definition: spin_mutex.h:40
Base class for types that should not be copied or assigned.
Definition: tbb_stddef.h:335
tbb::task_group_context * my_context
graph_iterator & operator=(const graph_iterator &other)
Assignment.
void register_node(graph_node *n)
Definition: flow_graph.h:785
reference operator *() const
Dereference.
Definition: flow_graph.h:725
void wait_for_all()
Wait for reference count to become one, and set reference count to zero.
Definition: task.h:776
iterator begin()
start iterator
Definition: flow_graph.h:831
void __TBB_EXPORTED_METHOD reset()
Forcefully reinitializes the context after the task tree it was associated with is completed.
#define __TBB_ASSERT(predicate, comment)
No-op version of __TBB_ASSERT.
Definition: tbb_stddef.h:169
The base of all graph nodes.
#define __TBB_override
Definition: tbb_stddef.h:244
tbb::task * execute() __TBB_override
Should be overridden by derived classes.
Tag class used to indicate the "attaching" constructor.
Definition: task_arena.h:235
Base class for types that should not be assigned.
Definition: tbb_stddef.h:324
#define FLOW_SPAWN(a)
void execute_in_graph_arena(graph &g, F &f)
Executes custom functor inside graph arena.
graph_iterator< graph, graph_node > iterator
void remove_node(graph_node *n)
Definition: flow_graph.h:796
const_iterator cend() const
end const iterator
Definition: flow_graph.h:841
graph_iterator(const graph_iterator &other)
Copy constructor.
Used to form groups of tasks.
Definition: task.h:319
void wait_for_all()
Wait until graph is idle and decrement_wait_count calls equals increment_wait_count calls.
virtual void reset_node(reset_flags f=rf_reset_protocol)=0
graph_iterator operator++(int)
Post-increment.
graph_iterator & operator++()
Pre-increment.
graph_iterator< const graph, const graph_node > const_iterator
void initialize()
Forces allocation of the resources for the task_arena as specified in constructor arguments.
Definition: task_arena.h:247
std::forward_iterator_tag iterator_category
void release_wait() __TBB_override
Deregisters an external entity that may have interacted with the graph.
Definition: flow_graph.h:778
The graph class.
pointer operator->() const
Dereference.
Definition: flow_graph.h:731
internal::return_type_or_void< F >::type execute(F &f)
Definition: task_arena.h:332
void run(Receiver &r, Body body)
Spawns a task that runs a body and puts its output to a specific receiver.
iterator end()
end iterator
Definition: flow_graph.h:833
void add_task_to_graph_reset_list(graph &g, tbb::task *tp)
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function void size_t int ITT_FORMAT d __itt_heap_function void ITT_FORMAT p __itt_heap_function void void size_t int ITT_FORMAT d no args no args unsigned int ITT_FORMAT u const __itt_domain __itt_id ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain __itt_id ITT_FORMAT p const __itt_domain __itt_id __itt_timestamp begin
void reset(reset_flags f=rf_reset_protocol)
Definition: flow_graph.h:808
const_iterator cbegin() const
start const iterator
Definition: flow_graph.h:839
uintptr_t traits() const
Returns the context's trait.
Definition: task.h:539
tbb::task * root_task()
Returns the root task of the graph.
~graph()
Destroys the graph.
Definition: flow_graph.h:763
void const char const char int ITT_FORMAT __itt_group_sync x void const char * name
static tbb::task *const SUCCESSFULLY_ENQUEUED
void prepare_task_arena(bool reinit=false)
bool operator!=(const graph_iterator &other) const
Inequality.
bool __TBB_EXPORTED_METHOD is_group_execution_cancelled() const
Returns true if the context received cancellation request.

Copyright © 2005-2018 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.