Intel(R) Threading Building Blocks Doxygen Documentation  version 4.2.3
parallel_while.h
Go to the documentation of this file.
1 /*
2  Copyright (c) 2005-2019 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_parallel_while
22 #define __TBB_parallel_while
23 
24 #include "task.h"
25 #include <new>
26 
27 namespace tbb {
28 
29 template<typename Body>
31 
33 namespace internal {
34 
35  template<typename Stream, typename Body> class while_task;
36 
38 
40  template<typename Body>
41  class while_iteration_task: public task {
42  const Body& my_body;
43  typename Body::argument_type my_value;
46  return NULL;
47  }
48  while_iteration_task( const typename Body::argument_type& value, const Body& body ) :
49  my_body(body), my_value(value)
50  {}
51  template<typename Body_> friend class while_group_task;
52  friend class tbb::parallel_while<Body>;
53  };
54 
56 
58  template<typename Body>
59  class while_group_task: public task {
60  static const size_t max_arg_size = 4;
61  const Body& my_body;
62  size_t size;
63  typename Body::argument_type my_arg[max_arg_size];
64  while_group_task( const Body& body ) : my_body(body), size(0) {}
66  typedef while_iteration_task<Body> iteration_type;
67  __TBB_ASSERT( size>0, NULL );
68  task_list list;
69  task* t;
70  size_t k=0;
71  for(;;) {
72  t = new( allocate_child() ) iteration_type(my_arg[k],my_body);
73  if( ++k==size ) break;
74  list.push_back(*t);
75  }
76  set_ref_count(int(k+1));
77  spawn(list);
79  return NULL;
80  }
81  template<typename Stream, typename Body_> friend class while_task;
82  };
83 
85 
87  template<typename Stream, typename Body>
88  class while_task: public task {
89  Stream& my_stream;
90  const Body& my_body;
93  typedef while_group_task<Body> block_type;
94  block_type& t = *new( allocate_additional_child_of(my_barrier) ) block_type(my_body);
95  size_t k=0;
96  while( my_stream.pop_if_present(t.my_arg[k]) ) {
97  if( ++k==block_type::max_arg_size ) {
98  // There might be more iterations.
100  break;
101  }
102  }
103  if( k==0 ) {
104  destroy(t);
105  return NULL;
106  } else {
107  t.size = k;
108  return &t;
109  }
110  }
111  while_task( Stream& stream, const Body& body, empty_task& barrier ) :
112  my_stream(stream),
113  my_body(body),
114  my_barrier(barrier)
115  {}
116  friend class tbb::parallel_while<Body>;
117  };
118 
119 } // namespace internal
121 
123 
128 template<typename Body>
129 class parallel_while: internal::no_copy {
130 public:
132  parallel_while() : my_body(NULL), my_barrier(NULL) {}
133 
136  if( my_barrier ) {
137  my_barrier->destroy(*my_barrier);
138  my_barrier = NULL;
139  }
140  }
141 
143  typedef typename Body::argument_type value_type;
144 
146 
149  template<typename Stream>
150  void run( Stream& stream, const Body& body );
151 
153 
154  void add( const value_type& item );
155 
156 private:
157  const Body* my_body;
159 };
160 
161 template<typename Body>
162 template<typename Stream>
163 void parallel_while<Body>::run( Stream& stream, const Body& body ) {
164  using namespace internal;
165  empty_task& barrier = *new( task::allocate_root() ) empty_task();
166  my_body = &body;
167  my_barrier = &barrier;
168  my_barrier->set_ref_count(2);
169  while_task<Stream,Body>& w = *new( my_barrier->allocate_child() ) while_task<Stream,Body>( stream, body, barrier );
170  my_barrier->spawn_and_wait_for_all(w);
171  my_barrier->destroy(*my_barrier);
172  my_barrier = NULL;
173  my_body = NULL;
174 }
175 
176 template<typename Body>
178  __TBB_ASSERT(my_barrier,"attempt to add to parallel_while that is not running");
179  typedef internal::while_iteration_task<Body> iteration_type;
180  iteration_type& i = *new( task::allocate_additional_child_of(*my_barrier) ) iteration_type(item,*my_body);
181  task::self().spawn( i );
182 }
183 
184 } // namespace
185 
186 #endif /* __TBB_parallel_while */
task * execute() __TBB_override
Should be overridden by derived classes.
#define __TBB_override
Definition: tbb_stddef.h:244
internal::allocate_child_proxy & allocate_child()
Returns proxy for overloaded new that allocates a child task of *this.
Definition: task.h:654
For internal use only.
Body::argument_type my_arg[max_arg_size]
Parallel iteration over a stream, with optional addition of more work.
#define __TBB_ASSERT(predicate, comment)
No-op version of __TBB_ASSERT.
Definition: tbb_stddef.h:169
task that does nothing. Useful for synchronization.
Definition: task.h:959
void run(Stream &stream, const Body &body)
Apply body.apply to each item in the stream.
A list of children.
Definition: task.h:990
Base class for user-defined tasks.
Definition: task.h:592
static task &__TBB_EXPORTED_FUNC self()
The innermost task being executed or destroyed by the current thread at the moment.
Definition: task.cpp:205
void add(const value_type &item)
Add a work item while running.
void spawn_and_wait_for_all(task &child)
Similar to spawn followed by wait_for_all, but more efficient.
Definition: task.h:773
while_task(Stream &stream, const Body &body, empty_task &barrier)
empty_task * my_barrier
task * execute() __TBB_override
Should be overridden by derived classes.
while_iteration_task(const typename Body::argument_type &value, const Body &body)
The graph class.
const Body * my_body
while_group_task(const Body &body)
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function void size_t int ITT_FORMAT d __itt_heap_function void ITT_FORMAT p __itt_heap_function void void size_t int ITT_FORMAT d no args no args unsigned int ITT_FORMAT u const __itt_domain __itt_id ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain __itt_id ITT_FORMAT p const __itt_domain __itt_id __itt_timestamp __itt_timestamp ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain ITT_FORMAT p const __itt_domain __itt_string_handle unsigned long long value
void push_back(task &task)
Push task onto back of list.
Definition: task.h:1007
void recycle_to_reexecute()
Schedule this for reexecution after current execute() returns.
Definition: task.h:714
task * execute() __TBB_override
Should be overridden by derived classes.
~parallel_while()
Destructor cleans up data members before returning.
void set_ref_count(int count)
Set reference count.
Definition: task.h:734
For internal use only.
Body::argument_type value_type
Type of items.
static internal::allocate_root_proxy allocate_root()
Returns proxy for overloaded new that allocates a root task.
Definition: task.h:636
parallel_while()
Construct empty non-running parallel while.
static const size_t max_arg_size

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