From 5b7d8df30604cfffaeb688f208bee49463980301 Mon Sep 17 00:00:00 2001 From: Lee Killough <15950023+leekillough@users.noreply.github.com> Date: Thu, 14 Nov 2024 13:34:06 -0600 Subject: [PATCH] Add [[noreturn]] attribute to Output::fatal, add SST_Exit() function (#1175) * Add [[noreturn]] attribute to Output::fatal, add SST_Exit() function --- src/sst/core/output.cc | 18 ++---------------- src/sst/core/output.h | 3 ++- src/sst/core/simulation.cc | 26 ++++++++++++++++++++++++++ src/sst/core/simulation_impl.h | 8 ++++++-- 4 files changed, 36 insertions(+), 19 deletions(-) diff --git a/src/sst/core/output.cc b/src/sst/core/output.cc index 7aaafe7ef..5e048a398 100644 --- a/src/sst/core/output.cc +++ b/src/sst/core/output.cc @@ -41,9 +41,6 @@ REENABLE_WARNING namespace SST { -// Atomic to control access to calling MPI_Abort or exit() in fatal() call -std::atomic fatal_count = 0; - // Initialize The Static Member Variables Output Output::m_defaultObject; std::string Output::m_sstGlobalSimFileName = ""; @@ -159,7 +156,7 @@ Output::getOutputLocation() const return m_targetLoc; } -void +[[noreturn]] void Output::fatal(uint32_t line, const char* file, const char* func, int exit_code, const char* format, ...) const { va_list arg1; @@ -217,18 +214,7 @@ Output::fatal(uint32_t line, const char* file, const char* func, int exit_code, Simulation_impl::emergencyShutdown(); - int count = fatal_count.fetch_add(1); - - // Make sure only one thread calls MPI_Abort() or exit() in the - // case where two threads call fatal() at the same time - if ( count == 0 ) { -#ifdef SST_CONFIG_HAVE_MPI - // If MPI exists, abort - MPI_Abort(MPI_COMM_WORLD, exit_code); -#else - exit(exit_code); -#endif - } + SST_Exit(exit_code); } void diff --git a/src/sst/core/output.h b/src/sst/core/output.h index a12c5f19a..41b4856e5 100644 --- a/src/sst/core/output.h +++ b/src/sst/core/output.h @@ -394,7 +394,8 @@ class Output @param format Format string. All valid formats for printf are available. @param ... Arguments for format. */ - void fatal(uint32_t line, const char* file, const char* func, int exit_code, const char* format, ...) const + [[noreturn]] void + fatal(uint32_t line, const char* file, const char* func, int exit_code, const char* format, ...) const __attribute__((format(printf, 6, 7))); // GET / SET METHODS diff --git a/src/sst/core/simulation.cc b/src/sst/core/simulation.cc index 7dd30bd6b..8ad51c6aa 100644 --- a/src/sst/core/simulation.cc +++ b/src/sst/core/simulation.cc @@ -43,7 +43,14 @@ #include "sst/core/unitAlgebra.h" #include "sst/core/warnmacros.h" +#ifdef SST_CONFIG_HAVE_MPI +DISABLE_WARN_MISSING_OVERRIDE +#include +REENABLE_WARNING +#endif + #include +#include #include #include #include @@ -2064,6 +2071,25 @@ Simulation_impl::printPerformanceInfo() } #endif +[[noreturn]] void +SST_Exit(int exit_code) +{ + // Make sure only one thread calls MPI_Abort() or exit() in the + // case where two threads call fatal() at the same time + // Only one thread initializes the function-local static variable + // Other threads are blocked + +#ifdef SST_CONFIG_HAVE_MPI + // If MPI exists, abort + static int exit_once = (MPI_Abort(MPI_COMM_WORLD, exit_code), 0); +#else + static int exit_once = (exit(exit_code), 0); +#endif + + // Should never get here + std::terminate(); +} + /* Define statics */ Factory* Simulation_impl::factory; TimeLord Simulation_impl::timeLord; diff --git a/src/sst/core/simulation_impl.h b/src/sst/core/simulation_impl.h index 4f4a029aa..a0a62f3c0 100644 --- a/src/sst/core/simulation_impl.h +++ b/src/sst/core/simulation_impl.h @@ -16,6 +16,7 @@ #include "sst/core/clock.h" #include "sst/core/componentInfo.h" +#include "sst/core/exit.h" #include "sst/core/oneshot.h" #include "sst/core/output.h" #include "sst/core/profile/profiletool.h" @@ -36,6 +37,9 @@ extern int main(int argc, char** argv); namespace SST { +// Function to exit, guarding against race conditions if multiple threads call it +[[noreturn]] void SST_Exit(int exit_code); + #define _SIM_DBG(fmt, args...) __DBG(DBG_SIM, Sim, fmt, ##args) #define STATALLFLAG "--ALLSTATS--" @@ -243,7 +247,7 @@ class Simulation_impl if ( nullptr != i ) { return i->getComponent(); } else { printf("Simulation::getComponent() couldn't find component with id = %" PRIu64 "\n", id); - exit(1); + SST_Exit(1); } } @@ -255,7 +259,7 @@ class Simulation_impl if ( nullptr != i ) { return i; } else { printf("Simulation::getComponentInfo() couldn't find component with id = %" PRIu64 "\n", id); - exit(1); + SST_Exit(1); } }