Skip to content

Commit

Permalink
Fixing local direction function execution and lambda actions perfect …
Browse files Browse the repository at this point in the history
…forwarding
  • Loading branch information
Thomas Heller committed Dec 2, 2017
1 parent cd29421 commit 9c661f7
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 50 deletions.
34 changes: 25 additions & 9 deletions hpx/lcos/detail/async_implementations.hpp
Expand Up @@ -134,15 +134,15 @@ namespace hpx { namespace detail
{
try
{
auto&& result = Action::execute_function(
addr.address_, addr.type_, std::forward<Ts>(vs)...);
typedef typename Action::remote_result_type remote_result_type;

typedef typename util::decay<decltype(result)>::type naked_type;
typedef traits::get_remote_result<Result, naked_type>
typedef traits::get_remote_result<Result, remote_result_type>
get_remote_result_type;

return make_ready_future(
get_remote_result_type::call(std::move(result)));
get_remote_result_type::call(
Action::execute_function(
addr.address_, addr.type_, std::forward<Ts>(vs)...)));
}
catch (...)
{
Expand Down Expand Up @@ -343,16 +343,32 @@ namespace hpx { namespace detail
id, addr.address_);
if (!r.first)
{
f = hpx::async(action_invoker<action_type>(),
addr.address_, addr.type_, std::forward<Ts>(vs)...);
if (action_type::direct_execution::value)
{
return sync_local_invoke<action_type, result_type>::call(
id, std::move(addr), std::forward<Ts>(vs)...);
}
else
{
f = hpx::async(action_invoker<action_type>(),
addr.address_, addr.type_, std::forward<Ts>(vs)...);
}

return keep_alive(std::move(f), id, std::move(r.second));
}
}
else
{
f = hpx::async(action_invoker<action_type>(),
addr.address_, addr.type_, std::forward<Ts>(vs)...);
if (action_type::direct_execution::value)
{
return sync_local_invoke<action_type, result_type>::call(
id, std::move(addr), std::forward<Ts>(vs)...);
}
else
{
f = hpx::async(action_invoker<action_type>(),
addr.address_, addr.type_, std::forward<Ts>(vs)...);
}

return keep_alive(std::move(f), id);
}
Expand Down
66 changes: 25 additions & 41 deletions hpx/runtime/actions/lambda_to_action.hpp
Expand Up @@ -35,62 +35,46 @@ namespace hpx { namespace actions
}
};

template<typename F, typename ReturnType, typename ... Args>
struct caller{
static inline ReturnType call(Args && ... args)
{
int * dummy = nullptr;
return reinterpret_cast<const F&>(*dummy)( std::forward<Args>(args)... );
}
};

template<class F, typename ReturnType, typename Sequence>
struct make_action_using_sequence
{};

template<class F, typename ReturnType,
template <typename...> class T, typename ... Args>
struct make_action_using_sequence< F, ReturnType, T<Args...> >
template<typename F, typename ReturnType, typename... Args>
struct lambda_action
: basic_action<detail::plain_function, ReturnType(Args...),
lambda_action<F, ReturnType, Args...>>
{
using type =
typename hpx::actions::make_action<
decltype(&caller<F,ReturnType,Args...>::call),
&caller<F,ReturnType,Args...>::call >::type;
};
typedef lambda_action derived_type;
typedef std::false_type direct_execution;
typedef void is_plain_action;

template <typename T>
struct extract_parameters
{};
static std::string get_action_name(naming::address::address_type /*lva*/)
{
return "lambda action()";
}

// Specialization for lambdas
template <typename ClassType, typename ReturnType, typename... Args>
struct extract_parameters<ReturnType(ClassType::*)(Args...) const>
{
using type = hpx::actions::detail::sequence< Args... >;
template <typename ...Ts>
static ReturnType invoke(naming::address::address_type /*lva*/,
naming::address::component_type comptype, Ts&&... vs)
{
int * dummy = nullptr;
return reinterpret_cast<const F&>(*dummy)( std::forward<Ts>(vs)... );
}
};

template <typename T>
struct extract_return_type
template <typename F, typename T>
struct extract_lambda_action
{};

template <typename ClassType, typename ReturnType, typename... Args>
struct extract_return_type<ReturnType(ClassType::*)(Args...) const>
// Specialization for lambdas
template <typename F, typename ClassType, typename ReturnType, typename... Args>
struct extract_lambda_action<F, ReturnType(ClassType::*)(Args...) const>
{
using type = ReturnType;
using type = lambda_action<F, ReturnType, Args...>;
};

template <typename F>
struct action_from_lambda
{
using sequence_type =
typename hpx::actions::detail::extract_parameters<
decltype(&F::operator())>::type;
using return_type =
typename hpx::actions::detail::extract_return_type<
decltype(&F::operator())>::type;
using type =
typename hpx::actions::detail::make_action_using_sequence<
F,return_type,sequence_type>::type;
typename extract_lambda_action<F, decltype(&F::operator())>::type;
};

#if defined(HPX_MSVC_WARNING_PRAGMA)
Expand Down

0 comments on commit 9c661f7

Please sign in to comment.