summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/base/pollevent.cc62
-rw-r--r--src/base/pollevent.hh9
-rw-r--r--src/sim/init.cc52
3 files changed, 48 insertions, 75 deletions
diff --git a/src/base/pollevent.cc b/src/base/pollevent.cc
index cb44d8728..67e97f98f 100644
--- a/src/base/pollevent.cc
+++ b/src/base/pollevent.cc
@@ -109,7 +109,6 @@ PollQueue::PollQueue()
PollQueue::~PollQueue()
{
- removeHandler();
for (int i = 0; i < num_fds; i++)
setupAsyncIO(poll_fds[0].fd, false);
@@ -170,7 +169,6 @@ PollQueue::schedule(PollEvent *event)
max_size *= 2;
} else {
max_size = 16;
- setupHandler();
}
poll_fds = new pollfd[max_size];
@@ -197,10 +195,6 @@ PollQueue::service()
}
}
-struct sigaction PollQueue::oldio;
-struct sigaction PollQueue::oldalrm;
-bool PollQueue::handler = false;
-
void
PollQueue::setupAsyncIO(int fd, bool set)
{
@@ -221,59 +215,3 @@ PollQueue::setupAsyncIO(int fd, bool set)
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 --git a/src/base/pollevent.hh b/src/base/pollevent.hh
index b9c833c8a..5e0faa729 100644
--- a/src/base/pollevent.hh
+++ b/src/base/pollevent.hh
@@ -83,17 +83,8 @@ class PollQueue
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 --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,