diff --git a/ostd/coroutine.hh b/ostd/coroutine.hh index 99477d9..d09360c 100644 --- a/ostd/coroutine.hh +++ b/ostd/coroutine.hh @@ -224,36 +224,14 @@ protected: template void make_context(SA &sa) { p_stack = sa.allocate(); - - void *sp = get_stack_ptr(); - auto asize = std::size_t(p_stack.size - std::size_t( - static_cast(p_stack.ptr) - - static_cast(sp) - )); - - p_coro = detail::ostd_make_fcontext(sp, asize, &context_call); - new (sp) SA(std::move(sa)); + p_coro = detail::ostd_make_fcontext( + p_stack.ptr, p_stack.size, &context_call + ); + new (&p_salloc) SA(std::move(sa)); p_free = &free_stack_call; } private: - /* we also store the stack allocator at the end of the stack */ - template - void *get_stack_ptr() { - /* 16 byte stack pointer alignment */ - constexpr std::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 std::size_t sasize = sizeof(SA); - - void *sp = static_cast(p_stack.ptr) - sasize - salign; - std::size_t space = sasize + salign; - sp = std::align(salign, sasize, sp, space); - - return sp; - } - struct forced_unwind { detail::transfer_t tfer; forced_unwind(detail::transfer_t t): tfer(t) {} @@ -285,7 +263,7 @@ private: template static void free_stack_call(void *data) { auto &self = *(static_cast(data)); - auto &sa = *(static_cast(self.get_stack_ptr())); + auto &sa = *(reinterpret_cast(&self.p_salloc)); SA dsa{std::move(sa)}; sa.~SA(); dsa.deallocate(self.p_stack); @@ -320,6 +298,10 @@ private: self.yield_done(); } + /* eventually generalize for any stack allocator, for now use + * the size of the biggest stack allocator we have in the library + */ + std::aligned_storage_t p_salloc; stack_context p_stack; detail::fcontext_t p_coro = nullptr; detail::fcontext_t p_orig = nullptr;