Skip to content

Commit a8412a4

Browse files
committed
add event, fix shared-task
1 parent 1562a96 commit a8412a4

File tree

4 files changed

+23
-25
lines changed

4 files changed

+23
-25
lines changed

runtime-light/coroutine/async-stack-methods.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <utility>
1111

1212
#include "runtime-light/coroutine/coroutine-state.h"
13+
#include "runtime-light/stdlib/diagnostics/logs.h"
1314

1415
namespace kphp::coro {
1516

@@ -19,11 +20,13 @@ namespace kphp::coro {
1920
* capturing one of the stack frames in the synchronous stack trace and jump between parts of the async_stack.
2021
*/
2122
[[clang::noinline]] inline void resume_with_new_root(std::coroutine_handle<> handle, async_stack_root* new_async_stack_root) noexcept {
23+
kphp::log::assertion(new_async_stack_root != nullptr);
2224
auto& coroutine_st{CoroutineInstanceState::get()};
23-
auto* previous_stack_root = coroutine_st.current_async_stack_root;
24-
new_async_stack_root->next_async_stack_root = coroutine_st.current_async_stack_root;
25+
auto* previous_stack_root{coroutine_st.current_async_stack_root};
2526

27+
new_async_stack_root->next_async_stack_root = coroutine_st.current_async_stack_root;
2628
new_async_stack_root->stop_sync_stack_frame = reinterpret_cast<stack_frame*>(STACK_FRAME_ADDRESS);
29+
2730
coroutine_st.current_async_stack_root = new_async_stack_root;
2831
handle.resume();
2932
coroutine_st.current_async_stack_root = previous_stack_root;

runtime-light/coroutine/detail/when-any.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,6 @@ class when_any_task_promise_base : public kphp::coro::async_stack_element {
194194
auto start(when_any_latch& latch, void* return_address) noexcept {
195195
m_latch = std::addressof(latch);
196196

197-
198197
kphp::coro::async_stack_root root{};
199198
auto& async_stack_frame{get_async_stack_frame()};
200199
// initialize when_all_task's async stack frame and make it the top frame

runtime-light/coroutine/event.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,15 @@ class event {
2424
event& m_event;
2525
bool m_suspended{};
2626
std::coroutine_handle<> m_awaiting_coroutine;
27-
kphp::coro::async_stack_root& m_async_stack_root;
27+
kphp::coro::async_stack_root* m_async_stack_root;
2828
kphp::coro::async_stack_frame* m_caller_async_stack_frame{};
2929

3030
awaiter* m_next{};
3131
awaiter* m_prev{};
3232

3333
explicit awaiter(event& event) noexcept
3434
: m_event(event),
35-
m_async_stack_root(CoroutineInstanceState::get().base_coroutine_stack_root) {}
35+
m_async_stack_root(CoroutineInstanceState::get().current_async_stack_root) {}
3636

3737
awaiter(const awaiter&) = delete;
3838
awaiter(awaiter&&) = delete;
@@ -85,7 +85,7 @@ inline auto event::awaiter::await_ready() const noexcept -> bool {
8585
template<std::derived_from<kphp::coro::async_stack_element> caller_promise_type>
8686
auto event::awaiter::await_suspend(std::coroutine_handle<caller_promise_type> awaiting_coroutine) noexcept -> void {
8787
// save caller's async stack frame
88-
m_caller_async_stack_frame = m_async_stack_root.top_async_stack_frame;
88+
m_caller_async_stack_frame = m_async_stack_root->top_async_stack_frame;
8989

9090
m_suspended = true;
9191
m_awaiting_coroutine = awaiting_coroutine;
@@ -105,7 +105,7 @@ inline auto event::awaiter::await_resume() noexcept -> void {
105105
if (std::exchange(m_suspended, false)) {
106106
// restore caller's async stack frame if it was suspended
107107
kphp::log::assertion(m_caller_async_stack_frame != nullptr);
108-
m_async_stack_root.top_async_stack_frame = std::exchange(m_caller_async_stack_frame, nullptr);
108+
m_async_stack_root->top_async_stack_frame = std::exchange(m_caller_async_stack_frame, nullptr);
109109
}
110110
}
111111

runtime-light/coroutine/shared-task.h

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,12 @@ struct promise_base : kphp::coro::async_stack_element {
5252
// read the m_next pointer before resuming the coroutine
5353
// since resuming the coroutine may destroy the shared_task_waiter value
5454
auto* next{awaiter->m_next};
55-
auto* async_stack_root{promise.get_async_stack_frame().async_stack_root};
56-
kphp::coro::resume_with_new_root(awaiter->m_continuation, async_stack_root);
55+
auto& async_stack_frame{promise.get_async_stack_frame()};
56+
57+
kphp::coro::async_stack_root root{};
58+
root.top_async_stack_frame = std::addressof(async_stack_frame);
59+
async_stack_frame.async_stack_root = std::addressof(root);
60+
kphp::coro::resume_with_new_root(awaiter->m_continuation, std::addressof(root));
5761
awaiter = next;
5862
}
5963
// return last awaiter's coroutine_handle to allow it to potentially be compiled as a tail-call
@@ -100,8 +104,12 @@ struct promise_base : kphp::coro::async_stack_element {
100104
if (m_awaiters == NOT_STARTED_VAL) {
101105
m_awaiters = STARTED_NO_WAITERS_VAL;
102106
const auto& handle{std::coroutine_handle<promise_type>::from_promise(*static_cast<promise_type*>(this))};
103-
auto* async_stack_root{get_async_stack_frame().async_stack_root};
104-
kphp::coro::resume_with_new_root(handle, async_stack_root);
107+
auto& async_stack_frame{get_async_stack_frame()};
108+
109+
kphp::coro::async_stack_root root{};
110+
root.top_async_stack_frame = std::addressof(async_stack_frame);
111+
async_stack_frame.async_stack_root = std::addressof(root);
112+
kphp::coro::resume_with_new_root(handle, std::addressof(root));
105113
}
106114
// coroutine already completed, don't suspend
107115
if (done()) {
@@ -169,24 +177,13 @@ template<typename promise_type>
169177
class awaiter_base {
170178
bool m_suspended{};
171179

172-
void set_async_top_frame(async_stack_frame& caller_frame, void* return_address) noexcept {
180+
void set_async_top_frame(void* return_address) noexcept {
173181
/**
174182
* shared_task is the top of the stack for calls from it.
175183
* Therefore, it's awaiter doesn't store caller_frame, but it save `await_suspend()` return address
176184
* */
177185
async_stack_frame& callee_frame{m_coro.promise().get_async_stack_frame()};
178-
179186
callee_frame.return_address = return_address;
180-
auto* async_stack_root{caller_frame.async_stack_root};
181-
kphp::log::assertion(async_stack_root != nullptr);
182-
callee_frame.async_stack_root = async_stack_root;
183-
async_stack_root->top_async_stack_frame = std::addressof(callee_frame);
184-
}
185-
186-
void reset_async_top_frame(async_stack_frame& caller_frame) noexcept {
187-
auto* async_stack_root{caller_frame.async_stack_root};
188-
kphp::log::assertion(async_stack_root != nullptr);
189-
async_stack_root->top_async_stack_frame = std::addressof(caller_frame);
190187
}
191188

192189
protected:
@@ -218,10 +215,9 @@ class awaiter_base {
218215

219216
template<std::derived_from<kphp::coro::async_stack_element> caller_promise_type>
220217
[[clang::noinline]] auto await_suspend(std::coroutine_handle<caller_promise_type> awaiting_coroutine) noexcept -> bool {
221-
set_async_top_frame(awaiting_coroutine.promise().get_async_stack_frame(), STACK_RETURN_ADDRESS);
218+
set_async_top_frame(STACK_RETURN_ADDRESS);
222219
m_awaiter.m_continuation = awaiting_coroutine;
223220
m_suspended = m_coro.promise().suspend_awaiter(m_awaiter);
224-
reset_async_top_frame(awaiting_coroutine.promise().get_async_stack_frame());
225221
return m_suspended;
226222
}
227223

0 commit comments

Comments
 (0)