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,