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
21namespace marl {
22
23namespace detail {
24
25MARL_NO_EXPORT inline void parallelizeChain(WaitGroup&) {}
26
27template <typename F, typename... L>
28MARL_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.
51template <typename F0, typename... FN>
52MARL_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