From f1604159b51fff5959efd60a0559b77c7be4d9dc Mon Sep 17 00:00:00 2001 From: Ben Prather Date: Thu, 3 Nov 2022 11:11:01 -0600 Subject: [PATCH 1/4] Die on repeated SIGINT Make signalflag a counter, and add intelligence to SetSignalFlag to throw an error if some number (3) SIGINTs have been received since the flag was last cleared. Also, update FS check to use std::filesystem::exists now that we're C++17 --- src/utils/signal_handler.cpp | 13 +++++++------ src/utils/utils.hpp | 11 +++++++++-- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/utils/signal_handler.cpp b/src/utils/signal_handler.cpp index 940721e154332..4eeaf4ca0440a 100644 --- a/src/utils/signal_handler.cpp +++ b/src/utils/signal_handler.cpp @@ -24,6 +24,7 @@ // first 2x macros and signal() are the only ISO C features; rest are POSIX C extensions #include #include +#include #include "parthenon_mpi.hpp" @@ -61,10 +62,8 @@ void SignalHandlerInit() { OutputSignal CheckSignalFlags() { if (Globals::my_rank == 0) { - // TODO(the person bumping std to C++17): use std::filesystem::exists - struct stat buffer; // if file "output_now" exists - if (stat("output_now", &buffer) == 0) { + if (std::filesystem::exists("output_now")) { signalflag[nsignal] = 1; } } @@ -131,15 +130,17 @@ void SetSignalFlag(int s) { // Signal handler functions must have C linkage; C++ linkage is implemantation-defined switch (s) { case SIGTERM: - signalflag[ITERM] = 1; + signalflag[ITERM] += 1; signal(s, SetSignalFlag); break; case SIGINT: - signalflag[IINT] = 1; + signalflag[IINT] += 1; + if (signalflag[IINT] >= SIGINTS_BEFORE_THROW) + PARTHENON_THROW("Terminating immediately on repeated Terminate signal"); signal(s, SetSignalFlag); break; case SIGALRM: - signalflag[IALRM] = 1; + signalflag[IALRM] += 1; signal(s, SetSignalFlag); break; default: diff --git a/src/utils/utils.hpp b/src/utils/utils.hpp index 5a086778f3731..66dfd762f0d42 100644 --- a/src/utils/utils.hpp +++ b/src/utils/utils.hpp @@ -40,11 +40,18 @@ void ShowConfig(); // \brief static data and functions that implement a simple signal handling system namespace SignalHandler { +// Enum of desired signal results enum class OutputSignal { none, now, final }; +// Signals handled: SIGTERM, SIGINT, SIGALRM +const int ITERM = 0, IINT = 1, IALRM = 2; constexpr int nsignal = 3; -// using the +1 for signaling based on "output_now" trigger +// Flag/counter of signals received of each type +// using the +1 for signaling based on a trigger file static volatile int signalflag[nsignal + 1]; -const int ITERM = 0, IINT = 1, IALRM = 2; + +// Immediately throw upon receiving 3+ SIGINT without clearing them +static int SIGINTS_BEFORE_THROW = 3; + static sigset_t mask; void SignalHandlerInit(); OutputSignal CheckSignalFlags(); From f039ffba28a68e20307cd1f099a5b4e2241243f7 Mon Sep 17 00:00:00 2001 From: Ben Prather Date: Thu, 3 Nov 2022 11:30:58 -0600 Subject: [PATCH 2/4] Fix a typo --- src/utils/utils.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/utils.hpp b/src/utils/utils.hpp index 66dfd762f0d42..cb727cd92ac38 100644 --- a/src/utils/utils.hpp +++ b/src/utils/utils.hpp @@ -50,7 +50,7 @@ constexpr int nsignal = 3; static volatile int signalflag[nsignal + 1]; // Immediately throw upon receiving 3+ SIGINT without clearing them -static int SIGINTS_BEFORE_THROW = 3; +const int SIGINTS_BEFORE_THROW = 3; static sigset_t mask; void SignalHandlerInit(); From c66859cd9923cfd1b8551d16e3aed01c61597887 Mon Sep 17 00:00:00 2001 From: par-hermes Date: Thu, 3 Nov 2022 17:31:43 +0000 Subject: [PATCH 3/4] cpp-py-formatter --- src/utils/signal_handler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/signal_handler.cpp b/src/utils/signal_handler.cpp index 4eeaf4ca0440a..152559949c45c 100644 --- a/src/utils/signal_handler.cpp +++ b/src/utils/signal_handler.cpp @@ -23,8 +23,8 @@ // first 2x macros and signal() are the only ISO C features; rest are POSIX C extensions #include -#include #include +#include #include "parthenon_mpi.hpp" From 113c9636ca0bc8f17cdee489cc32d17ada5c50ac Mon Sep 17 00:00:00 2001 From: Ben Prather Date: Thu, 3 Nov 2022 13:25:16 -0600 Subject: [PATCH 4/4] const->constexpr, update CHANGELOG --- CHANGELOG.md | 1 + src/utils/utils.hpp | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ea3b278d183ad..d5ad9685d3a52 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ - [[PR 712]](https://github.com/lanl/parthenon/pull/712) Allow to add params from cmdline ### Changed (changing behavior/API/variables/...) +- [[PR 782]](https://github.com/parthenon-hpc-lab/parthenon/pull/782) Die on repeatedly receiving SIGINT - [[PR 758]](https://github.com/lanl/parthenon/pull/758) Bump required C++ standard to C++17 - [[PR 710]](https://github.com/lanl/parthenon/pull/710) Remove data transpose in hdf5 and restart outputs - [[PR 713]](https://github.com/lanl/parthenon/pull/713) Remove Coordinates stub in favor of Coordinates_t diff --git a/src/utils/utils.hpp b/src/utils/utils.hpp index cb727cd92ac38..dde68e6bbfdf7 100644 --- a/src/utils/utils.hpp +++ b/src/utils/utils.hpp @@ -43,14 +43,14 @@ namespace SignalHandler { // Enum of desired signal results enum class OutputSignal { none, now, final }; // Signals handled: SIGTERM, SIGINT, SIGALRM -const int ITERM = 0, IINT = 1, IALRM = 2; +constexpr int ITERM = 0, IINT = 1, IALRM = 2; constexpr int nsignal = 3; // Flag/counter of signals received of each type // using the +1 for signaling based on a trigger file static volatile int signalflag[nsignal + 1]; // Immediately throw upon receiving 3+ SIGINT without clearing them -const int SIGINTS_BEFORE_THROW = 3; +constexpr int SIGINTS_BEFORE_THROW = 3; static sigset_t mask; void SignalHandlerInit();