forked from OctaForge/libostd
do not store the allocator/stack pointer directly, also call stack allocator dtor
parent
78d6a23ad3
commit
ce155190e0
|
@ -49,12 +49,10 @@ protected:
|
||||||
coroutine_context(coroutine_context const &) = delete;
|
coroutine_context(coroutine_context const &) = delete;
|
||||||
coroutine_context(coroutine_context &&c):
|
coroutine_context(coroutine_context &&c):
|
||||||
p_stack(std::move(c.p_stack)), p_coro(c.p_coro), p_orig(c.p_orig),
|
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_except(std::move(c.p_except)), p_state(std::move(c.p_state))
|
||||||
p_sa(c.p_sa)
|
|
||||||
{
|
{
|
||||||
c.p_coro = c.p_orig = nullptr;
|
c.p_coro = c.p_orig = nullptr;
|
||||||
c.p_stack = { nullptr, 0 };
|
c.p_stack = { nullptr, 0 };
|
||||||
c.p_sa = nullptr;
|
|
||||||
c.set_dead();
|
c.set_dead();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,28 +98,38 @@ protected:
|
||||||
swap(p_orig, other.p_orig);
|
swap(p_orig, other.p_orig);
|
||||||
swap(p_except, other.p_except);
|
swap(p_except, other.p_except);
|
||||||
swap(p_state, other.p_state);
|
swap(p_state, other.p_state);
|
||||||
swap(p_sa, other.p_sa);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename C, typename SA>
|
template<typename C, typename SA>
|
||||||
void make_context(SA &sa) {
|
void make_context(SA &sa) {
|
||||||
p_stack = sa.allocate();
|
p_stack = sa.allocate();
|
||||||
|
|
||||||
|
void *sp = get_stack_ptr<SA>();
|
||||||
|
size_t asize = p_stack.size -
|
||||||
|
(static_cast<byte *>(p_stack.ptr) - static_cast<byte *>(sp));
|
||||||
|
|
||||||
|
p_coro = ostd_make_fcontext(sp, asize, &context_call<C, SA>);
|
||||||
|
new (sp) SA(std::move(sa));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
/* we also store the stack allocator at the end of the stack */
|
||||||
|
template<typename SA>
|
||||||
|
void *get_stack_ptr() {
|
||||||
/* 16 byte stack pointer alignment */
|
/* 16 byte stack pointer alignment */
|
||||||
constexpr size_t salign = 16;
|
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);
|
constexpr size_t sasize = sizeof(SA);
|
||||||
|
|
||||||
void *sp = static_cast<byte *>(p_stack.ptr) - sasize - salign;
|
void *sp = static_cast<byte *>(p_stack.ptr) - sasize - salign;
|
||||||
size_t space = sasize + salign;
|
size_t space = sasize + salign;
|
||||||
sp = std::align(salign, sasize, sp, space);
|
sp = std::align(salign, sasize, sp, space);
|
||||||
size_t asize = p_stack.size -
|
|
||||||
(static_cast<byte *>(p_stack.ptr) - static_cast<byte *>(sp));
|
|
||||||
|
|
||||||
p_coro = ostd_make_fcontext(sp, asize, &context_call<C, SA>);
|
return sp;
|
||||||
p_sa = new (sp) SA(std::move(sa));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
|
||||||
struct forced_unwind {
|
struct forced_unwind {
|
||||||
fcontext_t ctx;
|
fcontext_t ctx;
|
||||||
forced_unwind(fcontext_t c): ctx(c) {}
|
forced_unwind(fcontext_t c): ctx(c) {}
|
||||||
|
@ -159,8 +167,11 @@ private:
|
||||||
set_dead();
|
set_dead();
|
||||||
ostd_ontop_fcontext(p_orig, this, [](transfer_t t) -> transfer_t {
|
ostd_ontop_fcontext(p_orig, this, [](transfer_t t) -> transfer_t {
|
||||||
auto &self = *(static_cast<coroutine_context *>(t.data));
|
auto &self = *(static_cast<coroutine_context *>(t.data));
|
||||||
auto &sa = *(static_cast<SA *>(self.p_sa));
|
auto &sa = *(static_cast<SA *>(self.get_stack_ptr<SA>()));
|
||||||
sa.deallocate(self.p_stack);
|
SA dsa{std::move(sa)};
|
||||||
|
/* in case it holds any state that needs destroying */
|
||||||
|
sa.~SA();
|
||||||
|
dsa.deallocate(self.p_stack);
|
||||||
return { nullptr, nullptr };
|
return { nullptr, nullptr };
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -194,7 +205,6 @@ release:
|
||||||
fcontext_t p_orig;
|
fcontext_t p_orig;
|
||||||
std::exception_ptr p_except;
|
std::exception_ptr p_except;
|
||||||
state p_state = state::HOLD;
|
state p_state = state::HOLD;
|
||||||
void *p_sa = nullptr;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace detail */
|
} /* namespace detail */
|
||||||
|
|
Loading…
Reference in New Issue