@@ -14,12 +14,15 @@ namespace {
1414
1515struct global_allocator {
1616
17- struct empty {};
17+ struct empty {
18+ auto operator ==(empty const &) const -> bool = default ;
19+ };
1820
1921 constexpr static auto push (std::size_t sz) -> void * { return ::operator new (sz); }
2022 constexpr static auto pop (void *p, std::size_t sz) noexcept -> void { ::operator delete (p, sz); }
2123 constexpr static auto checkpoint () noexcept -> empty { return {}; }
22- constexpr static auto switch_to (empty) noexcept -> void {}
24+ constexpr static auto release () noexcept -> void {}
25+ constexpr static auto acquire (empty) noexcept -> void {}
2326};
2427
2528static_assert (lf::stack_allocator<global_allocator>);
@@ -37,8 +40,8 @@ struct linear_allocator {
3740 constexpr auto pop (void *p, std::size_t ) noexcept -> void { ptr = static_cast <std::byte *>(p); }
3841
3942 constexpr auto checkpoint () noexcept -> std::byte * { return data.get (); }
40-
41- constexpr static auto switch_to (std::byte *) noexcept -> void {}
43+ constexpr auto release () noexcept -> void {}
44+ constexpr auto acquire (std::byte *) noexcept -> void {}
4245};
4346
4447static_assert (lf::stack_allocator<linear_allocator>);
@@ -57,10 +60,14 @@ constexpr auto no_await = [](this auto fib, std::int64_t *ret, std::int64_t n) -
5760
5861 auto t1 = fib (&lhs, n - 1 );
5962 t1.promise ->frame .kind = lf::category::root;
63+ t1.promise ->frame .stack_ckpt = lf::thread_context<T>->alloc ().checkpoint ();
64+ t1.promise ->frame .cancel = nullptr ;
6065 t1.promise ->handle ().resume ();
6166
6267 auto t2 = fib (&rhs, n - 2 );
6368 t2.promise ->frame .kind = lf::category::root;
69+ t2.promise ->frame .stack_ckpt = lf::thread_context<T>->alloc ().checkpoint ();
70+ t2.promise ->frame .cancel = nullptr ;
6471 t2.promise ->handle ().resume ();
6572
6673 *ret = lhs + rhs;
@@ -97,7 +104,7 @@ constexpr auto ret = [](this auto fib, std::int64_t n) -> lf::task<std::int64_t,
97104 co_return lhs + rhs;
98105};
99106
100- template <typename T>
107+ template <typename T, bool Join = false >
101108constexpr auto fork_call = [](this auto fib, std::int64_t n) -> lf::task<std::int64_t , T> {
102109 if (n < 2 ) {
103110 co_return n;
@@ -109,6 +116,10 @@ constexpr auto fork_call = [](this auto fib, std::int64_t n) -> lf::task<std::in
109116 co_await lf::fork (&rhs, fib, n - 2 );
110117 co_await lf::call (&lhs, fib, n - 1 );
111118
119+ if constexpr (Join) {
120+ co_await lf::join ();
121+ }
122+
112123 co_return lhs + rhs;
113124};
114125
@@ -138,11 +149,15 @@ void fib(benchmark::State &state) {
138149 if constexpr (requires { Fn (&result, n); }) {
139150 auto task = Fn (&result, n);
140151 task.promise ->frame .kind = lf::category::root;
152+ task.promise ->frame .cancel = nullptr ;
153+ task.promise ->frame .stack_ckpt = lf::thread_context<U>->alloc ().checkpoint ();
141154 task.promise ->handle ().resume ();
142155 } else {
143156 auto task = Fn (n);
144157 task.promise ->frame .kind = lf::category::root;
158+ task.promise ->frame .cancel = nullptr ;
145159 task.promise ->return_address = &result;
160+ task.promise ->frame .stack_ckpt = lf::thread_context<U>->alloc ().checkpoint ();
146161 task.promise ->handle ().resume ();
147162 }
148163
@@ -184,9 +199,21 @@ BENCHMARK(fib<ret<linear_alloc>, linear_alloc>)->Name("base/libfork/fib/bump/ret
184199BENCHMARK (fib<fork_call<linear_alloc>, linear_alloc>)->Name(" test/libfork/fib/vector_ctx" )->Arg(fib_test);
185200BENCHMARK (fib<fork_call<linear_alloc>, linear_alloc>)->Name(" base/libfork/fib/vector_ctx" )->Arg(fib_base);
186201
202+ // Same as above but with join.
203+ BENCHMARK (fib<fork_call<linear_alloc, true >, linear_alloc>)
204+ ->Name(" test/libfork/fib/vector_ctx/join" )
205+ ->Arg(fib_test);
206+ BENCHMARK (fib<fork_call<linear_alloc, true >, linear_alloc>)
207+ ->Name(" base/libfork/fib/vector_ctx/join" )
208+ ->Arg(fib_base);
209+
187210using A = poly_vector_ctx<linear_allocator>;
188211using B = lf::polymorphic_context<linear_allocator>;
189212
190213// Same as above but with polymorphic contexts.
191214BENCHMARK (fib<fork_call<B>, A, B>)->Name(" test/libfork/fib/poly_vector_ctx" )->Arg(fib_test);
192215BENCHMARK (fib<fork_call<B>, A, B>)->Name(" base/libfork/fib/poly_vector_ctx" )->Arg(fib_base);
216+
217+ // Same as above but with join.
218+ BENCHMARK (fib<fork_call<B, true >, A, B>)->Name(" test/libfork/fib/poly_vector_ctx/join" )->Arg(fib_test);
219+ BENCHMARK (fib<fork_call<B, true >, A, B>)->Name(" base/libfork/fib/poly_vector_ctx/join" )->Arg(fib_base);
0 commit comments