Skip to content

Commit 2ffc305

Browse files
author
Radosław Cybulski
committed
Add calls to update resume_point
Add calls to update `resume_point` variable with location of next resume location to all `await_suspend` functions and `then` functions.
1 parent 13d5be4 commit 2ffc305

File tree

9 files changed

+58
-42
lines changed

9 files changed

+58
-42
lines changed

include/seastar/core/coroutine.hh

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030

3131
#ifndef SEASTAR_MODULE
3232
#include <coroutine>
33+
#include <source_location>
3334
#endif
3435

3536
namespace seastar {
@@ -144,7 +145,8 @@ public:
144145
}
145146

146147
template<typename U>
147-
void await_suspend(std::coroutine_handle<U> hndl) noexcept {
148+
void await_suspend(std::coroutine_handle<U> hndl, std::source_location sl = std::source_location::current()) noexcept {
149+
hndl.promise().update_resume_point(sl);
148150
if (!CheckPreempt || !_future.available()) {
149151
_future.set_coroutine(hndl.promise());
150152
} else {
@@ -169,7 +171,8 @@ public:
169171
}
170172

171173
template<typename U>
172-
void await_suspend(std::coroutine_handle<U> hndl) noexcept {
174+
void await_suspend(std::coroutine_handle<U> hndl, std::source_location sl = std::source_location::current()) noexcept {
175+
hndl.promise().update_resume_point(sl);
173176
if (!CheckPreempt || !_future.available()) {
174177
_future.set_coroutine(hndl.promise());
175178
} else {

include/seastar/core/future.hh

Lines changed: 33 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include <stdexcept>
3232
#include <type_traits>
3333
#include <utility>
34+
#include <source_location>
3435
#endif
3536

3637
#include <seastar/core/task.hh>
@@ -1231,13 +1232,14 @@ private:
12311232
future_base::schedule(tws, &tws->_state);
12321233
}
12331234
template <typename Pr, typename Func, typename Wrapper>
1234-
void schedule(Pr&& pr, Func&& func, Wrapper&& wrapper) noexcept {
1235+
void schedule(Pr&& pr, Func&& func, Wrapper&& wrapper, std::source_location sl) noexcept {
12351236
// If this new throws a std::bad_alloc there is nothing that
12361237
// can be done about it. The corresponding future is not ready
12371238
// and we cannot break the chain. Since this function is
12381239
// noexcept, it will call std::terminate if new throws.
12391240
memory::scoped_critical_alloc_section _;
12401241
auto tws = new continuation<Pr, Func, Wrapper, T>(std::move(pr), std::move(func), std::move(wrapper));
1242+
tws->update_resume_point(sl);
12411243
// In a debug build we schedule ready futures, but not in
12421244
// other build modes.
12431245
#ifdef SEASTAR_DEBUG
@@ -1355,9 +1357,9 @@ public:
13551357
requires std::invocable<Func, T>
13561358
|| (std::same_as<void, T> && std::invocable<Func>)
13571359
Result
1358-
then(Func&& func) noexcept {
1360+
then(Func&& func, std::source_location sl = std::source_location::current()) noexcept {
13591361
#ifndef SEASTAR_TYPE_ERASE_MORE
1360-
return then_impl(std::move(func));
1362+
return then_impl(std::move(func), sl);
13611363
#else
13621364
using func_type = typename internal::future_result<Func, T>::func_type;
13631365
noncopyable_function<func_type> ncf;
@@ -1367,7 +1369,7 @@ public:
13671369
return futurize_invoke(func, std::forward<decltype(args)>(args)...);
13681370
});
13691371
}
1370-
return then_impl(std::move(ncf));
1372+
return then_impl(std::move(ncf), sl);
13711373
#endif
13721374
}
13731375

@@ -1393,18 +1395,18 @@ public:
13931395
template <typename Func, typename Result = futurize_t<internal::result_of_apply_t<Func, T>>>
13941396
requires ::seastar::CanApplyTuple<Func, T>
13951397
Result
1396-
then_unpack(Func&& func) noexcept {
1398+
then_unpack(Func&& func, std::source_location sl = std::source_location::current()) noexcept {
13971399
return then([func = std::forward<Func>(func)] (T&& tuple) mutable {
13981400
// sizeof...(tuple) is required to be 1
13991401
return std::apply(func, std::move(tuple));
1400-
});
1402+
}, sl);
14011403
}
14021404

14031405
private:
14041406

14051407
// Keep this simple so that Named Return Value Optimization is used.
14061408
template <typename Func, typename Result>
1407-
Result then_impl_nrvo(Func&& func) noexcept {
1409+
Result then_impl_nrvo(Func&& func, std::source_location sl) noexcept {
14081410
using futurator = futurize<internal::future_result_t<Func, T>>;
14091411
typename futurator::type fut(future_for_get_promise_marker{});
14101412
using pr_type = decltype(fut.get_promise());
@@ -1419,13 +1421,13 @@ private:
14191421
return internal::future_invoke(func, std::move(state).get_value());
14201422
});
14211423
}
1422-
});
1424+
}, sl);
14231425
return fut;
14241426
}
14251427

