From d9114d4fc69f218544ca92122c2799e12f8aa925 Mon Sep 17 00:00:00 2001 From: Hartmut Kaiser Date: Fri, 10 Feb 2017 06:45:07 -0600 Subject: [PATCH] Adding component base class which ties a component instance to a given executor_component.hpp - all actions will be executed in the context of this executor --- .../quickstart/component_with_executor.cpp | 44 +++------ hpx/include/components.hpp | 1 + .../components/server/executor_component.hpp | 98 +++++++++++++++++++ 3 files changed, 111 insertions(+), 32 deletions(-) create mode 100644 hpx/runtime/components/server/executor_component.hpp diff --git a/examples/quickstart/component_with_executor.cpp b/examples/quickstart/component_with_executor.cpp index 52a30395c73c..3363ed0d0562 100644 --- a/examples/quickstart/component_with_executor.cpp +++ b/examples/quickstart/component_with_executor.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014 Hartmut Kaiser +// Copyright (c) 2014-2017 Hartmut Kaiser // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -7,17 +7,25 @@ #include #include #include -#include +#include #include /////////////////////////////////////////////////////////////////////////////// // Define a base component which exposes the required interface struct hello_world_server - : hpx::components::component_base + : hpx::components::executor_component< + hpx::parallel::local_priority_queue_executor, + hpx::components::component_base > { + typedef hpx::parallel::local_priority_queue_executor executor_type; + typedef hpx::components::executor_component< + executor_type, hpx::components::component_base + > base_type; + + // run on all available cores hello_world_server() - : sched_(hpx::get_num_worker_threads()) // run on all available cores + : base_type(executor_type(hpx::get_num_worker_threads())) {} void print() const @@ -26,34 +34,6 @@ struct hello_world_server } HPX_DEFINE_COMPONENT_ACTION(hello_world_server, print, print_action); - - /////////////////////////////////////////////////////////////////////////// - // wrap given function into a nullary function as expected by the executor - static void func(hpx::threads::thread_function_type f) - { - f(hpx::threads::wait_signaled); - } - - /// This is the default hook implementation for schedule_thread which - /// forwards to the default scheduler. - static void schedule_thread(hpx::naming::address::address_type lva, - hpx::threads::thread_init_data& data, - hpx::threads::thread_state_enum initial_state) - { - hpx::util::thread_description desc(&hello_world_server::func); -#ifdef HPX_HAVE_THREAD_DESCRIPTION - desc = data.description; -#endif - - hpx::get_lva::call(lva)->sched_.add( - hpx::util::bind( - hpx::util::one_shot(&hello_world_server::func), - std::move(data.func)), - desc, initial_state); - } - -private: - hpx::threads::executors::local_priority_queue_executor sched_; }; typedef hpx::components::component server_type; diff --git a/hpx/include/components.hpp b/hpx/include/components.hpp index 6bde866e1bfe..9a06a8c21a2e 100644 --- a/hpx/include/components.hpp +++ b/hpx/include/components.hpp @@ -41,6 +41,7 @@ #include #include +#include #include #include diff --git a/hpx/runtime/components/server/executor_component.hpp b/hpx/runtime/components/server/executor_component.hpp new file mode 100644 index 000000000000..52d6ded5bc83 --- /dev/null +++ b/hpx/runtime/components/server/executor_component.hpp @@ -0,0 +1,98 @@ +// Copyright (c) 2017 Hartmut Kaiser +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(HPX_RUNTIME_COMPONENTS_SERVER_EXECUTOR_COMPONENT_FEB_09_2017_0839PM) +#define HPX_RUNTIME_COMPONENTS_SERVER_EXECUTOR_COMPONENT_FEB_09_2017_0839PM + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace hpx { namespace components +{ + // This is a base class which allows to associate the execution of all + // actions for a particular component instance with a given executor. + template + struct executor_component : BaseComponent + { + private: + typedef BaseComponent base_type; + typedef Executor executor_type; + typedef typename base_type::this_component_type this_component_type; + + public: + template + executor_component(executor_type const& exec, Arg &&... arg) + : base_type(std::forward(arg)...), + exec_(exec) + {} + + /////////////////////////////////////////////////////////////////////// + // wrap given function into a nullary function as expected by the + // executor + static void execute(hpx::threads::thread_function_type const& f) + { + f(hpx::threads::wait_signaled); + } + + /// This is the default hook implementation for schedule_thread which + /// forwards to the executor instance associated with this component. + template + static typename std::enable_if< + traits::is_threads_executor::value + >::type + schedule_thread(hpx::naming::address::address_type lva, + hpx::threads::thread_init_data& data, + hpx::threads::thread_state_enum initial_state) + { + hpx::util::thread_description desc(&executor_component::execute); +#ifdef HPX_HAVE_THREAD_DESCRIPTION + desc = data.description; +#endif + hpx::get_lva::call(lva)->exec_.add( + hpx::util::deferred_call(&executor_component::execute, + std::move(data.func)), + desc, initial_state); + } + + template + static typename std::enable_if< + !traits::is_threads_executor::value + >::type + schedule_thread(hpx::naming::address::address_type lva, + hpx::threads::thread_init_data& data, + hpx::threads::thread_state_enum initial_state) + { + hpx::util::thread_description desc(&executor_component::execute); +#ifdef HPX_HAVE_THREAD_DESCRIPTION + desc = data.description; +#endif + hpx::parallel::executor_traits::async_execute( + hpx::get_lva::call(lva)->exec_, + hpx::util::deferred_call( + hpx::util::annotated_function( + &executor_component::execute, desc.get_description() + ), + std::move(data.func))); + } + + protected: + executor_type exec_; + }; +}} + +#endif +