From 661393f9c5ad9fbef36137a0aef82f1f315d8abe Mon Sep 17 00:00:00 2001 From: q66 Date: Tue, 7 Mar 2017 21:49:43 +0100 Subject: [PATCH] some initial stack alloc/free funcs --- ostd/internal/context.hh | 39 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/ostd/internal/context.hh b/ostd/internal/context.hh index 49757a0..26aa2fe 100644 --- a/ostd/internal/context.hh +++ b/ostd/internal/context.hh @@ -6,6 +6,7 @@ #ifndef OSTD_INTERNAL_CONTEXT_HH #define OSTD_INTERNAL_CONTEXT_HH +#include #include #include @@ -16,6 +17,11 @@ namespace ostd { namespace detail { +struct context_stack_t { + void *ptr; + size_t size; +}; + /* from boost.fcontext */ using fcontext_t = void *; @@ -39,6 +45,9 @@ transfer_t OSTD_CDECL ostd_ontop_fcontext( fcontext_t const to, void *vp, transfer_t (*fn)(transfer_t) ); +context_stack_t context_stack_alloc(size_t ss); +void context_stack_free(context_stack_t &st); + struct coroutine_context { protected: struct forced_unwind { @@ -48,12 +57,17 @@ protected: coroutine_context() {} + ~coroutine_context() { + context_stack_free(p_stack); + } + 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)) { c.p_coro = c.p_orig = nullptr; + c.p_stack = { nullptr, 0 }; } coroutine_context &operator=(coroutine_context const &) = delete; @@ -95,17 +109,36 @@ protected: } void make_context(size_t ss, void (*callp)(transfer_t)) { - p_stack = std::unique_ptr{new byte[ss]}; - p_coro = ostd_make_fcontext(p_stack.get() + ss, ss, callp); + p_stack = context_stack_alloc(ss); + p_coro = ostd_make_fcontext(p_stack.ptr, p_stack.size, callp); } /* TODO: new'ing the stack is sub-optimal */ - std::unique_ptr p_stack; + context_stack_t p_stack = { nullptr, 0 }; fcontext_t p_coro; fcontext_t p_orig; std::exception_ptr p_except; }; +/* stack allocator */ + +inline context_stack_t context_stack_alloc(size_t ss) { + auto p = static_cast(std::malloc(ss)); + if (!p) { + throw std::bad_alloc{}; + } + return { p + ss, ss }; +} + +inline void context_stack_free(context_stack_t &st) { + if (!st.ptr) { + return; + } + auto p = static_cast(st.ptr) - st.size; + std::free(p); + st.ptr = nullptr; +} + } }