PollQueue::~PollQueue()
{
- removeHandler();
for (int i = 0; i < num_fds; i++)
setupAsyncIO(poll_fds[0].fd, false);
max_size *= 2;
} else {
max_size = 16;
- setupHandler();
}
poll_fds = new pollfd[max_size];
}
}
-struct sigaction PollQueue::oldio;
-struct sigaction PollQueue::oldalrm;
-bool PollQueue::handler = false;
-
void
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);
-}
-
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;
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.
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,