14261428
template <typename Func, typename Result = futurize_t<internal::future_result_t<Func, T>>>
14271429
Result
1428-
then_impl(Func&& func) noexcept {
1430+
then_impl(Func&& func, std::source_location sl) noexcept {
14291431
#ifndef SEASTAR_DEBUG
14301432
using futurator = futurize<internal::future_result_t<Func, T>>;
14311433
if (failed()) {
@@ -1434,7 +1436,7 @@ private:
14341436
return futurator::invoke(std::forward<Func>(func), get_available_state_ref().take_value());
14351437
}
14361438
#endif
1437-
return then_impl_nrvo<Func, Result>(std::forward<Func>(func));
1439+
return then_impl_nrvo<Func, Result>(std::forward<Func>(func), sl);
14381440
}
14391441

14401442
public:
@@ -1455,23 +1457,23 @@ public:
14551457
/// to the eventual value of this future.
14561458
template <std::invocable<future> Func, typename FuncResult = std::invoke_result_t<Func, future>>
14571459
futurize_t<FuncResult>
1458-
then_wrapped(Func&& func) & noexcept {
1459-
return then_wrapped_maybe_erase<false, FuncResult>(std::forward<Func>(func));
1460+
then_wrapped(Func&& func, std::source_location sl = std::source_location::current()) & noexcept {
1461+
return then_wrapped_maybe_erase<false, FuncResult>(std::forward<Func>(func), sl);
14601462
}
14611463

14621464
template <std::invocable<future&&> Func, typename FuncResult = std::invoke_result_t<Func, future&&>>
14631465
futurize_t<FuncResult>
1464-
then_wrapped(Func&& func) && noexcept {
1465-
return then_wrapped_maybe_erase<true, FuncResult>(std::forward<Func>(func));
1466+
then_wrapped(Func&& func, std::source_location sl = std::source_location::current()) && noexcept {
1467+
return then_wrapped_maybe_erase<true, FuncResult>(std::forward<Func>(func), sl);
14661468
}
14671469

14681470
private:
14691471

14701472
template <bool AsSelf, typename FuncResult, typename Func>
14711473
futurize_t<FuncResult>
1472-
then_wrapped_maybe_erase(Func&& func) noexcept {
1474+
then_wrapped_maybe_erase(Func&& func, std::source_location sl) noexcept {
14731475
#ifndef SEASTAR_TYPE_ERASE_MORE
1474-
return then_wrapped_common<AsSelf, FuncResult>(std::forward<Func>(func));
1476+
return then_wrapped_common<AsSelf, FuncResult>(std::forward<Func>(func), sl);
14751477
#else
14761478
using futurator = futurize<FuncResult>;
14771479
using WrapFuncResult = typename futurator::type;
@@ -1482,29 +1484,29 @@ private:
14821484
return futurator::invoke(func, std::move(f));
14831485
});
14841486
}
1485-
return then_wrapped_common<AsSelf, WrapFuncResult>(std::move(ncf));
1487+
return then_wrapped_common<AsSelf, WrapFuncResult>(std::move(ncf), sl);
14861488
#endif
14871489
}
14881490

14891491
// Keep this simple so that Named Return Value Optimization is used.
14901492
template <typename FuncResult, typename Func>
14911493
futurize_t<FuncResult>
1492-
then_wrapped_nrvo(Func&& func) noexcept {
1494+
then_wrapped_nrvo(Func&& func, std::source_location sl) noexcept {
14931495
using futurator = futurize<FuncResult>;
14941496
typename futurator::type fut(future_for_get_promise_marker{});
14951497
using pr_type = decltype(fut.get_promise());
14961498
schedule(fut.get_promise(), std::move(func), [](pr_type&& pr, Func& func, future_state&& state) {
14971499
futurator::satisfy_with_result_of(std::move(pr), [&func, &state] {
14981500
return func(future(std::move(state)));
14991501
});
1500-
});
1502+
}, sl);
15011503
return fut;
15021504
}
15031505

15041506

