changeset 12a0efdde000 in /z/repo/gem5
details: http://repo.gem5.org/gem5?cmd=changeset;node=12a0efdde000
description:
        base: Fix race in PollQueue and remove SIGALRM workaround

        There is a race between enabling asynchronous IO for a file descriptor
        and IO events happening on that descriptor. A SIGIO won't normally be
        delivered if an event is pending when asynchronous IO is
        enabled. Instead, the signal will be raised the next time there is an
        event on the FD. This changeset simulates a SIGIO by setting the
        async_io flag when setting up asynchronous IO for an FD. This causes
        the main event loop to poll all file descriptors to check for pending
        IO. As a consequence of this, the old SIGALRM hack should no longer be
        needed and is therefore removed.

diffstat:

 src/base/pollevent.cc |  10 ++++++++++
 src/sim/async.cc      |   1 -
 src/sim/async.hh      |   2 --
 src/sim/init.cc       |  18 ------------------
 src/sim/simulate.cc   |   3 +--
 5 files changed, 11 insertions(+), 23 deletions(-)

diffs (95 lines):

diff -r ba3be87e2a1d -r 12a0efdde000 src/base/pollevent.cc
--- a/src/base/pollevent.cc     Fri Nov 29 14:35:36 2013 +0100
+++ b/src/base/pollevent.cc     Fri Nov 29 14:36:10 2013 +0100
@@ -214,4 +214,14 @@
 
     if (fcntl(fd, F_SETFL, flags) == -1)
         panic("Could not set up async IO");
+
+    // The file descriptor might already have events pending. We won't
+    // see them if they occurred before we set the FASYNC
+    // flag. Simulate a SIGIO to ensure that the FD will be polled in
+    // next iteration of the simulation loop. We could just poll it,
+    // but this is much simpler.
+    if (set) {
+        async_event = true;
+        async_io = true;
+    }
 }
diff -r ba3be87e2a1d -r 12a0efdde000 src/sim/async.cc
--- a/src/sim/async.cc  Fri Nov 29 14:35:36 2013 +0100
+++ b/src/sim/async.cc  Fri Nov 29 14:36:10 2013 +0100
@@ -33,6 +33,5 @@
 volatile bool async_statreset = false;
 volatile bool async_exit = false;
 volatile bool async_io = false;
-volatile bool async_alarm = false;
 volatile bool async_exception = false;
 
diff -r ba3be87e2a1d -r 12a0efdde000 src/sim/async.hh
--- a/src/sim/async.hh  Fri Nov 29 14:35:36 2013 +0100
+++ b/src/sim/async.hh  Fri Nov 29 14:36:10 2013 +0100
@@ -40,14 +40,12 @@
 /// @name Asynchronous event flags.
 /// To avoid races, signal handlers simply set these flags, which are
 /// then checked in the main event loop.  Defined in main.cc.
-/// @note See the PollQueue object (in pollevent.hh) for the use of async_io 
and async_alarm.
 //@{
 extern volatile bool async_event;       ///< Some asynchronous event has 
happened.
 extern volatile bool async_statdump;    ///< Async request to dump stats.
 extern volatile bool async_statreset;   ///< Async request to reset stats.
 extern volatile bool async_exit;        ///< Async request to exit simulator.
 extern volatile bool async_io;          ///< Async I/O request (SIGIO).
-extern volatile bool async_alarm;       ///< Async alarm event (SIGALRM).
 extern volatile bool async_exception;   ///< Python exception.
 //@}
 
diff -r ba3be87e2a1d -r 12a0efdde000 src/sim/init.cc
--- a/src/sim/init.cc   Fri Nov 29 14:35:36 2013 +0100
+++ b/src/sim/init.cc   Fri Nov 29 14:36:10 2013 +0100
@@ -104,15 +104,6 @@
     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))
 {
@@ -156,15 +147,6 @@
     // 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,
diff -r ba3be87e2a1d -r 12a0efdde000 src/sim/simulate.cc
--- a/src/sim/simulate.cc       Fri Nov 29 14:35:36 2013 +0100
+++ b/src/sim/simulate.cc       Fri Nov 29 14:36:10 2013 +0100
@@ -210,9 +210,8 @@
                 exitSimLoop("user interrupt received");
             }
 
-            if (async_io || async_alarm) {
+            if (async_io) {
                 async_io = false;
-                async_alarm = false;
                 pollQueue.service();
             }
 
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to