changeset ba3be87e2a1d in /z/repo/gem5
details: http://repo.gem5.org/gem5?cmd=changeset;node=ba3be87e2a1d
description:
        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:

 src/base/pollevent.cc |  62 ---------------------------------------------------
 src/base/pollevent.hh |   9 -------
 src/sim/init.cc       |  52 +++++++++++++++++++++++++++++++++++++++---
 3 files changed, 48 insertions(+), 75 deletions(-)

diffs (186 lines):

diff -r 0b2e590c85be -r ba3be87e2a1d src/base/pollevent.cc
--- a/src/base/pollevent.cc     Tue Nov 26 17:05:25 2013 -0600
+++ b/src/base/pollevent.cc     Fri Nov 29 14:35:36 2013 +0100
@@ -109,7 +109,6 @@
 
 PollQueue::~PollQueue()
 {
-    removeHandler();
     for (int i = 0; i < num_fds; i++)
         setupAsyncIO(poll_fds[0].fd, false);
 
@@ -170,7 +169,6 @@
             max_size *= 2;
         } else {
             max_size = 16;
-            setupHandler();
         }
 
         poll_fds = new pollfd[max_size];
@@ -197,10 +195,6 @@
     }
 }
 
-struct sigaction PollQueue::oldio;
-struct sigaction PollQueue::oldalrm;
-bool PollQueue::handler = false;
-
 void
 PollQueue::setupAsyncIO(int fd, bool set)
 {
@@ -221,59 +215,3 @@
     if (fcntl(fd, F_SETFL, flags) == -1)
         panic("Could not set up async IO");
 }
-
-void
-PollQueue::setupHandler()
-{
-    struct sigaction act;
-
-    act.sa_handler = handleIO;
-    sigemptyset(&act.sa_mask);
-    act.sa_flags = SA_RESTART;
-
-    if (sigaction(SIGIO, &act, &oldio) == -1)
-        panic("could not do sigaction");
-
-    act.sa_handler = handleALRM;
-    sigemptyset(&act.sa_mask);
-    act.sa_flags = SA_RESTART;
-
-    if (sigaction(SIGALRM, &act, &oldalrm) == -1)
-        panic("could not do sigaction");
-
-    alarm(1);
-
-    handler = true;
-}
-
-void
-PollQueue::removeHandler()
-{
-    if (sigaction(SIGIO, &oldio, NULL) == -1)
-        panic("could not remove handler");
-
-    if (sigaction(SIGIO, &oldalrm, NULL) == -1)
-        panic("could not remove handler");
-}
-
-void
-PollQueue::handleIO(int sig)
-{
-    if (sig != SIGIO)
-        panic("Wrong Handler");
-
-    async_event = true;
-    async_io = true;
-}
-
-void
-PollQueue::handleALRM(int sig)
-{
-    if (sig != SIGALRM)
-        panic("Wrong Handler");
-
-    async_event = true;
-    async_alarm = true;
-    alarm(1);
-}
-
diff -r 0b2e590c85be -r ba3be87e2a1d src/base/pollevent.hh
--- a/src/base/pollevent.hh     Tue Nov 26 17:05:25 2013 -0600
+++ b/src/base/pollevent.hh     Fri Nov 29 14:35:36 2013 +0100
@@ -83,17 +83,8 @@
     void schedule(PollEvent *event);
     void service();
 
-  protected:
-    static bool handler;
-    static struct sigaction oldio;
-    static struct sigaction oldalrm;
-
   public:
     static void setupAsyncIO(int fd, bool set);
-    static void handleIO(int);
-    static void handleALRM(int);
-    static void removeHandler();
-    static void setupHandler();
 };
 
 extern PollQueue pollQueue;
diff -r 0b2e590c85be -r ba3be87e2a1d src/sim/init.cc
--- a/src/sim/init.cc   Tue Nov 26 17:05:25 2013 -0600
+++ b/src/sim/init.cc   Fri Nov 29 14:35:36 2013 +0100
@@ -96,6 +96,37 @@
     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 @@
     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,
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to