proxygen
composition_2.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2018-present Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #include <algorithm>
17 #include <cassert>
18 #include <iostream>
19 #include <vector>
20 
22 
26 
27 using namespace folly::pushmi::aliases;
28 
29 struct f_t {};
30 f_t f() {
31  return {};
32 }
33 struct g_t {};
34 g_t g(f_t) {
35  return {};
36 }
37 
38 // these expressions are read backward, bottom-right to top-left
39 template <class CPUExecutor, class IOExecutor>
40 void lisp(CPUExecutor cpu, IOExecutor io) {
41  // f on cpu - g on cpu (implicit: a single task on the cpu executor runs all
42  // the functions)
43  op::submit([](g_t) {})(op::transform([](f_t ft) { return g(ft); })(
44  op::transform([](auto) { return f(); })(cpu)));
45 
46  // f on cpu - g on cpu (explicit: the first cpu task runs f and a second cpu
47  // task runs g)
48  op::submit([](g_t) {})(op::transform([](f_t ft) { return g(ft); })(
49  op::via(mi::strands(cpu))(op::transform([](auto) { return f(); })(cpu))));
50 
51  // f on io - g on cpu
52  op::submit([](g_t) {})(op::transform([](f_t ft) { return g(ft); })(
53  op::via(mi::strands(cpu))(op::transform([](auto) { return f(); })(io))));
54 }
55 
56 template <class CPUExecutor, class IOExecutor>
57 void sugar(CPUExecutor cpu, IOExecutor io) {
58  // f on cpu - g on cpu (implicit: a single task on the cpu executor runs all
59  // the functions)
60  cpu | op::transform([](auto) { return f(); }) |
61  op::transform([](f_t ft) { return g(ft); }) | op::submit([](g_t) {});
62 
63  // f on cpu - g on cpu (explicit: the first cpu task runs f and a second cpu
64  // task runs g)
65  cpu | op::transform([](auto) { return f(); }) | op::via(mi::strands(cpu)) |
66  op::transform([](f_t ft) { return g(ft); }) | op::submit([](g_t) {});
67 
68  // f on io - g on cpu
69  io | op::transform([](auto) { return f(); }) | op::via(mi::strands(cpu)) |
70  op::transform([](f_t ft) { return g(ft); }) | op::submit([](g_t) {});
71 }
72 
73 template <class CPUExecutor, class IOExecutor>
74 void pipe(CPUExecutor cpu, IOExecutor io) {
75  // f on cpu - g on cpu (implicit: a single task on the cpu executor runs all
76  // the functions)
77  mi::pipe(
78  cpu,
79  op::transform([](auto) { return f(); }),
80  op::transform([](f_t ft) { return g(ft); }),
81  op::submit([](g_t) {}));
82 
83  // f on cpu - g on cpu (explicit: the first cpu task runs f and a second cpu
84  // task runs g)
85  mi::pipe(
86  cpu,
87  op::transform([](auto) { return f(); }),
88  op::via(mi::strands(cpu)),
89  op::transform([](f_t ft) { return g(ft); }),
90  op::submit([](g_t) {}));
91 
92  // f on io - g on cpu
93  mi::pipe(
94  io,
95  op::transform([](auto) { return f(); }),
96  op::via(mi::strands(cpu)),
97  op::transform([](f_t ft) { return g(ft); }),
98  op::submit([](g_t) {}));
99 }
100 
101 int main() {
102  mi::pool cpuPool{std::max(1u, std::thread::hardware_concurrency())};
103  mi::pool ioPool{std::max(1u, std::thread::hardware_concurrency())};
104 
105  lisp(cpuPool.executor(), ioPool.executor());
106  sugar(cpuPool.executor(), ioPool.executor());
107  pipe(cpuPool.executor(), ioPool.executor());
108 
109  ioPool.wait();
110  cpuPool.wait();
111 
112  std::cout << "OK" << std::endl;
113 }
PUSHMI_INLINE_VAR constexpr struct folly::pushmi::pipe_fn pipe
int main()
requires Invocable< ExecutorFactory & > &&Executor< invoke_result_t< ExecutorFactory & > > &&ConcurrentSequence< invoke_result_t< ExecutorFactory & > > auto strands(ExecutorFactory ef)
Definition: strand.h:246
LogLevel max
Definition: LogLevel.cpp:31
PUSHMI_INLINE_VAR constexpr detail::transform_fn transform
Definition: transform.h:158
PUSHMI_INLINE_VAR constexpr detail::via_fn via
Definition: via.h:166
f_t f()
void sugar(CPUExecutor cpu, IOExecutor io)
g_t g(f_t)
void lisp(CPUExecutor cpu, IOExecutor io)
void pipe(CPUExecutor cpu, IOExecutor io)