-
-
Notifications
You must be signed in to change notification settings - Fork 420
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
835 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
// Copyright (c) 2007-2012 Hartmut Kaiser | ||
// Copyright (c) 2011 Bryce Adelstein-Lelbach | ||
// | ||
// 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) | ||
|
||
#include <hpx/hpx.hpp> | ||
#include <hpx/runtime/components/component_factory.hpp> | ||
|
||
#include "server/accumulator.hpp" | ||
|
||
/////////////////////////////////////////////////////////////////////////////// | ||
// Add factory registration functionality. | ||
HPX_REGISTER_COMPONENT_MODULE(); | ||
|
||
/////////////////////////////////////////////////////////////////////////////// | ||
typedef hpx::components::component< | ||
examples::server::accumulator | ||
> accumulator_type; | ||
|
||
HPX_REGISTER_COMPONENT(accumulator_type, accumulator); | ||
|
||
/////////////////////////////////////////////////////////////////////////////// | ||
// Serialization support for accumulator actions. | ||
HPX_REGISTER_ACTION( | ||
accumulator_type::wrapped_type::reset_action, | ||
accumulator_reset_action); | ||
HPX_REGISTER_ACTION( | ||
accumulator_type::wrapped_type::add_action, | ||
accumulator_add_action); | ||
HPX_REGISTER_ACTION( | ||
accumulator_type::wrapped_type::query_action, | ||
accumulator_query_action); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
// Copyright (c) 2007-2011 Hartmut Kaiser | ||
// Copyright (c) 2011 Bryce Adelstein-Lelbach | ||
// | ||
// 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_ECFE19F9_A826_4AE1_AC7C_33DC5714CF0B) | ||
#define HPX_ECFE19F9_A826_4AE1_AC7C_33DC5714CF0B | ||
|
||
#include <hpx/include/components.hpp> | ||
|
||
#include "stubs/accumulator.hpp" | ||
|
||
namespace examples | ||
{ | ||
/////////////////////////////////////////////////////////////////////////// | ||
/// Client for the \a server::accumulator component. | ||
class accumulator | ||
: public hpx::components::client_base< | ||
accumulator, stubs::accumulator | ||
> | ||
{ | ||
typedef hpx::components::client_base< | ||
accumulator, stubs::accumulator | ||
> base_type; | ||
|
||
typedef base_type::argument_type argument_type; | ||
|
||
public: | ||
/// Default construct an empty client side representation (not | ||
/// connected to any existing component). | ||
accumulator() | ||
{} | ||
|
||
/// Create a client side representation for the existing | ||
/// \a server::accumulator instance with the given GID. | ||
accumulator(hpx::future<hpx::naming::id_type> && gid) | ||
: base_type(std::move(gid)) | ||
{} | ||
|
||
/////////////////////////////////////////////////////////////////////// | ||
/// Reset the accumulator's value to 0. | ||
/// | ||
/// \note This function has fire-and-forget semantics. It will not wait | ||
/// for the action to be executed. Instead, it will return | ||
/// immediately after the action has has been dispatched. | ||
void reset_non_blocking() | ||
{ | ||
HPX_ASSERT(this->get_id()); | ||
this->base_type::reset_non_blocking(this->get_id()); | ||
} | ||
|
||
/// Reset the accumulator's value to 0. | ||
/// | ||
/// \note This function is fully synchronous. | ||
void reset_sync() | ||
{ | ||
HPX_ASSERT(this->get_id()); | ||
this->base_type::reset_sync(this->get_id()); | ||
} | ||
|
||
/////////////////////////////////////////////////////////////////////// | ||
/// Add \p arg to the accumulator's value. | ||
/// | ||
/// \note This function has fire-and-forget semantics. It will not wait | ||
/// for the action to be executed. Instead, it will return | ||
/// immediately after the action has has been dispatched. | ||
void add_non_blocking(argument_type arg) | ||
{ | ||
HPX_ASSERT(this->get_id()); | ||
this->base_type::add_non_blocking(this->get_id(), arg); | ||
} | ||
|
||
/// Add \p arg to the accumulator's value. | ||
/// | ||
/// \note This function is fully synchronous. | ||
void add_sync(argument_type arg) | ||
{ | ||
HPX_ASSERT(this->get_id()); | ||
this->base_type::add_sync(this->get_id(), arg); | ||
} | ||
|
||
/////////////////////////////////////////////////////////////////////// | ||
/// Asynchronously query the current value of the accumulator. | ||
/// | ||
/// \returns This function returns an \a hpx::lcos::future. When the | ||
/// value of this computation is needed, the get() method of | ||
/// the future should be called. If the value is available, | ||
/// get() will return immediately; otherwise, it will block | ||
/// until the value is ready. | ||
hpx::lcos::future<argument_type> query_async() | ||
{ | ||
HPX_ASSERT(this->get_id()); | ||
return this->base_type::query_async(this->get_id()); | ||
} | ||
|
||
/// Query the current value of the accumulator. | ||
/// | ||
/// \note This function is fully synchronous. | ||
argument_type query_sync() | ||
{ | ||
HPX_ASSERT(this->get_id()); | ||
return this->base_type::query_sync(this->get_id()); | ||
} | ||
}; | ||
} | ||
|
||
#endif | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
// Copyright (c) 2007-2012 Hartmut Kaiser | ||
// Copyright (c) 2011 Bryce Adelstein-Lelbach | ||
// Copyright (c) 2008 Richard D Guidry Jr. | ||
// | ||
// 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) | ||
|
||
#include <hpx/hpx_init.hpp> | ||
|
||
#include "accumulator.hpp" | ||
|
||
#include <boost/lexical_cast.hpp> | ||
#include <boost/algorithm/string/split.hpp> | ||
#include <boost/algorithm/string/trim.hpp> | ||
#include <boost/algorithm/string/classification.hpp> | ||
|
||
char const* const help = "commands: reset, add [amount], query, help, quit"; | ||
|
||
/////////////////////////////////////////////////////////////////////////////// | ||
int hpx_main() | ||
{ | ||
{ | ||
typedef examples::server::accumulator accumulator_type; | ||
typedef accumulator_type::argument_type argument_type; | ||
|
||
// Find the localities connected to this application. | ||
std::vector<hpx::id_type> localities = hpx::find_all_localities(); | ||
|
||
// Create an accumulator component either on this locality (if the | ||
// example is executed on one locality only) or on any of the remote | ||
// localities (otherwise). | ||
examples::accumulator accu( | ||
hpx::components::new_<accumulator_type>(localities.back())); | ||
|
||
// Print out the available commands. | ||
std::cout << help << std::endl << "> "; | ||
|
||
// Enter the interpreter loop. | ||
std::string line; | ||
while (std::getline(std::cin, line)) | ||
{ | ||
boost::algorithm::trim(line); | ||
|
||
std::vector<std::string> cmd; | ||
boost::algorithm::split(cmd, line, | ||
boost::algorithm::is_any_of(" \t\n"), | ||
boost::algorithm::token_compress_on); | ||
|
||
if (!cmd.empty() && !cmd[0].empty()) | ||
{ | ||
// try to interpret the entered command | ||
if (cmd[0] == "reset") { | ||
accu.reset_sync(); | ||
} | ||
else if (cmd[0] == "add") { | ||
if (cmd.size() == 2) { | ||
accu.add_sync(boost::lexical_cast<argument_type>(cmd[1])); | ||
} | ||
else { | ||
std::cout << "error: invalid command '" | ||
<< line << "'" << std::endl | ||
<< help << std::endl; | ||
} | ||
} | ||
else if (cmd[0] == "query") { | ||
std::cout << accu.query_sync() << std::endl; | ||
} | ||
else if (cmd[0] == "help") { | ||
std::cout << help << std::endl; | ||
} | ||
else if (cmd[0] == "quit") { | ||
break; | ||
} | ||
else { | ||
std::cout << "error: invalid command '" | ||
<< line << "'" << std::endl | ||
<< help << std::endl; | ||
} | ||
} | ||
|
||
std:: cout << "> "; | ||
} | ||
} | ||
|
||
// Initiate shutdown of the runtime systems on all localities. | ||
return hpx::finalize(); | ||
} | ||
|
||
/////////////////////////////////////////////////////////////////////////////// | ||
int main(int argc, char* argv[]) | ||
{ | ||
// We force this example to use 2 threads by default as one of the threads | ||
// will be sitting most of the time in the kernel waiting for user input. | ||
std::vector<std::string> cfg; | ||
cfg.push_back("hpx.os_threads=2"); | ||
|
||
// Initialize and run HPX. | ||
return hpx::init(argc, argv, cfg); | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
// Copyright (c) 2007-2011 Hartmut Kaiser | ||
// Copyright (c) 2011 Bryce Adelstein-Lelbach | ||
// | ||
// 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_4C46C86D_A43F_42A8_8164_C9EBA3B210CC) | ||
#define HPX_4C46C86D_A43F_42A8_8164_C9EBA3B210CC | ||
|
||
#include <hpx/hpx_fwd.hpp> | ||
#include <hpx/include/components.hpp> | ||
#include <hpx/runtime/actions/component_action.hpp> | ||
|
||
/////////////////////////////////////////////////////////////////////////////// | ||
namespace examples { namespace server | ||
{ | ||
/////////////////////////////////////////////////////////////////////////// | ||
/// This class is a very simple example of an HPX component. An HPX | ||
/// component is a class that: | ||
/// | ||
/// * Inherits from a component base class: | ||
/// \a hpx::components::component_base | ||
/// * Exposes methods that can be called asynchronously and/or remotely. | ||
/// These constructs are known as HPX actions. | ||
/// | ||
/// By deriving this component from \a locking_hook the runtime system | ||
/// ensures that all action invocations are serialized. That means that | ||
/// the system ensures that no two actions are invoked at the same time on | ||
/// a given component instance. This makes the component thread safe and no | ||
/// additional locking has to be implemented by the user. | ||
/// | ||
/// Components are first-class objects in HPX. This means that they are | ||
/// globally addressable; all components have a unique GID. | ||
/// | ||
/// This example demonstrates how to write a simple component. Simple | ||
/// components are allocated one at a time with the C++'s new allocator. | ||
/// When a component needs to be created in small quantities, simple | ||
/// components should be used. At least two AGAS requests will be made when | ||
/// a simple component is created. | ||
/// | ||
/// This component exposes 3 different actions: reset, add and query. | ||
class accumulator | ||
: public hpx::components::locking_hook< | ||
hpx::components::component_base<accumulator> > | ||
{ | ||
public: | ||
typedef boost::int64_t argument_type; | ||
|
||
accumulator() : value_(0) {} | ||
|
||
/////////////////////////////////////////////////////////////////////// | ||
// Exposed functionality of this component. | ||
|
||
/// Reset the components value to 0. | ||
void reset() | ||
{ | ||
// set value_ to 0. | ||
value_ = 0; | ||
} | ||
|
||
/// Add the given number to the accumulator. | ||
void add(argument_type arg) | ||
{ | ||
// add value_ to arg, and store the result in value_. | ||
value_ += arg; | ||
} | ||
|
||
/// Return the current value to the caller. | ||
argument_type query() const | ||
{ | ||
// Get the value of value_. | ||
return value_; | ||
} | ||
|
||
/////////////////////////////////////////////////////////////////////// | ||
// Each of the exposed functions needs to be encapsulated into an | ||
// action type, generating all required boilerplate code for threads, | ||
// serialization, etc. | ||
|
||
HPX_DEFINE_COMPONENT_ACTION(accumulator, reset); | ||
HPX_DEFINE_COMPONENT_ACTION(accumulator, add); | ||
HPX_DEFINE_COMPONENT_ACTION(accumulator, query); | ||
|
||
private: | ||
argument_type value_; | ||
}; | ||
}} | ||
|
||
HPX_REGISTER_ACTION_DECLARATION( | ||
examples::server::accumulator::reset_action, | ||
accumulator_reset_action); | ||
|
||
HPX_REGISTER_ACTION_DECLARATION( | ||
examples::server::accumulator::add_action, | ||
accumulator_add_action); | ||
|
||
HPX_REGISTER_ACTION_DECLARATION( | ||
examples::server::accumulator::query_action, | ||
accumulator_query_action); | ||
|
||
#endif | ||
|
Oops, something went wrong.