void gasneti_bootstrapAbort_mpi(int exitcode) { (void) MPI_Abort(gasnetc_mpi_comm, exitcode); gasneti_reghandler(SIGABRT, SIG_DFL); gasneti_fatalerror("gasneti_bootstrapAbort_mpi aborting..."); /* NOT REACHED */ }
/* This signal handler is for a last-ditch exit when a signal arrives while * attempting the graceful exit. That includes SIGALRM if we get wedged. * DOES NOT RETURN */ static void gasnetc_exit_sighandler(int sig) { static int once = 1; if (once) { /* We ask the bootstrap support to kill us, but only once */ once = 0; gasneti_reghandler(SIGALRM, gasnetc_exit_sighandler); alarm(5); gasneti_bootstrapAbort(127); } else { gasneti_killmyprocess(127); gasneti_reghandler(SIGABRT, SIG_DFL); gasneti_fatalerror("gasnetc_exit aborting..."); } /* NOT REACHED */ }
extern void gasnetc_exit(int exitcode) { gasnetc_exit_in_progress = 1; gasneti_sync_writes(); /* once we start a shutdown, ignore all future SIGQUIT signals or we risk reentrancy */ gasneti_reghandler(SIGQUIT, SIG_IGN); { /* ensure only one thread ever continues past this point */ static gasneti_mutex_t exit_lock = GASNETI_MUTEX_INITIALIZER; gasneti_mutex_lock(&exit_lock); } GASNETI_TRACE_PRINTF(C,("gasnet_exit(%i)\n", exitcode)); /* Establish a last-ditch signal handler in case of failure. */ gasneti_reghandler(SIGALRM, gasnetc_exit_sighandler); #if GASNET_DEBUG gasneti_reghandler(SIGABRT, SIG_DFL); #else gasneti_reghandler(SIGABRT, gasnetc_exit_sighandler); #endif gasneti_reghandler(SIGILL, gasnetc_exit_sighandler); gasneti_reghandler(SIGSEGV, gasnetc_exit_sighandler); gasneti_reghandler(SIGFPE, gasnetc_exit_sighandler); gasneti_reghandler(SIGBUS, gasnetc_exit_sighandler); /* Prior to attach we cannot send AMs to coordinate the exit */ if (! gasneti_attach_done) { fprintf(stderr, "WARNING: GASNet ofi-conduit may not shutdown cleanly when gasnet_exit() is called before gasnet_attach()\n"); gasneti_bootstrapAbort(exitcode); gasneti_killmyprocess(exitcode); } const int timeout = (unsigned int)gasnetc_exittimeout; alarm(2 + timeout); if (gasnetc_exit_coordinate(exitcode)) { alarm(timeout); gasnetc_ofi_exit(); } alarm(0); gasneti_flush_streams(); gasneti_trace_finish(); gasneti_sched_yield(); alarm(timeout); gasneti_bootstrapFini(); alarm(0); gasneti_killmyprocess(exitcode); gasneti_fatalerror("gasnetc_exit failed!"); }
extern void gasnetc_exit(int exitcode) { /* once we start a shutdown, ignore all future SIGQUIT signals or we risk reentrancy */ gasneti_reghandler(SIGQUIT, SIG_IGN); { /* ensure only one thread ever continues past this point */ static gasneti_mutex_t exit_lock = GASNETI_MUTEX_INITIALIZER; gasneti_mutex_lock(&exit_lock); } GASNETI_TRACE_PRINTF(C,("gasnet_exit(%i)\n", exitcode)); gasnetc_p4_exit(); gasneti_flush_streams(); gasneti_trace_finish(); gasneti_sched_yield(); gasneti_killmyprocess(exitcode); gasneti_fatalerror("gasnetc_exit failed!"); }
extern void gasnetc_exit(int exitcode) { /* once we start a shutdown, ignore all future SIGQUIT signals or we risk reentrancy */ gasneti_reghandler(SIGQUIT, SIG_IGN); gasnetc_exitcalled = 1; { /* ensure only one thread ever continues past this point */ static gasneti_mutex_t exit_lock = GASNETI_MUTEX_INITIALIZER; gasneti_mutex_lock(&exit_lock); } GASNETI_TRACE_PRINTF(C,("gasnet_exit(%i)\n", exitcode)); #ifdef GASNETE_EXIT_CALLBACK /* callback for native conduits using an mpi-conduit core this should cleanup extended API resources (only) and then return so that MPI can be shutdown properly */ GASNETE_EXIT_CALLBACK(exitcode); #endif gasneti_flush_streams(); gasneti_trace_finish(); gasneti_sched_yield(); { int i; /* try to prevent races where we exit while other local pthreads are in MPI can't use a blocking lock here, because may be in a signal context */ for (i=0; i < 5; i++) { #if GASNET_DEBUG /* ignore recursive lock attempts */ if (gasnetc_AMlock.owner == GASNETI_THREADIDQUERY()) break; #endif if (!gasneti_mutex_trylock(&gasnetc_AMlock)) break; gasneti_sched_yield(); } } AMMPI_SPMDExit(exitcode); gasneti_fatalerror("AMMPI_SPMDExit failed"); }
extern void gasnetc_exit(int exitcode) { /* once we start a shutdown, ignore all future SIGQUIT signals or we risk reentrancy */ gasneti_reghandler(SIGQUIT, SIG_IGN); gasnetc_exitcalled = 1; { /* ensure only one thread ever continues past this point */ static gasneti_mutex_t exit_lock = GASNETI_MUTEX_INITIALIZER; gasneti_mutex_lock(&exit_lock); } GASNETI_TRACE_PRINTF(C,("gasnet_exit(%i)\n", exitcode)); gasneti_flush_streams(); gasneti_trace_finish(); gasneti_sched_yield(); /* bug2181: try to prevent races where we exit while other local pthreads are in AMUDP can't use a blocking lock here, because may be in a signal context */ AMLOCK_CAUTIOUS(); AMUDP_SPMDExit(exitcode); gasneti_fatalerror("AMUDP_SPMDExit failed!"); }