15051507
template <bool AsSelf, typename FuncResult, typename Func>
15061508
futurize_t<FuncResult>
1507-
then_wrapped_common(Func&& func) noexcept {
1509+
then_wrapped_common(Func&& func, std::source_location sl) noexcept {
15081510
#ifndef SEASTAR_DEBUG
15091511
using futurator = futurize<FuncResult>;
15101512
if (available()) {
@@ -1518,7 +1520,7 @@ private:
15181520
}
15191521
}
15201522
#endif
1521-
return then_wrapped_nrvo<FuncResult, Func>(std::forward<Func>(func));
1523+
return then_wrapped_nrvo<FuncResult, Func>(std::forward<Func>(func), sl);
15221524
}
15231525

15241526
void forward_to(internal::promise_base_with_type<T>&& pr) noexcept {
@@ -1570,8 +1572,8 @@ public:
15701572
* nested will be propagated.
15711573
*/
15721574
template <std::invocable Func>
1573-
future<T> finally(Func&& func) noexcept {
1574-
return then_wrapped(finally_body<Func, is_future<std::invoke_result_t<Func>>::value>(std::forward<Func>(func)));
1575+
future<T> finally(Func&& func, std::source_location sl = std::source_location::current()) noexcept {
1576+
return then_wrapped(finally_body<Func, is_future<std::invoke_result_t<Func>>::value>(std::forward<Func>(func)), sl);
15751577
}
15761578

15771579

@@ -1617,24 +1619,24 @@ public:
16171619
///
16181620
/// Terminates the entire program is this future resolves
16191621
/// to an exception. Use with caution.
1620-
future<> or_terminate() noexcept {
1622+
future<> or_terminate(std::source_location sl = std::source_location::current()) noexcept {
16211623
return then_wrapped([] (auto&& f) {
16221624
try {
16231625
f.get();
16241626
} catch (...) {
16251627
engine_exit(std::current_exception());
16261628
}
1627-
});
1629+
}, sl);
16281630
}
16291631

16301632
/// \brief Discards the value carried by this future.
16311633
///
16321634
/// Converts the future into a no-value \c future<>, by
16331635
/// ignoring any result. Exceptions are propagated unchanged.
1634-
future<> discard_result() noexcept {
1636+
future<> discard_result(std::source_location sl = std::source_location::current()) noexcept {
16351637
// We need the generic variadic lambda, below, because then() behaves differently
16361638
// when value_type is when_all_succeed_tuple
1637-
return then([] (auto&&...) {});
1639+
return then([] (auto&&...) {}, sl);
16381640
}
16391641

16401642
/// \brief Handle the exception carried by this future.
@@ -1655,15 +1657,15 @@ public:
16551657
|| (std::tuple_size_v<tuple_type> == 0 && std::is_invocable_r_v<void, Func, std::exception_ptr>)
16561658
|| (std::tuple_size_v<tuple_type> == 1 && std::is_invocable_r_v<T, Func, std::exception_ptr>)
16571659
|| (std::tuple_size_v<tuple_type> > 1 && std::is_invocable_r_v<tuple_type ,Func, std::exception_ptr>)
1658-
future<T> handle_exception(Func&& func) noexcept {
1660+
future<T> handle_exception(Func&& func, std::source_location sl = std::source_location::current()) noexcept {
16591661
return then_wrapped([func = std::forward<Func>(func)]
16601662
(auto&& fut) mutable -> future<T> {
16611663
if (!fut.failed()) {
16621664
return make_ready_future<T>(fut.get());
16631665
} else {
16641666
return futurize_invoke(func, fut.get_exception());
16651667
}
1666-
});
1668+
}, sl);
16671669
}
16681670

16691671
/// \brief Handle the exception of a certain type carried by this future.
@@ -1677,7 +1679,7 @@ public:
16771679
/// If exception, that future holds, does not match func parameter type
16781680
/// it is propagated as is.
16791681
template <typename Func>
1680-
future<T> handle_exception_type(Func&& func) noexcept {
1682+
future<T> handle_exception_type(Func&& func, std::source_location sl = std::source_location::current()) noexcept {
16811683
using trait = function_traits<Func>;
16821684
static_assert(trait::arity == 1, "func can take only one parameter");
16831685
using ex_type = typename trait::template arg<0>::type;
@@ -1688,7 +1690,7 @@ public:
16881690
} catch(ex_type& ex) {
16891691
return futurize_invoke(func, ex);
16901692
}
1691-
});
1693+
}, sl);
16921694
}
16931695

16941696
/// \brief Ignore any result hold by this future

