summaryrefslogtreecommitdiff
path: root/src/sim/init.cc
diff options
context:
space:
mode:
authorAndreas Sandberg <andreas@sandberg.pp.se>2013-11-29 14:35:36 +0100
committerAndreas Sandberg <andreas@sandberg.pp.se>2013-11-29 14:35:36 +0100
commit9c57d5b5a66df60f77d1209f6660e4986da4bf8e (patch)
treeb081dd2ebd6bccb433701f9ae62c5defd1314881 /src/sim/init.cc
parent2823982a3cbd60a1b21db1a73b78440468df158a (diff)
downloadgem5-9c57d5b5a66df60f77d1209f6660e4986da4bf8e.tar.xz
base: Clean up signal handling
The PollEvent class dynamically installs a SIGIO and SIGALRM handler when a file handler is registered. Most signal handlers currently get registered in the initSignals() function. This changeset moves the SIGIO/SIGALRM handlers to initSignals() to live with the other signal handlers. The original code installs SIGIO and SIGALRM with the SA_RESTART option to prevent syscalls from returning EINTR. This changeset consistently uses this flag for all signal handlers to ensure that other signals that trigger asynchronous behavior (e.g., statistics dumping) do not cause undesirable EINTR returns.
Diffstat (limited to 'src/sim/init.cc')
-rw-r--r--src/sim/init.cc52
1 files changed, 48 insertions, 4 deletions
diff --git a/src/sim/init.cc b/src/sim/init.cc
index 0cebc417d..660fab62b 100644
--- a/src/sim/init.cc
+++ b/src/sim/init.cc
@@ -96,6 +96,37 @@ abortHandler(int sigtype)
ccprintf(cerr, "Program aborted at cycle %d\n", curTick());
}
+// Handle SIGIO
+static void
+ioHandler(int sigtype)
+{
+ async_event = true;
+ async_io = true;
+}
+
+// Handle SIGALRM
+static void
+alrmHandler(int sigtype)
+{
+ async_event = true;
+ async_alarm = true;
+ alarm(1);
+}
+
+static void
+installSignalHandler(int signal, void (*handler)(int sigtype))
+{
+ struct sigaction sa;
+
+ memset(&sa, 0, sizeof(sa));
+ sigemptyset(&sa.sa_mask);
+ sa.sa_handler = handler;
+ sa.sa_flags = SA_RESTART;
+
+ if (sigaction(signal, &sa, NULL) == -1)
+ panic("Failed to setup handler for signal %i\n", signal);
+}
+
/*
* M5 can do several special things when various signals are sent.
* None are mandatory.
@@ -111,16 +142,29 @@ initSignals()
signal(SIGTRAP, SIG_IGN);
// Dump intermediate stats
- signal(SIGUSR1, dumpStatsHandler);
+ installSignalHandler(SIGUSR1, dumpStatsHandler);
// Dump intermediate stats and reset them
- signal(SIGUSR2, dumprstStatsHandler);
+ installSignalHandler(SIGUSR2, dumprstStatsHandler);
// Exit cleanly on Interrupt (Ctrl-C)
- signal(SIGINT, exitNowHandler);
+ installSignalHandler(SIGINT, exitNowHandler);
// Print out cycle number on abort
- signal(SIGABRT, abortHandler);
+ installSignalHandler(SIGABRT, abortHandler);
+
+ // Install a SIGIO handler to handle asynchronous file IO. See the
+ // PollQueue class.
+ installSignalHandler(SIGIO, ioHandler);
+
+ // Setup an alarm handler that triggers every second. This
+ // triggers a PollQueue service just like a SIGIO. It is
+ // /probably/ used to work around a bug in the poll queue (likely
+ // a race between setting up a asynchronous IO and data becoming
+ // available), but its use isn't documented anywhere.
+ // TODO: Find out why this is needed and fix the original bug.
+ installSignalHandler(SIGALRM, alrmHandler);
+ alarm(1);
}
// The python library is totally messed up with respect to constness,