diff options
Diffstat (limited to 'base/pollevent.cc')
-rw-r--r-- | base/pollevent.cc | 273 |
1 files changed, 0 insertions, 273 deletions
diff --git a/base/pollevent.cc b/base/pollevent.cc deleted file mode 100644 index 99044fc09..000000000 --- a/base/pollevent.cc +++ /dev/null @@ -1,273 +0,0 @@ -/* - * Copyright (c) 2002-2005 The Regents of The University of Michigan - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <sys/ioctl.h> -#include <sys/types.h> - -#include <fcntl.h> -#include <signal.h> -#include <unistd.h> - -#include "sim/async.hh" -#include "sim/host.hh" -#include "base/misc.hh" -#include "base/pollevent.hh" -#include "sim/root.hh" -#include "sim/serialize.hh" - -using namespace std; - -PollQueue pollQueue; - -///////////////////////////////////////////////////// -// -PollEvent::PollEvent(int _fd, int _events) - : queue(NULL), enabled(true) -{ - pfd.fd = _fd; - pfd.events = _events; -} - -PollEvent::~PollEvent() -{ - if (queue) - queue->remove(this); -} - -void -PollEvent::disable() -{ - if (!enabled) return; - enabled = false; - - if (queue) - queue->copy(); -} - -void -PollEvent::enable() -{ - if (enabled) return; - enabled = true; - - if (queue) - queue->copy(); -} - -void -PollEvent::serialize(ostream &os) -{ - SERIALIZE_SCALAR(pfd.fd); - SERIALIZE_SCALAR(pfd.events); - SERIALIZE_SCALAR(enabled); -} - -void -PollEvent::unserialize(Checkpoint *cp, const std::string §ion) -{ - UNSERIALIZE_SCALAR(pfd.fd); - UNSERIALIZE_SCALAR(pfd.events); - UNSERIALIZE_SCALAR(enabled); -} - -///////////////////////////////////////////////////// -// -PollQueue::PollQueue() - : poll_fds(NULL), max_size(0), num_fds(0) -{ } - -PollQueue::~PollQueue() -{ - removeHandler(); - for (int i = 0; i < num_fds; i++) - setupAsyncIO(poll_fds[0].fd, false); - - delete [] poll_fds; -} - -void -PollQueue::copy() -{ - eventvec_t::iterator i = events.begin(); - eventvec_t::iterator end = events.end(); - - num_fds = 0; - - while (i < end) { - if ((*i)->enabled) - poll_fds[num_fds++] = (*i)->pfd; - ++i; - } -} - -void -PollQueue::remove(PollEvent *event) -{ - eventvec_t::iterator i = events.begin(); - eventvec_t::iterator end = events.end(); - - while (i < end) { - if (*i == event) { - events.erase(i); - copy(); - event->queue = NULL; - return; - } - - ++i; - } - - panic("Event does not exist. Cannot remove."); -} - -void -PollQueue::schedule(PollEvent *event) -{ - if (event->queue) - panic("Event already scheduled!"); - - event->queue = this; - events.push_back(event); - setupAsyncIO(event->pfd.fd, true); - - // if we ran out of space in the fd array, double the capacity - // if this is the first time that we've scheduled an event, create - // the array with an initial size of 16 - if (++num_fds > max_size) { - if (max_size > 0) { - delete [] poll_fds; - max_size *= 2; - } else { - max_size = 16; - setupHandler(); - } - - poll_fds = new pollfd[max_size]; - } - - copy(); -} - -void -PollQueue::service() -{ - int ret = poll(poll_fds, num_fds, 0); - - if (ret <= 0) - return; - - for (int i = 0; i < num_fds; i++) { - int revents = poll_fds[i].revents; - if (revents) { - events[i]->process(revents); - if (--ret <= 0) - break; - } - } -} - -struct sigaction PollQueue::oldio; -struct sigaction PollQueue::oldalrm; -bool PollQueue::handler = false; - -void -PollQueue::setupAsyncIO(int fd, bool set) -{ - int flags = fcntl(fd, F_GETFL); - if (flags == -1) - panic("Could not set up async IO"); - - if (set) - flags |= FASYNC; - else - flags &= ~(FASYNC); - - if (fcntl(fd, F_SETFL, flags) == -1) - panic("Could not set up async IO"); - - if (set) { - if (fcntl(fd, F_SETOWN, getpid()) == -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); -} - |