include/seastar/coroutine/all.hh

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,9 @@ private:
161161
return (... && futures.available());
162162
}, state._futures);
163163
}
164-
void await_suspend(coroutine_handle_t h) {
164+
template <typename U>
165+
void await_suspend(std::coroutine_handle<U> h, std::source_location sl = std::source_location::current()) {
166+
h.promise().update_resume_point(sl);
165167
when_ready = h;
166168
process<0>();
167169
}

include/seastar/coroutine/as_future.hh

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#pragma once
2323

2424
#include <seastar/core/coroutine.hh>
25+
#include <source_location>
2526

2627
namespace seastar {
2728

@@ -42,7 +43,8 @@ public:
4243
}
4344

4445
template<typename U>
45-
void await_suspend(std::coroutine_handle<U> hndl) noexcept {
46+
void await_suspend(std::coroutine_handle<U> hndl, std::source_location sl = std::source_location::current()) noexcept {
47+
hndl.promise().update_resume_point(sl);
4648
if (!CheckPreempt || !_future.available()) {
4749
_future.set_coroutine(hndl.promise());
4850
} else {

include/seastar/coroutine/exception.hh

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include <seastar/core/future.hh>
2525
#include <coroutine>
2626
#include <exception>
27+
#include <source_location>
2728

2829
namespace seastar {
2930

@@ -42,7 +43,8 @@ struct exception_awaiter {
4243
}
4344

4445
template<typename U>
45-
void await_suspend(std::coroutine_handle<U> hndl) noexcept {
46+
void await_suspend(std::coroutine_handle<U> hndl, std::source_location sl = std::source_location::current()) noexcept {
47+
hndl.promise().update_resume_point(sl);
4648
hndl.promise().set_exception(std::move(eptr));
4749
hndl.destroy();
4850
}

include/seastar/coroutine/generator.hh

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ public:
141141
return _future.available();
142142
}
143143

144-
coroutine_handle<> await_suspend(coroutine_handle<promise_type> coro) noexcept;
144+
coroutine_handle<> await_suspend(coroutine_handle<promise_type> coro, std::source_location sl = std::source_location::current()) noexcept;
145145
void await_resume() noexcept { }
146146
};
147147

@@ -260,7 +260,8 @@ public:
260260
}
261261

262262
template<typename Promise>
263-
void await_suspend(coroutine_handle<Promise> coro) noexcept {
263+
void await_suspend(coroutine_handle<Promise> coro, std::source_location sl = std::source_location::current()) noexcept {
264+
coro.promise().update_resume_point(sl);
264265
auto& current_task = coro.promise();
265266
if (_next_value_future.available()) {
266267
seastar::schedule(&current_task);
@@ -527,7 +528,8 @@ auto generator_buffered_promise<T, Container>::get_return_object() noexcept -> g
527528

528529
template<typename T, template <typename> class Container>
529530
coroutine_handle<> yield_awaiter<T, Container>::await_suspend(
530-
coroutine_handle<generator_buffered_promise<T, Container>> coro) noexcept {
531+
coroutine_handle<generator_buffered_promise<T, Container>> coro, std::source_location sl) noexcept {
532+
coro.promise().update_resume_point(sl);
531533
if (_future.available()) {
532534
auto& current_task = coro.promise();
533535
seastar::schedule(&current_task);

include/seastar/coroutine/maybe_yield.hh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ struct maybe_yield_awaiter final {
3535
}
3636

3737
template <typename T>
38-
void await_suspend(std::coroutine_handle<T> h) {
38+
void await_suspend(std::coroutine_handle<T> h, std::source_location sl = std::source_location::current()) noexcept {
39+
h.promise().update_resume_point(sl);
3940
schedule(&h.promise());
4041
}
4142

include/seastar/coroutine/parallel_for_each.hh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,8 @@ public:
152152
}
153153

154154
template<typename T>
155-
void await_suspend(std::coroutine_handle<T> h) {
155+
void await_suspend(std::coroutine_handle<T> h, std::source_location sl = std::source_location::current()) noexcept {
156+
h.promise().update_resume_point(sl);
156157
_when_ready = h;
157158
_waiting_task = &h.promise();
158159
resume_or_set_callback();

include/seastar/coroutine/switch_to.hh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,8 @@ public:
7070
}
7171

7272
template<typename T>
73-
void await_suspend(std::coroutine_handle<T> hndl) noexcept {
73+
void await_suspend(std::coroutine_handle<T> hndl, std::source_location sl = std::source_location::current()) noexcept {
74+
hndl.promise().update_resume_point(sl);
7475
auto& t = hndl.promise();
7576
t.set_scheduling_group(_switch_to_sg);
7677
_task = &t;

0 commit comments

Comments
 (0)