From 4cb5119dfa978af3deecb83a56587ed08384193a Mon Sep 17 00:00:00 2001 From: Arnaud Giersch Date: Fri, 25 Feb 2011 15:21:28 +0100 Subject: [PATCH] Terminate smoothly on CTRL-C. --- TODO | 2 -- main.cpp | 28 +++++++++++++++++++++++++++- options.cpp | 1 + options.h | 1 + process.cpp | 4 ++++ 5 files changed, 33 insertions(+), 3 deletions(-) diff --git a/TODO b/TODO index 50395d1..0d476f4 100644 --- a/TODO +++ b/TODO @@ -9,8 +9,6 @@ * Implement some random initial distribution of load Options -r seed, -R [algo ?] -* Terminate smoothly on ctrl+c. - * Support heterogeneous platforms? Not sure yet. Should be doable if each process also sends its speed to its neighbors. diff --git a/main.cpp b/main.cpp index ff1fa1b..76125e9 100644 --- a/main.cpp +++ b/main.cpp @@ -1,5 +1,7 @@ -#include +#include +#include // strchr #include +#include #include #include #include @@ -36,6 +38,7 @@ namespace { EXIT_FAILURE_INIT = 0x02, // failed to initialize simulator EXIT_FAILURE_SIMU = 0x04, // simulation failed EXIT_FAILURE_CLEAN = 0x08, // error at cleanup + EXIT_FAILURE_OTHER = 0x10, // other error }; // Cannot be globally initialized... @@ -131,6 +134,28 @@ static void check_for_lost_load() total_running, running_ratio); } +static void signal_handler(int /*sig*/) +{ + if (!opt::exit_request) { + XBT_CRITICAL(">>>>>>>>>>" + " caught CTRL-C: global exit requested " + "<<<<<<<<<<"); + opt::exit_request = true; + } +} + +static void install_signal_handler() +{ + struct sigaction action; + action.sa_handler = signal_handler; + sigemptyset(&action.sa_mask); + action.sa_flags = SA_RESTART; + if (sigaction (SIGINT, &action, NULL) == -1) { + std::cerr << "sigaction: " << strerror(errno) << "\n"; + exit(EXIT_FAILURE_OTHER); + } +} + #define PR_STATS(descr, st) \ XBT_INFO("| %.*s: %g / %g / %g", DATA_DESCR_WIDTH, \ descr " (total/avg./stddev)................................", \ @@ -162,6 +187,7 @@ int main(int argc, char* argv[]) // Note: MSG_global_init() may throw an exception, but it seems // impossible to catch it correctly :-( MSG_global_init(&argc, argv); + install_signal_handler(); // Parse global parameters bool parse_res = opt::parse_args(&argc, argv); diff --git a/options.cpp b/options.cpp index c0becfd..2994640 100644 --- a/options.cpp +++ b/options.cpp @@ -35,6 +35,7 @@ namespace opt { // Simulation parameters int log_rate = 1; + bool exit_request = false; // Platform and deployment std::string platform_file; diff --git a/options.h b/options.h index b3e3081..0abec0f 100644 --- a/options.h +++ b/options.h @@ -22,6 +22,7 @@ namespace opt { // Simulation parameters extern int log_rate; + extern bool exit_request; // Platform and deployment extern std::string platform_file; diff --git a/process.cpp b/process.cpp index d0bfc21..cbf512b 100644 --- a/process.cpp +++ b/process.cpp @@ -224,6 +224,10 @@ bool process::still_running() if (!last_status) { /* nop */ + } else if (opt::exit_request) { + XBT_VERB("Global exit requested"); + last_status = false; + } else if (opt::time_limit && MSG_get_clock() >= opt::time_limit) { XBT_VERB("Reached time limit: %g/%g", MSG_get_clock(), opt::time_limit); last_status = false; -- 2.39.5