sim,python: Restore sigint handler in python (#531)

Currently, if you try to use ctrl-c while python code is running nothing
happens. This is not ideal. This change enables users to use ctrl-c
while python is running (e.g., when a large disk image is downloading).
To do this, we moved the `initSignals` function in gem5 from `main` to
the simulate loop. Thus, every time the simulate loop starts (i.e., is
called from python) gem5 will install its signal handlers. Also, when
the control is returned to python, we put python's default SIGINT
handler back.

Change-Id: I14490e48d931eb316e8c641217bf8d8ddaa340ed
Signed-off-by: Jason Lowe-Power <jason@lowepower.com>
This commit is contained in:
Jason Lowe-Power
2023-11-30 07:27:52 -08:00
committed by GitHub
parent dcdebec0f6
commit 9afe9932bc
3 changed files with 30 additions and 5 deletions

View File

@@ -84,7 +84,8 @@ setupAltStack()
static void
installSignalHandler(int signal, void (*handler)(int sigtype),
int flags = SA_RESTART)
int flags = SA_RESTART,
struct sigaction *old_sa = NULL)
{
struct sigaction sa;
@@ -93,7 +94,7 @@ installSignalHandler(int signal, void (*handler)(int sigtype),
sa.sa_handler = handler;
sa.sa_flags = flags;
if (sigaction(signal, &sa, NULL) == -1)
if (sigaction(signal, &sa, old_sa) == -1)
panic("Failed to setup handler for signal %i\n", signal);
}
@@ -196,9 +197,6 @@ initSignals()
// Dump intermediate stats and reset them
installSignalHandler(SIGUSR2, dumprstStatsHandler);
// Exit cleanly on Interrupt (Ctrl-C)
installSignalHandler(SIGINT, exitNowHandler);
// Print the current cycle number and a backtrace on abort. Make
// sure the signal is unmasked and the handler reset when a signal
// is delivered to be able to invoke the default handler.
@@ -218,4 +216,19 @@ initSignals()
installSignalHandler(SIGIO, ioHandler);
}
struct sigaction old_int_sa;
void initSigInt()
{
// Exit cleanly on Interrupt (Ctrl-C)
installSignalHandler(SIGINT, exitNowHandler, SA_RESTART, &old_int_sa);
}
void restoreSigInt()
{
// Restore the old SIGINT handler
sigaction(SIGINT, &old_int_sa, NULL);
}
} // namespace gem5

View File

@@ -38,6 +38,10 @@ void exitNowHandler(int sigtype);
void abortHandler(int sigtype);
void initSignals();
// separate out sigint handler so that we can restore the python one
void initSigInt();
void restoreSigInt();
} // namespace gem5
#endif // __SIM_INIT_SIGNALS_HH__

View File

@@ -50,6 +50,7 @@
#include "base/types.hh"
#include "sim/async.hh"
#include "sim/eventq.hh"
#include "sim/init_signals.hh"
#include "sim/sim_events.hh"
#include "sim/sim_exit.hh"
#include "sim/stat_control.hh"
@@ -187,6 +188,10 @@ GlobalSimLoopExitEvent *global_exit_event= nullptr;
GlobalSimLoopExitEvent *
simulate(Tick num_cycles)
{
// install the sigint handler to catch ctrl-c and exit the sim loop cleanly
// Note: This should be done before initializing the threads
initSigInt();
if (global_exit_event)//cleaning last global exit event
global_exit_event->clean();
std::unique_ptr<GlobalSyncEvent, DescheduleDeleter> quantum_event;
@@ -229,6 +234,9 @@ simulate(Tick num_cycles)
Event *local_event = doSimLoop(mainEventQueue[0]);
assert(local_event);
// Restore normal ctrl-c operation as soon as the event queue is done
restoreSigInt();
inParallelMode = false;
// locate the global exit event and return it to Python