#include "process.h"
+mutex_t *process::proc_mutex;
+
double process::total_load_init = 0.0;
double process::total_load_running = 0.0;
double process::total_load_exit = 0.0;
double process::total_load_average;
double process::load_diff_threshold;
+std::atomic<int> process::convergence_counter(0);
+
namespace {
void sleep_until_date(double& date, double duration)
rev_neigh.insert(std::make_pair(host, ptr));
}
- // Note: there should not be race condition with the current
- // version of Simgrid, when updating the global variables.
-
prev_load_broadcast = -1; // force sending of load on first send_all()
expected_load = real_load;
- total_load_running += real_load;
- total_load_init += real_load;
received_load = 0.0;
idle_duration = 0.0;
convergence = -1.0;
+ proc_mutex->acquire();
process_counter++;
+ convergence_counter++;
+ total_load_init += real_load;
+ total_load_running += real_load;
total_load_average = total_load_running / process_counter;
load_diff_threshold = (opt::load_ratio_threshold +
opt::avg_load_ratio * total_load_average) / 100.0;
+ proc_mutex->release();
ctrl_close_pending = data_close_pending = neigh.size();
close_received = false;
process::~process()
{
delete lb_thread;
+ proc_mutex->acquire();
total_load_exit += real_load;
+ proc_mutex->release();
xbt_assert(received_load == 0.0,
"received_load is %g, but should be 0.0 !", received_load);
if (opt::log_rate < 0)
double process::get_iter_deviation() const
{
- double average_cost = opt::comp_cost(total_load_average);
+ double average_cost = opt::comp_cost(total_load_average); // fixme: get locked?
// Do not count idle periods
double comp_iter_opt = acc.comp_amount / average_cost;
/*
}
real_load += received_load;
received_load = 0.0;
+ proc_mutex->acquire();
total_load_running -= real_load;
+ proc_mutex->release();
convergence_check();
comm.data_flush(true);
}
void process::convergence_check()
{
- double load_diff = std::fabs(real_load - total_load_average);
+ double average = total_load_average; // fixme: get locked?
+ double load_diff = std::fabs(real_load - average);
bool converged = load_diff <= load_diff_threshold;
if (convergence >= 0.0) {
if (!converged) {
XBT_VERB("current load has diverged: %g (%.4g%%)",
- real_load, 100.0 * load_diff / total_load_average);
+ real_load, 100.0 * load_diff / average);
convergence = -1.0;
+ convergence_counter++;
}
} else {
if (converged) {
XBT_VERB("current load has converged: %g (%.4g%%)",
- real_load, 100.0 * load_diff / total_load_average);
+ real_load, 100.0 * load_diff / average);
convergence = MSG_get_clock();
+ convergence_counter--;
}
}
}
XBT_VERB("Reached comp_maxiter: %d/%d", comp_iter, opt::comp_maxiter);
last_status = false;
+ } else if (opt::exit_on_convergence && convergence_counter == 0) {
+ XBT_VERB("Global convergence detected");
+ last_status = false;
+
} else if (opt::exit_on_close && close_received) {
XBT_VERB("Close received");
last_status = false;
last_status = false;
} else if (100.0 * total_load_running / total_load_init <=
- opt::load_ratio_threshold) {
+ opt::load_ratio_threshold) { // fixme: get locked?
// fixme: this check should be implemented with a distributed
// algorithm, and not a shared global variable!
XBT_VERB("No more load to balance in system.");