Skip to content

Commit

Permalink
Supporting generic context for boost >= 1.61
Browse files Browse the repository at this point in the history
  • Loading branch information
AntonBikineev committed May 4, 2017
1 parent b88f140 commit e7b0d70
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 5 deletions.
59 changes: 55 additions & 4 deletions hpx/runtime/threads/coroutines/detail/context_generic_context.hpp
Expand Up @@ -34,7 +34,11 @@

#include <boost/atomic.hpp>

#if BOOST_VERSION < 106100
#include <boost/context/all.hpp>
#else
#include <boost/context/detail/fcontext.hpp>
#endif

#include <cstddef>
#include <cstdint>
Expand Down Expand Up @@ -132,7 +136,13 @@ namespace hpx { namespace threads { namespace coroutines
{ return minimum_stacksize(); }

static std::size_t minimum_stacksize()
{ return SIGSTKSZ + sizeof(boost::context::fcontext_t) + 15; }
{ return SIGSTKSZ +
#if BOOST_VERSION < 106100
sizeof(boost::context::fcontext_t)
#else
sizeof(boost::context::detail::fcontext_t)
#endif
+ 15; }

void* allocate(std::size_t size) const
{
Expand All @@ -158,6 +168,7 @@ namespace hpx { namespace threads { namespace coroutines

// Generic implementation for the context_impl_base class based on
// Boost.Context.
#if BOOST_VERSION < 106100
template <typename T>
HPX_FORCEINLINE void trampoline(intptr_t pv)
{
Expand All @@ -166,6 +177,23 @@ namespace hpx { namespace threads { namespace coroutines
(*fun)();
std::abort();
}
#else
template <typename T>
HPX_FORCEINLINE void trampoline(boost::context::detail::transfer_t tr)
{
auto arg = reinterpret_cast<std::pair<void*,
boost::context::detail::fcontext_t*>*>(tr.data);

HPX_ASSERT(arg->second);
*arg->second = tr.fctx;

T* fun = reinterpret_cast<T*>(arg->first);
HPX_ASSERT(fun);
(*fun)();

std::abort();
}
#endif

class fcontext_context_impl
{
Expand All @@ -175,7 +203,11 @@ namespace hpx { namespace threads { namespace coroutines
typedef fcontext_context_impl context_impl_base;

fcontext_context_impl()
#if BOOST_VERSION < 106100
: cb_(0)
#else
: cb_(std::make_pair(nullptr, nullptr))
#endif
, funp_(0)
#if BOOST_VERSION > 105500
, ctx_(0)
Expand All @@ -189,7 +221,11 @@ namespace hpx { namespace threads { namespace coroutines
// a new stack. The stack size can be optionally specified.
template <typename Functor>
fcontext_context_impl(Functor& cb, std::ptrdiff_t stack_size)
#if BOOST_VERSION < 106100
: cb_(reinterpret_cast<intptr_t>(&cb))
#else
: cb_(std::make_pair(reinterpret_cast<void*>(&cb), nullptr))
#endif
, funp_(&trampoline<Functor>)
#if BOOST_VERSION > 105500
, ctx_(0)
Expand All @@ -206,9 +242,13 @@ namespace hpx { namespace threads { namespace coroutines
boost::context::make_fcontext(stack_pointer_, stack_size_, funp_);

std::swap(*ctx, ctx_);
#else
#elif BOOST_VERSION < 106100
ctx_ =
boost::context::make_fcontext(stack_pointer_, stack_size_, funp_);
#else
ctx_ =
boost::context::detail::make_fcontext(
stack_pointer_, stack_size_, funp_);
#endif
}

Expand Down Expand Up @@ -267,7 +307,7 @@ namespace hpx { namespace threads { namespace coroutines

private:
friend void swap_context(fcontext_context_impl& from,
fcontext_context_impl const& to, detail::default_hint)
fcontext_context_impl& to, detail::default_hint)
{
#if defined(HPX_GENERIC_CONTEXT_USE_SEGMENTED_STACKS)
__splitstack_getcontext(from.alloc_.segments_ctx_);
Expand All @@ -276,8 +316,13 @@ namespace hpx { namespace threads { namespace coroutines
// switch to other coroutine context
#if BOOST_VERSION < 105600
boost::context::jump_fcontext(&from.ctx_, &to.ctx_, to.cb_, false);
#else
#elif BOOST_VERSION < 106100
boost::context::jump_fcontext(&from.ctx_, to.ctx_, to.cb_, false);
#else
to.cb_.second = &from.ctx_;
auto transfer = boost::context::detail::jump_fcontext(
to.ctx_, reinterpret_cast<void*>(&to.cb_));
to.ctx_ = transfer.fctx;
#endif

#if defined(HPX_GENERIC_CONTEXT_USE_SEGMENTED_STACKS)
Expand All @@ -286,9 +331,15 @@ namespace hpx { namespace threads { namespace coroutines
}

private:
#if BOOST_VERSION < 106100
intptr_t cb_;
void (*funp_)(intptr_t);
boost::context::fcontext_t ctx_;
#else
std::pair<void*, boost::context::detail::fcontext_t*> cb_;
void (*funp_)(boost::context::detail::transfer_t);
boost::context::detail::fcontext_t ctx_;
#endif
stack_allocator alloc_;
std::size_t stack_size_;
void * stack_pointer_;
Expand Down
Expand Up @@ -51,9 +51,12 @@ namespace hpx { namespace threads { namespace coroutines
boost::context::make_fcontext(stack_pointer_, stack_size_, funp_);

std::swap(*ctx, ctx_);
#else
#elif BOOST_VERSION < 106100
ctx_ =
boost::context::make_fcontext(stack_pointer_, stack_size_, funp_);
#else
ctx_ =
boost::context::detail::make_fcontext(stack_pointer_, stack_size_, funp_);
#endif
}
}
Expand Down

0 comments on commit e7b0d70

Please sign in to comment.