diff --git a/tests/perf/future_util_perf.cc b/tests/perf/future_util_perf.cc index d02d25a26a..27e2abf591 100644 --- a/tests/perf/future_util_perf.cc +++ b/tests/perf/future_util_perf.cc @@ -24,6 +24,7 @@ #include #include +#include #include #include #include @@ -82,6 +83,25 @@ struct chain { co_await std::move(w); } } + + [[gnu::noinline]] + future do_await_as_future(future w, int depth = scale) { + if (depth > 0) { + auto fut = co_await coroutine::as_future(do_await_as_future(std::move(w), depth - 1)); + if (fut.failed()) { + co_await seastar::coroutine::return_exception_ptr(fut.get_exception()); + } + value += 1; + perf_tests::do_not_optimize(value); + co_return fut.get(); + } else { + auto fut = co_await coroutine::as_future(std::move(w)); + if (fut.failed()) { + co_await seastar::coroutine::return_exception_ptr(fut.get_exception()); + } + co_return fut.get(); + } + } }; PERF_TEST_F(chain, then_value) @@ -100,6 +120,14 @@ PERF_TEST_F(chain, await_value) return f.then([] { return scale; }); } +PERF_TEST_F(chain, await_value_as_future) +{ + promise p; + auto f = do_await_as_future(p.get_future()); + p.set_value(std::nullopt); + return f.then([](std::nullopt_t) { return scale; }); +} + PERF_TEST_F(chain, then_exception) { promise<> p; @@ -122,6 +150,17 @@ PERF_TEST_F(chain, await_exception) }); } +PERF_TEST_F(chain, await_exception_as_future) +{ + promise p; + auto f = do_await_as_future(p.get_future()); + p.set_exception(std::runtime_error("")); + return f.then_wrapped([] (auto x) { + x.ignore_ready_future(); + return scale; + }); +} + PERF_TEST_F(parallel_for_each, immediate_1) { auto&& begin = range.begin();