Embedded Multicore Building Blocks V1.0.0
invoke.h
1 /*
2  * Copyright (c) 2014-2017, Siemens AG. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * 1. Redistributions of source code must retain the above copyright notice,
8  * this list of conditions and the following disclaimer.
9  *
10  * 2. Redistributions in binary form must reproduce the above copyright notice,
11  * this list of conditions and the following disclaimer in the documentation
12  * and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
18  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24  * POSSIBILITY OF SUCH DAMAGE.
25  */
26 
27 #ifndef EMBB_ALGORITHMS_INVOKE_H_
28 #define EMBB_ALGORITHMS_INVOKE_H_
29 
30 #include <embb/base/function.h>
31 #include <embb/mtapi/mtapi.h>
32 
33 namespace embb {
34 namespace algorithms {
35 
48 
49 #ifdef DOXYGEN
50 
59 template<typename Function1, typename Function2, ...>
60 void Invoke(
61  Function1 func1,
63  Function2 func2,
65  ...);
66 
75 template<typename Function1, typename Function2, ...>
76 void Invoke(
77  Function1 func1,
79  Function2 func2,
81  ...,
82  const embb::mtapi::ExecutionPolicy & policy
84  );
85 
86 #else // DOXYGEN
87 
88 namespace internal {
89 
93 template<typename Function>
94 class TaskWrapper {
95  public:
100  explicit TaskWrapper(
101  Function function,
102  const embb::mtapi::ExecutionPolicy& policy)
103  : function_(function), task_() {
105  embb::base::MakeFunction(*this, &TaskWrapper::Run),
106  policy);
107  }
108 
112  ~TaskWrapper() {
113  task_.Wait(MTAPI_INFINITE);
114  }
115 
116  private:
117  Function function_;
118  embb::mtapi::Task task_;
119 
120  void Run(embb::mtapi::TaskContext&) {
121  function_();
122  }
123 };
124 
128 template<>
129 class TaskWrapper<embb::mtapi::Job> {
130  public:
135  explicit TaskWrapper(
136  embb::mtapi::Job function,
137  const embb::mtapi::ExecutionPolicy& policy)
138  : function_(function), task_() {
140  attr.SetPolicy(policy);
142  function,
143  static_cast<void const *>(MTAPI_NULL),
144  static_cast<void *>(MTAPI_NULL),
145  attr);
146  }
147 
151  ~TaskWrapper() {
152  task_.Wait(MTAPI_INFINITE);
153  }
154 
155  private:
156  embb::mtapi::Job function_;
157  embb::mtapi::Task task_;
158 };
159 
160 } // namespace internal
161 
162 template<typename Function1, typename Function2>
163 void Invoke(
164  Function1 func1,
165  Function2 func2,
166  const embb::mtapi::ExecutionPolicy& policy) {
167  internal::TaskWrapper<Function1> wrap1(func1, policy);
168  internal::TaskWrapper<Function2> wrap2(func2, policy);
169 }
170 
171 template<typename Function1, typename Function2, typename Function3>
172 void Invoke(
173  Function1 func1,
174  Function2 func2,
175  Function3 func3,
176  const embb::mtapi::ExecutionPolicy& policy) {
177  internal::TaskWrapper<Function1> wrap1(func1, policy);
178  internal::TaskWrapper<Function2> wrap2(func2, policy);
179  internal::TaskWrapper<Function3> wrap3(func3, policy);
180 }
181 
182 template<typename Function1, typename Function2, typename Function3,
183  typename Function4>
184  void Invoke(
185  Function1 func1,
186  Function2 func2,
187  Function3 func3,
188  Function4 func4,
189  const embb::mtapi::ExecutionPolicy& policy) {
190  internal::TaskWrapper<Function1> wrap1(func1, policy);
191  internal::TaskWrapper<Function2> wrap2(func2, policy);
192  internal::TaskWrapper<Function3> wrap3(func3, policy);
193  internal::TaskWrapper<Function4> wrap4(func4, policy);
194 }
195 
196 template<typename Function1, typename Function2, typename Function3,
197  typename Function4, typename Function5>
198  void Invoke(
199  Function1 func1,
200  Function2 func2,
201  Function3 func3,
202  Function4 func4,
203  Function5 func5,
204  const embb::mtapi::ExecutionPolicy& policy) {
205  internal::TaskWrapper<Function1> wrap1(func1, policy);
206  internal::TaskWrapper<Function2> wrap2(func2, policy);
207  internal::TaskWrapper<Function3> wrap3(func3, policy);
208  internal::TaskWrapper<Function4> wrap4(func4, policy);
209  internal::TaskWrapper<Function5> wrap5(func5, policy);
210 }
211 
212 template<typename Function1, typename Function2, typename Function3,
213  typename Function4, typename Function5, typename Function6>
214  void Invoke(
215  Function1 func1,
216  Function2 func2,
217  Function3 func3,
218  Function4 func4,
219  Function5 func5,
220  Function6 func6,
221  const embb::mtapi::ExecutionPolicy& policy) {
222  internal::TaskWrapper<Function1> wrap1(func1, policy);
223  internal::TaskWrapper<Function2> wrap2(func2, policy);
224  internal::TaskWrapper<Function3> wrap3(func3, policy);
225  internal::TaskWrapper<Function4> wrap4(func4, policy);
226  internal::TaskWrapper<Function5> wrap5(func5, policy);
227  internal::TaskWrapper<Function6> wrap6(func6, policy);
228 }
229 
230 template<typename Function1, typename Function2, typename Function3,
231  typename Function4, typename Function5, typename Function6,
232  typename Function7>
233  void Invoke(
234  Function1 func1,
235  Function2 func2,
236  Function3 func3,
237  Function4 func4,
238  Function5 func5,
239  Function6 func6,
240  Function7 func7,
241  const embb::mtapi::ExecutionPolicy& policy) {
242  internal::TaskWrapper<Function1> wrap1(func1, policy);
243  internal::TaskWrapper<Function2> wrap2(func2, policy);
244  internal::TaskWrapper<Function3> wrap3(func3, policy);
245  internal::TaskWrapper<Function4> wrap4(func4, policy);
246  internal::TaskWrapper<Function5> wrap5(func5, policy);
247  internal::TaskWrapper<Function6> wrap6(func6, policy);
248  internal::TaskWrapper<Function7> wrap7(func7, policy);
249 }
250 
251 template<typename Function1, typename Function2, typename Function3,
252  typename Function4, typename Function5, typename Function6,
253  typename Function7, typename Function8>
254  void Invoke(
255  Function1 func1,
256  Function2 func2,
257  Function3 func3,
258  Function4 func4,
259  Function5 func5,
260  Function6 func6,
261  Function7 func7,
262  Function8 func8,
263  const embb::mtapi::ExecutionPolicy& policy) {
264  internal::TaskWrapper<Function1> wrap1(func1, policy);
265  internal::TaskWrapper<Function2> wrap2(func2, policy);
266  internal::TaskWrapper<Function3> wrap3(func3, policy);
267  internal::TaskWrapper<Function4> wrap4(func4, policy);
268  internal::TaskWrapper<Function5> wrap5(func5, policy);
269  internal::TaskWrapper<Function6> wrap6(func6, policy);
270  internal::TaskWrapper<Function7> wrap7(func7, policy);
271  internal::TaskWrapper<Function8> wrap8(func8, policy);
272 }
273 
274 template<typename Function1, typename Function2, typename Function3,
275  typename Function4, typename Function5, typename Function6,
276  typename Function7, typename Function8, typename Function9>
277  void Invoke(
278  Function1 func1,
279  Function2 func2,
280  Function3 func3,
281  Function4 func4,
282  Function5 func5,
283  Function6 func6,
284  Function7 func7,
285  Function8 func8,
286  Function9 func9,
287  const embb::mtapi::ExecutionPolicy& policy) {
288  internal::TaskWrapper<Function1> wrap1(func1, policy);
289  internal::TaskWrapper<Function2> wrap2(func2, policy);
290  internal::TaskWrapper<Function3> wrap3(func3, policy);
291  internal::TaskWrapper<Function4> wrap4(func4, policy);
292  internal::TaskWrapper<Function5> wrap5(func5, policy);
293  internal::TaskWrapper<Function6> wrap6(func6, policy);
294  internal::TaskWrapper<Function7> wrap7(func7, policy);
295  internal::TaskWrapper<Function8> wrap8(func8, policy);
296  internal::TaskWrapper<Function9> wrap9(func9, policy);
297 }
298 
299 template<typename Function1, typename Function2, typename Function3,
300  typename Function4, typename Function5, typename Function6,
301  typename Function7, typename Function8, typename Function9,
302  typename Function10>
303  void Invoke(
304  Function1 func1,
305  Function2 func2,
306  Function3 func3,
307  Function4 func4,
308  Function5 func5,
309  Function6 func6,
310  Function7 func7,
311  Function8 func8,
312  Function9 func9,
313  Function10 func10,
314  const embb::mtapi::ExecutionPolicy& policy) {
315  internal::TaskWrapper<Function1> wrap1(func1, policy);
316  internal::TaskWrapper<Function2> wrap2(func2, policy);
317  internal::TaskWrapper<Function3> wrap3(func3, policy);
318  internal::TaskWrapper<Function4> wrap4(func4, policy);
319  internal::TaskWrapper<Function5> wrap5(func5, policy);
320  internal::TaskWrapper<Function6> wrap6(func6, policy);
321  internal::TaskWrapper<Function7> wrap7(func7, policy);
322  internal::TaskWrapper<Function8> wrap8(func8, policy);
323  internal::TaskWrapper<Function9> wrap9(func9, policy);
324  internal::TaskWrapper<Function10> wrap10(func10, policy);
325 }
326 
327 template<typename Function1, typename Function2>
328 void Invoke(
329  Function1 func1,
330  Function2 func2) {
331  Invoke(func1, func2, embb::mtapi::ExecutionPolicy());
332 }
333 template<typename Function1, typename Function2, typename Function3>
334 void Invoke(
335  Function1 func1,
336  Function2 func2,
337  Function3 func3) {
338  Invoke(func1, func2, func3, embb::mtapi::ExecutionPolicy());
339 }
340 
341 template<typename Function1, typename Function2, typename Function3,
342  typename Function4>
343 void Invoke(
344  Function1 func1,
345  Function2 func2,
346  Function3 func3,
347  Function4 func4) {
348  Invoke(func1, func2, func3, func4, embb::mtapi::ExecutionPolicy());
349 }
350 
351 template<typename Function1, typename Function2, typename Function3,
352  typename Function4, typename Function5>
353 void Invoke(
354  Function1 func1,
355  Function2 func2,
356  Function3 func3,
357  Function4 func4,
358  Function5 func5) {
359  Invoke(func1, func2, func3, func4, func5, embb::mtapi::ExecutionPolicy());
360 }
361 
362 template<typename Function1, typename Function2, typename Function3,
363  typename Function4, typename Function5, typename Function6>
364 void Invoke(
365  Function1 func1,
366  Function2 func2,
367  Function3 func3,
368  Function4 func4,
369  Function5 func5,
370  Function6 func6) {
371  Invoke(func1, func2, func3, func4, func5, func6,
373 }
374 
375 template<typename Function1, typename Function2, typename Function3,
376  typename Function4, typename Function5, typename Function6,
377  typename Function7>
378 void Invoke(
379  Function1 func1,
380  Function2 func2,
381  Function3 func3,
382  Function4 func4,
383  Function5 func5,
384  Function6 func6,
385  Function7 func7) {
386  Invoke(func1, func2, func3, func4, func5, func6, func7,
388 }
389 
390 template<typename Function1, typename Function2, typename Function3,
391  typename Function4, typename Function5, typename Function6,
392  typename Function7, typename Function8>
393 void Invoke(
394  Function1 func1,
395  Function2 func2,
396  Function3 func3,
397  Function4 func4,
398  Function5 func5,
399  Function6 func6,
400  Function7 func7,
401  Function8 func8) {
402  Invoke(func1, func2, func3, func4, func5, func6, func7, func8,
404 }
405 
406 template<typename Function1, typename Function2, typename Function3,
407  typename Function4, typename Function5, typename Function6,
408  typename Function7, typename Function8, typename Function9>
409 void Invoke(
410  Function1 func1,
411  Function2 func2,
412  Function3 func3,
413  Function4 func4,
414  Function5 func5,
415  Function6 func6,
416  Function7 func7,
417  Function8 func8,
418  Function9 func9) {
419  Invoke(func1, func2, func3, func4, func5, func6, func7, func8, func9,
421 }
422 
423 template<typename Function1, typename Function2, typename Function3,
424  typename Function4, typename Function5, typename Function6,
425  typename Function7, typename Function8, typename Function9,
426  typename Function10>
427 void Invoke(
428  Function1 func1,
429  Function2 func2,
430  Function3 func3,
431  Function4 func4,
432  Function5 func5,
433  Function6 func6,
434  Function7 func7,
435  Function8 func8,
436  Function9 func9,
437  Function10 func10) {
438  Invoke(func1, func2, func3, func4, func5, func6, func7, func8, func9, func10,
440 }
441 
442 #endif // else DOXYGEN
443 
444 } // namespace algorithms
445 } // namespace embb
446 
447 #endif // EMBB_ALGORITHMS_INVOKE_H_
Definition: lock_free_mpmc_queue.h:40
static Node & GetInstance()
Gets the instance of the runtime system.
Function< ReturnType,[Arg1,..., Arg5]> MakeFunction(ClassType &obj, ReturnType(ClassType::*func)([Arg1,..., Arg5]))
Wraps an object and a member function pointer into a Function.
mtapi_status_t Wait(mtapi_timeout_t timeout)
Waits for Task to finish for timeout milliseconds.
Definition: task.h:86
void Invoke(Function1 func1, Function2 func2,..., const embb::mtapi::ExecutionPolicy &policy)
Spawns two to ten function objects or embb::mtapi::Job at once and runs them in parallel using the gi...
Task Start(SMPFunction const &func)
Starts a new Task.
Definition: node.h:193
Represents a collection of Actions.
Definition: job.h:41
Wraps function pointers, member function pointers, and functors with up to five arguments.
Definition: function.h:94
Contains attributes of a Task.
Definition: task_attributes.h:42
Describes the execution policy of a parallel algorithm.
Definition: execution_policy.h:48
TaskAttributes & SetPolicy(ExecutionPolicy const &policy)
Sets the ExecutionPolicy of a Task.
Definition: task_attributes.h:114
embb::base::Function< void > InvokeFunctionType
Function type used by Invoke.
Definition: invoke.h:47
Provides information about the status of the currently running Task.
Definition: task_context.h:41
A Task represents a running Action of a specific Job.
Definition: task.h:41