21 #ifndef __TBB_parallel_invoke_H 22 #define __TBB_parallel_invoke_H 27 #if __TBB_VARIADIC_PARALLEL_INVOKE 33 #if !__TBB_TASK_GROUP_CONTEXT 35 struct task_group_context {
43 template<
typename function>
57 template <
size_t N,
typename function1,
typename function2,
typename function3>
69 __TBB_ASSERT(N==2 || N==3,
"Number of arguments passed to spawner is wrong");
72 internal::function_invoker<function2>* invoker2 =
new (
allocate_child()) internal::function_invoker<function2>(
my_func2);
77 internal::function_invoker<function3>* invoker3 =
new (
allocate_child()) internal::function_invoker<function3>(
my_func3);
105 #if __TBB_VARIADIC_PARALLEL_INVOKE 109 template <
typename function>
112 internal::function_invoker<function>* invoker =
new (
allocate_child()) internal::function_invoker<function>(std::forward<function>(_func));
117 template<
typename function>
124 template <
typename function1,
typename function2,
typename...
function>
125 void add_children(function1&& _func1, function2&& _func2,
function&&... _func)
128 parallel_invoke_noop noop;
129 typedef internal::spawner<2, function1, function2, parallel_invoke_noop> spawner_type;
130 spawner_type & sub_root = *
new(
allocate_child()) spawner_type(std::forward<function1>(_func1), std::forward<function2>(_func2), noop);
136 template <
typename function>
139 internal::function_invoker<function>* invoker =
new (
allocate_child()) internal::function_invoker<function>(_func);
146 template <
typename function1,
typename function2>
151 internal::spawner<2, function1, function2, parallel_invoke_noop>& sub_root = *
new(
allocate_child())internal::spawner<2, function1, function2, parallel_invoke_noop>(_func1, _func2, noop);
155 template <
typename function1,
typename function2,
typename function3>
156 void add_children (
const function1& _func1,
const function2& _func2,
const function3& _func3)
158 internal::spawner<3, function1, function2, function3>& sub_root = *
new(
allocate_child())internal::spawner<3, function1, function2, function3>(_func1, _func2, _func3);
161 #endif // __TBB_VARIADIC_PARALLEL_INVOKE 164 template <
typename F0>
167 internal::function_invoker<F0>* invoker =
new (
allocate_child()) internal::function_invoker<F0>(f0);
175 #if __TBB_TASK_GROUP_CONTEXT 187 internal::parallel_invoke_helper&
root;
190 #if __TBB_VARIADIC_PARALLEL_INVOKE 192 template<
typename... T>
struct impl_selector;
194 template<
typename T1,
typename... T>
struct impl_selector<T1, T...> {
195 typedef typename impl_selector<T...>
::type type;
198 template<
typename T>
struct impl_selector<T> {
201 template<>
struct impl_selector<task_group_context&> {
206 inline task_group_context& get_context( task_group_context& tgc ) {
return tgc; }
208 template<
typename T1,
typename... T>
209 task_group_context& get_context( T1&& , T&&... t )
210 {
return get_context( std::forward<T>(t)... ); }
213 template<
typename F0,
typename F1,
typename... F>
214 void parallel_invoke_impl(
true_type, F0&& f0, F1&& f1, F&&... f) {
217 const size_t number_of_children = 2 +
sizeof...(F)/2;
218 parallel_invoke_cleaner cleaner(number_of_children, get_context(std::forward<F>(f)...));
219 parallel_invoke_helper& root = cleaner.root;
221 root.add_children(std::forward<F>(f)...);
222 root.add_children(std::forward<F1>(f1));
223 root.run_and_finish(std::forward<F0>(f0));
227 template<
typename F0,
typename F1,
typename... F>
228 void parallel_invoke_impl(
false_type, F0&& f0, F1&& f1, F&&... f) {
231 parallel_invoke_impl(
true_type(), std::forward<F0>(f0), std::forward<F1>(f1), std::forward<F>(f)..., context);
243 #if __TBB_VARIADIC_PARALLEL_INVOKE 247 template<
typename F0,
typename F1,
typename... F>
250 internal::parallel_invoke_impl(selector_type(), std::forward<F0>(f0), std::forward<F1>(f1), std::forward<F>(f)...);
257 template<
typename F0,
typename F1 >
259 internal::parallel_invoke_cleaner cleaner(2, context);
260 internal::parallel_invoke_helper& root = cleaner.root;
262 root.add_children(f1);
264 root.run_and_finish(f0);
268 template<
typename F0,
typename F1,
typename F2 >
270 internal::parallel_invoke_cleaner cleaner(3, context);
271 internal::parallel_invoke_helper& root = cleaner.root;
273 root.add_children(f2);
274 root.add_children(f1);
276 root.run_and_finish(f0);
280 template<
typename F0,
typename F1,
typename F2,
typename F3>
284 internal::parallel_invoke_cleaner cleaner(4, context);
285 internal::parallel_invoke_helper& root = cleaner.root;
287 root.add_children(f3);
288 root.add_children(f2);
289 root.add_children(f1);
291 root.run_and_finish(f0);
295 template<
typename F0,
typename F1,
typename F2,
typename F3,
typename F4 >
296 void parallel_invoke(
const F0& f0,
const F1& f1,
const F2& f2,
const F3& f3,
const F4& f4,
299 internal::parallel_invoke_cleaner cleaner(3, context);
300 internal::parallel_invoke_helper& root = cleaner.root;
302 root.add_children(f4, f3);
303 root.add_children(f2, f1);
305 root.run_and_finish(f0);
309 template<
typename F0,
typename F1,
typename F2,
typename F3,
typename F4,
typename F5>
310 void parallel_invoke(
const F0& f0,
const F1& f1,
const F2& f2,
const F3& f3,
const F4& f4,
const F5& f5,
313 internal::parallel_invoke_cleaner cleaner(3, context);
314 internal::parallel_invoke_helper& root = cleaner.root;
316 root.add_children(f5, f4, f3);
317 root.add_children(f2, f1);
319 root.run_and_finish(f0);
323 template<
typename F0,
typename F1,
typename F2,
typename F3,
typename F4,
typename F5,
typename F6>
324 void parallel_invoke(
const F0& f0,
const F1& f1,
const F2& f2,
const F3& f3,
const F4& f4,
325 const F5& f5,
const F6& f6,
328 internal::parallel_invoke_cleaner cleaner(3, context);
329 internal::parallel_invoke_helper& root = cleaner.root;
331 root.add_children(f6, f5, f4);
332 root.add_children(f3, f2, f1);
334 root.run_and_finish(f0);
338 template<
typename F0,
typename F1,
typename F2,
typename F3,
typename F4,
339 typename F5,
typename F6,
typename F7>
340 void parallel_invoke(
const F0& f0,
const F1& f1,
const F2& f2,
const F3& f3,
const F4& f4,
341 const F5& f5,
const F6& f6,
const F7& f7,
344 internal::parallel_invoke_cleaner cleaner(4, context);
345 internal::parallel_invoke_helper& root = cleaner.root;
347 root.add_children(f7, f6, f5);
348 root.add_children(f4, f3);
349 root.add_children(f2, f1);
351 root.run_and_finish(f0);
355 template<
typename F0,
typename F1,
typename F2,
typename F3,
typename F4,
356 typename F5,
typename F6,
typename F7,
typename F8>
357 void parallel_invoke(
const F0& f0,
const F1& f1,
const F2& f2,
const F3& f3,
const F4& f4,
358 const F5& f5,
const F6& f6,
const F7& f7,
const F8& f8,
361 internal::parallel_invoke_cleaner cleaner(4, context);
362 internal::parallel_invoke_helper& root = cleaner.root;
364 root.add_children(f8, f7, f6);
365 root.add_children(f5, f4, f3);
366 root.add_children(f2, f1);
368 root.run_and_finish(f0);
372 template<
typename F0,
typename F1,
typename F2,
typename F3,
typename F4,
373 typename F5,
typename F6,
typename F7,
typename F8,
typename F9>
374 void parallel_invoke(
const F0& f0,
const F1& f1,
const F2& f2,
const F3& f3,
const F4& f4,
375 const F5& f5,
const F6& f6,
const F7& f7,
const F8& f8,
const F9& f9,
378 internal::parallel_invoke_cleaner cleaner(4, context);
379 internal::parallel_invoke_helper& root = cleaner.root;
381 root.add_children(f9, f8, f7);
382 root.add_children(f6, f5, f4);
383 root.add_children(f3, f2, f1);
385 root.run_and_finish(f0);
389 template<
typename F0,
typename F1>
392 parallel_invoke<F0, F1>(f0, f1, context);
395 template<
typename F0,
typename F1,
typename F2>
398 parallel_invoke<F0, F1, F2>(f0, f1, f2, context);
401 template<
typename F0,
typename F1,
typename F2,
typename F3 >
404 parallel_invoke<F0, F1, F2, F3>(f0, f1, f2, f3, context);
407 template<
typename F0,
typename F1,
typename F2,
typename F3,
typename F4>
408 void parallel_invoke(
const F0& f0,
const F1& f1,
const F2& f2,
const F3& f3,
const F4& f4) {
410 parallel_invoke<F0, F1, F2, F3, F4>(f0, f1, f2, f3, f4, context);
413 template<
typename F0,
typename F1,
typename F2,
typename F3,
typename F4,
typename F5>
414 void parallel_invoke(
const F0& f0,
const F1& f1,
const F2& f2,
const F3& f3,
const F4& f4,
const F5& f5) {
416 parallel_invoke<F0, F1, F2, F3, F4, F5>(f0, f1, f2, f3, f4, f5, context);
419 template<
typename F0,
typename F1,
typename F2,
typename F3,
typename F4,
typename F5,
typename F6>
420 void parallel_invoke(
const F0& f0,
const F1& f1,
const F2& f2,
const F3& f3,
const F4& f4,
421 const F5& f5,
const F6& f6)
424 parallel_invoke<F0, F1, F2, F3, F4, F5, F6>(f0, f1, f2, f3, f4, f5, f6, context);
427 template<
typename F0,
typename F1,
typename F2,
typename F3,
typename F4,
428 typename F5,
typename F6,
typename F7>
429 void parallel_invoke(
const F0& f0,
const F1& f1,
const F2& f2,
const F3& f3,
const F4& f4,
430 const F5& f5,
const F6& f6,
const F7& f7)
433 parallel_invoke<F0, F1, F2, F3, F4, F5, F6, F7>(f0, f1, f2, f3, f4, f5, f6, f7, context);
436 template<
typename F0,
typename F1,
typename F2,
typename F3,
typename F4,
437 typename F5,
typename F6,
typename F7,
typename F8>
438 void parallel_invoke(
const F0& f0,
const F1& f1,
const F2& f2,
const F3& f3,
const F4& f4,
439 const F5& f5,
const F6& f6,
const F7& f7,
const F8& f8)
442 parallel_invoke<F0, F1, F2, F3, F4, F5, F6, F7, F8>(f0, f1, f2, f3, f4, f5, f6, f7, f8, context);
445 template<
typename F0,
typename F1,
typename F2,
typename F3,
typename F4,
446 typename F5,
typename F6,
typename F7,
typename F8,
typename F9>
447 void parallel_invoke(
const F0& f0,
const F1& f1,
const F2& f2,
const F3& f3,
const F4& f4,
448 const F5& f5,
const F6& f6,
const F7& f7,
const F8& f8,
const F9& f9)
451 parallel_invoke<F0, F1, F2, F3, F4, F5, F6, F7, F8, F9>(f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, context);
453 #endif // __TBB_VARIADIC_PARALLEL_INVOKE task_group_context(kind_type relation_with_parent=bound, uintptr_t t=default_traits)
Default & binding constructor.
internal::allocate_child_proxy & allocate_child()
Returns proxy for overloaded new that allocates a child task of *this.
#define __TBB_STATIC_ASSERT(condition, msg)
#define __TBB_ASSERT(predicate, comment)
No-op version of __TBB_ASSERT.
const function & my_function
task that does nothing. Useful for synchronization.
Used to form groups of tasks.
bool_constant< true > true_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_id __itt_string_handle __itt_metadata_type type
void run_and_finish(const F0 &f0)
Base class for user-defined tasks.
internal::parallel_invoke_helper & root
void add_children(const function &_func)
void spawn_and_wait_for_all(task &child)
Similar to spawn followed by wait_for_all, but more efficient.
function_invoker(const function &_function)
parallel_invoke_helper(int number_of_children)
void parallel_invoke(const F0 &f0, const F1 &f1, tbb::task_group_context &context)
Executes a list of tasks in parallel and waits for all tasks to complete.
const function2 & my_func2
const function3 & my_func3
void add_children(const function1 &_func1, const function2 &_func2, const function3 &_func3)
~parallel_invoke_cleaner()
const function1 & my_func1
parallel_invoke_cleaner(int number_of_children, tbb::task_group_context &context)
task * execute() __TBB_override
Should be overridden by derived classes.
void recycle_as_safe_continuation()
Recommended to use, safe variant of recycle_as_continuation.
void set_ref_count(int count)
Set reference count.
bool_constant< false > false_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_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 d int
task * execute() __TBB_override
Should be overridden by derived classes.
void add_children(const function1 &_func1, const function2 &_func2)
spawner(const function1 &_func1, const function2 &_func2, const function3 &_func3)