gem5  v21.0.1.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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 
54 
56 //
57 PollEvent::PollEvent(int _fd, int _events)
58  : queue(NULL), enabled(true)
59 {
60  pfd.fd = _fd;
61  pfd.events = _events;
62  pfd.revents = 0;
63 }
64 
66 {
67  if (queue)
68  queue->remove(this);
69 }
70 
71 void
73 {
74  if (!enabled) return;
75  enabled = false;
76 
77  if (queue)
78  queue->copy();
79 }
80 
81 void
83 {
84  if (enabled) return;
85  enabled = true;
86 
87  if (queue)
88  queue->copy();
89 }
90 
91 void
93 {
95  SERIALIZE_SCALAR(pfd.events);
97 }
98 
99 void
101 {
103  UNSERIALIZE_SCALAR(pfd.events);
105 }
106 
108 //
110  : poll_fds(NULL), max_size(0), num_fds(0)
111 { }
112 
114 {
115  for (int i = 0; i < num_fds; i++)
116  setupAsyncIO(poll_fds[0].fd, false);
117 
118  delete [] poll_fds;
119 }
120 
121 void
123 {
124  eventvec_t::iterator i = events.begin();
125  eventvec_t::iterator end = events.end();
126 
127  num_fds = 0;
128 
129  while (i < end) {
130  if ((*i)->enabled)
131  poll_fds[num_fds++] = (*i)->pfd;
132  ++i;
133  }
134 }
135 
136 void
138 {
139  eventvec_t::iterator i = events.begin();
140  eventvec_t::iterator end = events.end();
141 
142  while (i < end) {
143  if (*i == event) {
144  events.erase(i);
145  copy();
146  event->queue = NULL;
147  return;
148  }
149 
150  ++i;
151  }
152 
153  panic("Event does not exist. Cannot remove.");
154 }
155 
156 void
158 {
159  if (event->queue)
160  panic("Event already scheduled!");
161 
162  event->queue = this;
163  events.push_back(event);
164  setupAsyncIO(event->pfd.fd, true);
165 
166  // if we ran out of space in the fd array, double the capacity
167  // if this is the first time that we've scheduled an event, create
168  // the array with an initial size of 16
169  if (++num_fds > max_size) {
170  if (max_size > 0) {
171  delete [] poll_fds;
172  max_size *= 2;
173  } else {
174  max_size = 16;
175  }
176 
177  poll_fds = new pollfd[max_size];
178  }
179 
180  copy();
181 }
182 
183 void
185 {
186  int ret = poll(poll_fds, num_fds, 0);
187 
188  if (ret <= 0)
189  return;
190 
191  for (int i = 0; i < num_fds; i++) {
192  int revents = poll_fds[i].revents;
193  if (revents) {
194  events[i]->process(revents);
195  if (--ret <= 0)
196  break;
197  }
198  }
199 }
200 
201 template <class ArgT>
202 static int fcntlHelper(int fd, int cmd, ArgT arg)
203 {
204  int retval = fcntl(fd, cmd, arg);
205  if (retval == -1) {
206  char *errstr = strerror(errno);
207  panic("fcntl(%d, %d, %s): \"%s\" when setting up async IO.\n",
208  errstr, fd, cmd, arg);
209  }
210  return retval;
211 }
212 
213 static int fcntlHelper(int fd, int cmd)
214 {
215  int retval = fcntl(fd, cmd);
216  if (retval == -1) {
217  char *errstr = strerror(errno);
218  panic("fcntl(%d, %d): \"%s\" when setting up async IO.\n",
219  errstr, fd, cmd);
220  }
221  return retval;
222 }
223 
224 void
226 {
227  int flags = fcntlHelper(fd, F_GETFL);
228 
229  if (set)
230  flags |= FASYNC;
231  else
232  flags &= ~(FASYNC);
233 
234  if (set)
235  fcntlHelper(fd, F_SETOWN, getpid());
236 
237  fcntlHelper(fd, F_SETFL, flags);
238 
239  // The file descriptor might already have events pending. We won't
240  // see them if they occurred before we set the FASYNC
241  // flag. Simulate a SIGIO to ensure that the FD will be polled in
242  // next iteration of the simulation loop. We could just poll it,
243  // but this is much simpler.
244  if (set) {
245  async_event = true;
246  async_io = true;
247  /* Wake up some event queue to handle event */
248  getEventQueue(0)->wakeup();
249  }
250 }
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:60
PollQueue::~PollQueue
~PollQueue()
Definition: pollevent.cc:113
serialize.hh
UNSERIALIZE_SCALAR
#define UNSERIALIZE_SCALAR(scalar)
Definition: serialize.hh:591
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:122
PollEvent::disable
void disable()
Definition: pollevent.cc:72
PollQueue::PollQueue
PollQueue()
Definition: pollevent.cc:109
PollEvent::enable
void enable()
Definition: pollevent.cc:82
PollQueue::schedule
void schedule(PollEvent *event)
Definition: pollevent.cc:157
PollQueue::setupAsyncIO
static void setupAsyncIO(int fd, bool set)
Definition: pollevent.cc:225
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:927
pollQueue
PollQueue pollQueue
Definition: pollevent.cc:53
cp
Definition: cprintf.cc:37
Stats::enabled
bool enabled()
Definition: statistics.cc:275
PollEvent::PollEvent
PollEvent(int fd, int event)
Definition: pollevent.cc:57
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:584
PollEvent::serialize
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: pollevent.cc:92
PollQueue::events
eventvec_t events
Definition: pollevent.hh:80
async.hh
fcntlHelper
static int fcntlHelper(int fd, int cmd, ArgT arg)
Definition: pollevent.cc:202
PollEvent::unserialize
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: pollevent.cc:100
PollQueue::max_size
int max_size
Definition: pollevent.hh:83
PollQueue::remove
void remove(PollEvent *event)
Definition: pollevent.cc:137
types.hh
PollQueue
Definition: pollevent.hh:76
logging.hh
PollEvent::pfd
pollfd pfd
Definition: pollevent.hh:47
CheckpointOut
std::ostream CheckpointOut
Definition: serialize.hh:64
PollEvent
Definition: pollevent.hh:41
PollQueue::service
void service()
Definition: pollevent.cc:184
PollEvent::enabled
bool enabled
Definition: pollevent.hh:49
CheckpointIn
Definition: serialize.hh:68
PollEvent::~PollEvent
virtual ~PollEvent()
Definition: pollevent.cc:65
panic
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:171
eventq.hh

Generated on Tue Jun 22 2021 15:28:25 for gem5 by doxygen 1.8.17