From ce155190e020ed8155b854bb41c1a5be6431bbb0 Mon Sep 17 00:00:00 2001 From: q66 Date: Wed, 15 Mar 2017 01:19:01 +0100 Subject: [PATCH] do not store the allocator/stack pointer directly, also call stack allocator dtor --- ostd/internal/context.hh | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/ostd/internal/context.hh b/ostd/internal/context.hh index 57a92f1..f719641 100644 --- a/ostd/internal/context.hh +++ b/ostd/internal/context.hh @@ -49,12 +49,10 @@ protected: coroutine_context(coroutine_context const &) = delete; coroutine_context(coroutine_context &&c): p_stack(std::move(c.p_stack)), p_coro(c.p_coro), p_orig(c.p_orig), - p_except(std::move(c.p_except)), p_state(std::move(c.p_state)), - p_sa(c.p_sa) + p_except(std::move(c.p_except)), p_state(std::move(c.p_state)) { c.p_coro = c.p_orig = nullptr; c.p_stack = { nullptr, 0 }; - c.p_sa = nullptr; c.set_dead(); } @@ -100,28 +98,38 @@ protected: swap(p_orig, other.p_orig); swap(p_except, other.p_except); swap(p_state, other.p_state); - swap(p_sa, other.p_sa); } template void make_context(SA &sa) { p_stack = sa.allocate(); + void *sp = get_stack_ptr(); + size_t asize = p_stack.size - + (static_cast(p_stack.ptr) - static_cast(sp)); + + p_coro = ostd_make_fcontext(sp, asize, &context_call); + new (sp) SA(std::move(sa)); + } + +private: + /* we also store the stack allocator at the end of the stack */ + template + void *get_stack_ptr() { /* 16 byte stack pointer alignment */ constexpr size_t salign = 16; + /* makes enough space so that we can store the allocator at + * stack pointer location (we'll need it for dealloc later) + */ constexpr size_t sasize = sizeof(SA); void *sp = static_cast(p_stack.ptr) - sasize - salign; size_t space = sasize + salign; sp = std::align(salign, sasize, sp, space); - size_t asize = p_stack.size - - (static_cast(p_stack.ptr) - static_cast(sp)); - p_coro = ostd_make_fcontext(sp, asize, &context_call); - p_sa = new (sp) SA(std::move(sa)); + return sp; } -private: struct forced_unwind { fcontext_t ctx; forced_unwind(fcontext_t c): ctx(c) {} @@ -159,8 +167,11 @@ private: set_dead(); ostd_ontop_fcontext(p_orig, this, [](transfer_t t) -> transfer_t { auto &self = *(static_cast(t.data)); - auto &sa = *(static_cast(self.p_sa)); - sa.deallocate(self.p_stack); + auto &sa = *(static_cast(self.get_stack_ptr())); + SA dsa{std::move(sa)}; + /* in case it holds any state that needs destroying */ + sa.~SA(); + dsa.deallocate(self.p_stack); return { nullptr, nullptr }; }); } @@ -194,7 +205,6 @@ release: fcontext_t p_orig; std::exception_ptr p_except; state p_state = state::HOLD; - void *p_sa = nullptr; }; } /* namespace detail */