Skip to content

Commit

Permalink
Simplify stack management with _frame_state
Browse files Browse the repository at this point in the history
  • Loading branch information
ispeters committed Aug 28, 2024
1 parent 02f3921 commit 4db8856
Showing 1 changed file with 38 additions and 21 deletions.
59 changes: 38 additions & 21 deletions include/unifex/task.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -416,26 +416,34 @@ struct _promise final {
};
};

struct _frame_state {
_frame_state() noexcept = default;

explicit _frame_state(AsyncStackFrame& frame, AsyncStackRoot& root) noexcept
: frame_(&frame), root_(&root) {}

void restore_frame_state() const noexcept {
if (frame_) {
activateAsyncStackFrame(*root_, *frame_);
}
}

private:
AsyncStackFrame* frame_{};
AsyncStackRoot* root_; // only conditionally initialized
};

struct _sr_thunk_promise_base : _promise_base {
_sr_thunk_promise_base()
: _promise_base([this]() noexcept -> coro::coroutine_handle<> {
callback_.destruct();

whoToContinue_ = continuation_.done_handle();

AsyncStackRoot* root;
auto* const frame = frame_;
if (frame) {
popAsyncStackFrameFromCaller(*frame);

root = frame_->getStackRoot();
deactivateAsyncStackFrame(*frame);
}
const auto frameState = ensure_frame_deactivated();

if (refCount_.fetch_sub(1, std::memory_order_acq_rel) == 1) {
if (frame) {
activateAsyncStackFrame(*root, *frame);
}
frameState.restore_frame_state();

return whoToContinue_;
} else {
Expand Down Expand Up @@ -518,6 +526,22 @@ struct _sr_thunk_promise_base : _promise_base {
void register_stop_callback() noexcept {
callback_.construct(stoken_, stop_callback{this});
}

_frame_state ensure_frame_deactivated() noexcept {
if (frame_ != nullptr) {
if (whoToContinue_ == continuation_.done_handle()) {
popAsyncStackFrameFromCaller(*frame_);
}

auto* root = frame_->getStackRoot();
// this asserts that root is not null
deactivateAsyncStackFrame(*frame_);

return _frame_state(*frame_, *root);
}

return {};
}
};

// TODO: determine if this should also be nothrow
Expand Down Expand Up @@ -560,20 +584,13 @@ struct _sr_thunk_promise final {
// deferred stop callback's completion
p.whoToContinue_ = p.continuation_.handle();

AsyncStackRoot* root;
auto* const frame = p.frame_;

if (frame) {
root = frame->getStackRoot();
deactivateAsyncStackFrame(*frame);
}
const auto frameState = p.ensure_frame_deactivated();

// if we're last to complete, continue our continuation; otherwise do
// nothing and wait for the async stop request to do it
if (p.refCount_.fetch_sub(1, std::memory_order_acq_rel) == 1) {
if (frame) {
activateAsyncStackFrame(*root, *frame);
}
frameState.restore_frame_state();

return p.whoToContinue_;
} else {
// the deferred stop callback will reactivate this frame
Expand Down

0 comments on commit 4db8856

Please sign in to comment.