• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2020 The Marl Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef marl_parallelize_h
16 #define marl_parallelize_h
17 
18 #include "scheduler.h"
19 #include "waitgroup.h"
20 
21 namespace marl {
22 
23 namespace detail {
24 
parallelizeChain(WaitGroup &)25 MARL_NO_EXPORT inline void parallelizeChain(WaitGroup&) {}
26 
27 template <typename F, typename... L>
parallelizeChain(WaitGroup & wg,F && f,L &&...l)28 MARL_NO_EXPORT inline void parallelizeChain(WaitGroup& wg, F&& f, L&&... l) {
29   schedule([=] {
30     f();
31     wg.done();
32   });
33   parallelizeChain(wg, std::forward<L>(l)...);
34 }
35 
36 }  // namespace detail
37 
38 // parallelize() invokes all the function parameters, potentially concurrently,
39 // and waits for them all to complete before returning.
40 //
41 // Each function must take no parameters.
42 //
43 // parallelize() does the following:
44 //   (1) Schedules the function parameters in the parameter pack fn.
45 //   (2) Calls f0 on the current thread.
46 //   (3) Once f0 returns, waits for the scheduled functions in fn to all
47 //   complete.
48 // As the fn functions are scheduled before running f0, it is recommended to
49 // pass the function that'll take the most time as the first argument. That way
50 // you'll be more likely to avoid the cost of a fiber switch.
51 template <typename F0, typename... FN>
parallelize(F0 && f0,FN &&...fn)52 MARL_NO_EXPORT inline void parallelize(F0&& f0, FN&&... fn) {
53   WaitGroup wg(sizeof...(FN));
54   // Schedule all the functions in fn.
55   detail::parallelizeChain(wg, std::forward<FN>(fn)...);
56   // While we wait for fn to complete, run the first function on this thread.
57   f0();
58   wg.wait();
59 }
60 
61 }  // namespace marl
62 
63 #endif  // marl_parallelize_h
64