gem5  v20.1.0.0
pollevent.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2002-2005 The Regents of The University of Michigan
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met: redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer;
9  * redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution;
12  * neither the name of the copyright holders nor the names of its
13  * contributors may be used to endorse or promote products derived from
14  * this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #include <sys/ioctl.h>
30 #include <sys/types.h>
31 
32 #if defined(__sun__) || defined(__SUNPRO_CC)
33 #include <sys/file.h>
34 
35 #endif
36 
37 #include "base/pollevent.hh"
38 
39 #include <fcntl.h>
40 #include <unistd.h>
41 
42 #include <cerrno>
43 #include <csignal>
44 #include <cstring>
45 
46 #include "base/logging.hh"
47 #include "base/types.hh"
48 #include "sim/async.hh"
49 #include "sim/core.hh"
50 #include "sim/eventq.hh"
51 #include "sim/serialize.hh"
52 
53 using namespace std;
54 
56 
58 //
59 PollEvent::PollEvent(int _fd, int _events)
60  : queue(NULL), enabled(true)
61 {
62  pfd.fd = _fd;
63  pfd.events = _events;
64  pfd.revents = 0;
65 }
66 
68 {
69  if (queue)
70  queue->remove(this);
71 }
72 
73 void
75 {
76  if (!enabled) return;
77  enabled = false;
78 
79  if (queue)
80  queue->copy();
81 }
82 
83 void
85 {
86  if (enabled) return;
87  enabled = true;
88 
89  if (queue)
90  queue->copy();
91 }
92 
93 void
95 {
97  SERIALIZE_SCALAR(pfd.events);
99 }
100 
101 void
103 {
105  UNSERIALIZE_SCALAR(pfd.events);
107 }
108 
110 //
112  : poll_fds(NULL), max_size(0), num_fds(0)
113 { }
114 
116 {
117  for (int i = 0; i < num_fds; i++)
118  setupAsyncIO(poll_fds[0].fd, false);
119 
120  delete [] poll_fds;
121 }
122 
123 void
125 {
126  eventvec_t::iterator i = events.begin();
127  eventvec_t::iterator end = events.end();
128 
129  num_fds = 0;
130 
131  while (i < end) {
132  if ((*i)->enabled)
133  poll_fds[num_fds++] = (*i)->pfd;
134  ++i;
135  }
136 }
137 
138 void
140 {
141  eventvec_t::iterator i = events.begin();
142  eventvec_t::iterator end = events.end();
143 
144  while (i < end) {
145  if (*i == event) {
146  events.erase(i);
147  copy();
148  event->queue = NULL;
149  return;
150  }
151 
152  ++i;
153  }
154 
155  panic("Event does not exist. Cannot remove.");
156 }
157 
158 void
160 {
161  if (event->queue)
162  panic("Event already scheduled!");
163 
164  event->queue = this;
165  events.push_back(event);
166  setupAsyncIO(event->pfd.fd, true);
167 
168  // if we ran out of space in the fd array, double the capacity
169  // if this is the first time that we've scheduled an event, create
170  // the array with an initial size of 16
171  if (++num_fds > max_size) {
172  if (max_size > 0) {
173  delete [] poll_fds;
174  max_size *= 2;
175  } else {
176  max_size = 16;
177  }
178 
179  poll_fds = new pollfd[max_size];
180  }
181 
182  copy();
183 }
184 
185 void
187 {
188  int ret = poll(poll_fds, num_fds, 0);
189 
190  if (ret <= 0)
191  return;
192 
193  for (int i = 0; i < num_fds; i++) {
194  int revents = poll_fds[i].revents;
195  if (revents) {
196  events[i]->process(revents);
197  if (--ret <= 0)
198  break;
199  }
200  }
201 }
202 
203 template <class ArgT>
204 static int fcntlHelper(int fd, int cmd, ArgT arg)
205 {
206  int retval = fcntl(fd, cmd, arg);
207  if (retval == -1) {
208  char *errstr = strerror(errno);
209  panic("fcntl(%d, %d, %s): \"%s\" when setting up async IO.\n",
210  errstr, fd, cmd, arg);
211  }
212  return retval;
213 }
214 
215 static int fcntlHelper(int fd, int cmd)
216 {
217  int retval = fcntl(fd, cmd);
218  if (retval == -1) {
219  char *errstr = strerror(errno);
220  panic("fcntl(%d, %d): \"%s\" when setting up async IO.\n",
221  errstr, fd, cmd);
222  }
223  return retval;
224 }
225 
226 void
228 {
229  int flags = fcntlHelper(fd, F_GETFL);
230 
231  if (set)
232  flags |= FASYNC;
233  else
234  flags &= ~(FASYNC);
235 
236  if (set)
237  fcntlHelper(fd, F_SETOWN, getpid());
238 
239  fcntlHelper(fd, F_SETFL, flags);
240 
241  // The file descriptor might already have events pending. We won't
242  // see them if they occurred before we set the FASYNC
243  // flag. Simulate a SIGIO to ensure that the FD will be polled in
244  // next iteration of the simulation loop. We could just poll it,
245  // but this is much simpler.
246  if (set) {
247  async_event = true;
248  async_io = true;
249  /* Wake up some event queue to handle event */
250  getEventQueue(0)->wakeup();
251  }
252 }
async_event
volatile bool async_event
Some asynchronous event has happened.
Definition: async.cc:29
async_io
volatile bool async_io
Async I/O request (SIGIO).
Definition: async.cc:33
getEventQueue
EventQueue * getEventQueue(uint32_t index)
Function for returning eventq queue for the provided index.
Definition: eventq.cc:61
PollQueue::~PollQueue
~PollQueue()
Definition: pollevent.cc:115
serialize.hh
UNSERIALIZE_SCALAR
#define UNSERIALIZE_SCALAR(scalar)
Definition: serialize.hh:797
ArmISA::i
Bitfield< 7 > i
Definition: miscregs_types.hh:63
ArmISA::fd
Bitfield< 14, 12 > fd
Definition: types.hh:159
PollQueue::copy
void copy()
Definition: pollevent.cc:124
PollEvent::disable
void disable()
Definition: pollevent.cc:74
PollQueue::PollQueue
PollQueue()
Definition: pollevent.cc:111
PollEvent::enable
void enable()
Definition: pollevent.cc:84
PollQueue::schedule
void schedule(PollEvent *event)
Definition: pollevent.cc:159
PollQueue::setupAsyncIO
static void setupAsyncIO(int fd, bool set)
Definition: pollevent.cc:227
EventQueue::wakeup
virtual void wakeup(Tick when=(Tick) -1)
Function to signal that the event loop should be woken up because an event has been scheduled by an a...
Definition: eventq.hh:923
pollQueue
PollQueue pollQueue
Definition: pollevent.cc:55
cp
Definition: cprintf.cc:40
Stats::enabled
bool enabled()
Definition: statistics.cc:545
PollEvent::PollEvent
PollEvent(int fd, int event)
Definition: pollevent.cc:59
PollQueue::num_fds
int num_fds
Definition: pollevent.hh:84
PollQueue::poll_fds
pollfd * poll_fds
Definition: pollevent.hh:82
MipsISA::event
Bitfield< 10, 5 > event
Definition: pra_constants.hh:297
pollevent.hh
PollEvent::queue
PollQueue * queue
Definition: pollevent.hh:48
core.hh
SERIALIZE_SCALAR
#define SERIALIZE_SCALAR(scalar)
Definition: serialize.hh:790
PollEvent::serialize
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: pollevent.cc:94
PollQueue::events
eventvec_t events
Definition: pollevent.hh:80
async.hh
fcntlHelper
static int fcntlHelper(int fd, int cmd, ArgT arg)
Definition: pollevent.cc:204
PollEvent::unserialize
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: pollevent.cc:102
PollQueue::max_size
int max_size
Definition: pollevent.hh:83
PollQueue::remove
void remove(PollEvent *event)
Definition: pollevent.cc:139
std
Overload hash function for BasicBlockRange type.
Definition: vec_reg.hh:587
types.hh
PollQueue
Definition: pollevent.hh:76
logging.hh
PollEvent::pfd
pollfd pfd
Definition: pollevent.hh:47
CheckpointOut
std::ostream CheckpointOut
Definition: serialize.hh:63
PollEvent
Definition: pollevent.hh:41
PollQueue::service
void service()
Definition: pollevent.cc:186
PollEvent::enabled
bool enabled
Definition: pollevent.hh:49
CheckpointIn
Definition: serialize.hh:67
PollEvent::~PollEvent
virtual ~PollEvent()
Definition: pollevent.cc:67
panic
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:171
eventq.hh

Generated on Wed Sep 30 2020 14:02:07 for gem5 by doxygen 1.8.17