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");
71 recycle_as_safe_continuation();
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);
88 spawner(
const function1& _func1,
const function2& _func2,
const function3& _func3) : my_func1(_func1), my_func2(_func2), my_func3(_func3), is_recycled(false) {}
97 void operator() ()
const {}
102 set_ref_count(number_of_children + 1);
105 #if __TBB_VARIADIC_PARALLEL_INVOKE 106 void add_children() {}
109 template <
typename function>
110 void add_children(
function&& _func)
112 internal::function_invoker<function>* invoker =
new (allocate_child()) internal::function_invoker<function>(std::forward<function>(_func));
117 template<
typename function>
120 add_children(std::forward<function>(_func));
124 template <
typename function1,
typename function2,
typename...
function>
125 void add_children(function1&& _func1, function2&& _func2,
function&&... _func)
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);
132 add_children(std::forward<function>(_func)...);
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);
169 spawn_and_wait_for_all(*invoker);
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> {
208 template<
typename T1,
typename... 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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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 * execute() __TBB_override
Should be overridden by derived classes.
const function3 & my_func3
#define __TBB_STATIC_ASSERT(condition, msg)
#define __TBB_ASSERT(predicate, comment)
No-op version of __TBB_ASSERT.
task * execute() __TBB_override
Should be overridden by derived classes.
bool_constant< true > true_type
task that does nothing. Useful for synchronization.
internal::parallel_invoke_helper & root
const function & my_function
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
function_invoker(const function &_function)
void run_and_finish(const F0 &f0)
const function2 & my_func2
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.
void add_children(const function &_func)
spawner(const function1 &_func1, const function2 &_func2, const function3 &_func3)
parallel_invoke_helper(int number_of_children)
void add_children(const function1 &_func1, const function2 &_func2, const function3 &_func3)
~parallel_invoke_cleaner()
void add_children(const function1 &_func1, const function2 &_func2)
Used to form groups of tasks.
parallel_invoke_cleaner(int number_of_children, tbb::task_group_context &context)
Base class for user-defined tasks.
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_group_context(kind_type relation_with_parent=bound, uintptr_t t=default_traits)
Default & binding constructor.
const function1 & my_func1