Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Making sure, that hpx::finalize can be called from any locality #1134

Merged
merged 1 commit into from May 15, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions hpx/runtime/components/server/runtime_support.hpp
Expand Up @@ -21,6 +21,7 @@
#include <boost/preprocessor/comma_if.hpp>
#include <boost/preprocessor/enum_params.hpp>
#include <boost/preprocessor/iterate.hpp>
#include <boost/atomic.hpp>

#include <hpx/hpx_fwd.hpp>
#include <hpx/runtime/agas/gva.hpp>
Expand Down Expand Up @@ -406,6 +407,7 @@ namespace hpx { namespace components { namespace server
bool stopped_;
bool terminated_;
bool dijkstra_color_; // false: white, true: black
boost::atomic<bool> shutdown_all_invoked_;

lcos::local::spinlock dijkstra_mtx_;
lcos::local::condition_variable dijkstra_cond_;
Expand Down
40 changes: 23 additions & 17 deletions src/hpx_init.cpp
Expand Up @@ -1150,29 +1150,35 @@ namespace hpx
if (&ec != &throws)
ec = make_success_code();

if (hpx::find_here() == hpx::find_root_locality())
if (std::abs(localwait + 1.0) < 1e-16)
localwait = detail::get_option("hpx.finalize_wait_time", -1.0);
else
{
if (std::abs(localwait + 1.0) < 1e-16)
localwait = detail::get_option("hpx.finalize_wait_time", -1.0);
else
{
hpx::util::high_resolution_timer t;
double start_time = t.elapsed();
double current = 0.0;
do {
current = t.elapsed();
} while (current - start_time < localwait * 1e-6);
}
hpx::util::high_resolution_timer t;
double start_time = t.elapsed();
double current = 0.0;
do {
current = t.elapsed();
} while (current - start_time < localwait * 1e-6);
}

if (std::abs(shutdown_timeout + 1.0) < 1e-16)
shutdown_timeout = detail::get_option("hpx.shutdown_timeout", -1.0);
if (std::abs(shutdown_timeout + 1.0) < 1e-16)
shutdown_timeout = detail::get_option("hpx.shutdown_timeout", -1.0);

components::server::runtime_support* p =
reinterpret_cast<components::server::runtime_support*>(
get_runtime().get_runtime_support_lva());
using components::server::runtime_support;

hpx::id_type root = hpx::find_root_locality();
if (hpx::find_here() == root)
{
runtime_support* p = get_runtime_support_ptr();
p->shutdown_all(shutdown_timeout);
}
else
{
// tell main locality to start application exit, duplicate requests
// will be ignored
apply<runtime_support::shutdown_all_action>(root, shutdown_timeout);
}

util::apex_finalize();
return 0;
Expand Down
21 changes: 18 additions & 3 deletions src/runtime/components/server/runtime_support_server.cpp
Expand Up @@ -245,7 +245,8 @@ namespace hpx { namespace components { namespace server
{
///////////////////////////////////////////////////////////////////////////
runtime_support::runtime_support()
: stopped_(false), terminated_(false), dijkstra_color_(false)
: stopped_(false), terminated_(false), dijkstra_color_(false),
shutdown_all_invoked_(false)
{}

///////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -591,7 +592,7 @@ namespace hpx { namespace components { namespace server

agas_client.start_shutdown();

// First wait for this locality to become passive. We do this by
// First wait for this locality to become passive. We do this by
// periodically checking the number of still running threads.
//
// Rule 0: When active, machine nr.i + 1 keeps the token; when passive,
Expand Down Expand Up @@ -656,7 +657,7 @@ namespace hpx { namespace components { namespace server
boost::uint32_t initiating_locality_id,
boost::uint32_t num_localities, bool dijkstra_token)
{
// First wait for this locality to become passive. We do this by
// First wait for this locality to become passive. We do this by
// periodically checking the number of still running threads.
//
// Rule 0: When active, machine nr.i + 1 keeps the token; when passive,
Expand Down Expand Up @@ -762,6 +763,19 @@ namespace hpx { namespace components { namespace server
///////////////////////////////////////////////////////////////////////////
void runtime_support::shutdown_all(double timeout)
{
if (find_here() != hpx::find_root_locality())
{
HPX_THROW_EXCEPTION(invalid_status,
"runtime_support::shutdown_all",
"shutdown_all shut be invoked on the troot locality only");
return;
}

// make sure shutdown_all is invoked only once
bool flag = false;
if (!shutdown_all_invoked_.compare_exchange_strong(flag, true))
return;

applier::applier& appl = hpx::applier::get_applier();
naming::resolver_client& agas_client = appl.get_agas_client();

Expand Down Expand Up @@ -935,6 +949,7 @@ namespace hpx { namespace components { namespace server
mutex_type::scoped_lock l(mtx_);
stopped_ = false;
terminated_ = false;
shutdown_all_invoked_.store(false);
}

void runtime_support::wait()
Expand Down