gem5  v19.0.0.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  * Authors: Nathan Binkert
29  */
30 
31 #include <sys/ioctl.h>
32 #include <sys/types.h>
33 
34 #if defined(__sun__) || defined(__SUNPRO_CC)
35 #include <sys/file.h>
36 
37 #endif
38 
39 #include "base/pollevent.hh"
40 
41 #include <fcntl.h>
42 #include <unistd.h>
43 
44 #include <cerrno>
45 #include <csignal>
46 #include <cstring>
47 
48 #include "base/logging.hh"
49 #include "base/types.hh"
50 #include "sim/async.hh"
51 #include "sim/core.hh"
52 #include "sim/eventq.hh"
53 #include "sim/serialize.hh"
54 
55 using namespace std;
56 
58 
60 //
61 PollEvent::PollEvent(int _fd, int _events)
62  : queue(NULL), enabled(true)
63 {
64  pfd.fd = _fd;
65  pfd.events = _events;
66  pfd.revents = 0;
67 }
68 
70 {
71  if (queue)
72  queue->remove(this);
73 }
74 
75 void
77 {
78  if (!enabled) return;
79  enabled = false;
80 
81  if (queue)
82  queue->copy();
83 }
84 
85 void
87 {
88  if (enabled) return;
89  enabled = true;
90 
91  if (queue)
92  queue->copy();
93 }
94 
95 void
97 {
99  SERIALIZE_SCALAR(pfd.events);
101 }
102 
103 void
105 {
107  UNSERIALIZE_SCALAR(pfd.events);
109 }
110 
112 //
114  : poll_fds(NULL), max_size(0), num_fds(0)
115 { }
116 
118 {
119  for (int i = 0; i < num_fds; i++)
120  setupAsyncIO(poll_fds[0].fd, false);
121 
122  delete [] poll_fds;
123 }
124 
125 void
127 {
128  eventvec_t::iterator i = events.begin();
129  eventvec_t::iterator end = events.end();
130 
131  num_fds = 0;
132 
133  while (i < end) {
134  if ((*i)->enabled)
135  poll_fds[num_fds++] = (*i)->pfd;
136  ++i;
137  }
138 }
139 
140 void
142 {
143  eventvec_t::iterator i = events.begin();
144  eventvec_t::iterator end = events.end();
145 
146  while (i < end) {
147  if (*i == event) {
148  events.erase(i);
149  copy();
150  event->queue = NULL;
151  return;
152  }
153 
154  ++i;
155  }
156 
157  panic("Event does not exist. Cannot remove.");
158 }
159 
160 void
162 {
163  if (event->queue)
164  panic("Event already scheduled!");
165 
166  event->queue = this;
167  events.push_back(event);
168  setupAsyncIO(event->pfd.fd, true);
169 
170  // if we ran out of space in the fd array, double the capacity
171  // if this is the first time that we've scheduled an event, create
172  // the array with an initial size of 16
173  if (++num_fds > max_size) {
174  if (max_size > 0) {
175  delete [] poll_fds;
176  max_size *= 2;
177  } else {
178  max_size = 16;
179  }
180 
181  poll_fds = new pollfd[max_size];
182  }
183 
184  copy();
185 }
186 
187 void
189 {
190  int ret = poll(poll_fds, num_fds, 0);
191 
192  if (ret <= 0)
193  return;
194 
195  for (int i = 0; i < num_fds; i++) {
196  int revents = poll_fds[i].revents;
197  if (revents) {
198  events[i]->process(revents);
199  if (--ret <= 0)
200  break;
201  }
202  }
203 }
204 
205 template <class ArgT>
206 static int fcntlHelper(int fd, int cmd, ArgT arg)
207 {
208  int retval = fcntl(fd, cmd, arg);
209  if (retval == -1) {
210  char *errstr = strerror(errno);
211  panic("fcntl(%d, %d, %s): \"%s\" when setting up async IO.\n",
212  errstr, fd, cmd, arg);
213  }
214  return retval;
215 }
216 
217 static int fcntlHelper(int fd, int cmd)
218 {
219  int retval = fcntl(fd, cmd);
220  if (retval == -1) {
221  char *errstr = strerror(errno);
222  panic("fcntl(%d, %d): \"%s\" when setting up async IO.\n",
223  errstr, fd, cmd);
224  }
225  return retval;
226 }
227 
228 void
230 {
231  int flags = fcntlHelper(fd, F_GETFL);
232 
233  if (set)
234  flags |= FASYNC;
235  else
236  flags &= ~(FASYNC);
237 
238  if (set)
239  fcntlHelper(fd, F_SETOWN, getpid());
240 
241  fcntlHelper(fd, F_SETFL, flags);
242 
243  // The file descriptor might already have events pending. We won't
244  // see them if they occurred before we set the FASYNC
245  // flag. Simulate a SIGIO to ensure that the FD will be polled in
246  // next iteration of the simulation loop. We could just poll it,
247  // but this is much simpler.
248  if (set) {
249  async_event = true;
250  async_io = true;
251  /* Wake up some event queue to handle event */
252  getEventQueue(0)->wakeup();
253  }
254 }
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:167
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:676
EventQueue * getEventQueue(uint32_t index)
Function for returning eventq queue for the provided index.
Definition: eventq.cc:64
void copy()
Definition: pollevent.cc:126
virtual ~PollEvent()
Definition: pollevent.cc:69
PollQueue pollQueue
Definition: pollevent.cc:57
Bitfield< 7 > i
void service()
Definition: pollevent.cc:188
This file defines flags used to handle asynchronous simulator events.
eventvec_t events
Definition: pollevent.hh:71
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: pollevent.cc:104
Overload hash function for BasicBlockRange type.
Definition: vec_reg.hh:586
Definition: cprintf.cc:42
static int fcntlHelper(int fd, int cmd, ArgT arg)
Definition: pollevent.cc:206
void disable()
Definition: pollevent.cc:76
void schedule(PollEvent *event)
Definition: pollevent.cc:161
pollfd * poll_fds
Definition: pollevent.hh:73
PollQueue * queue
Definition: pollevent.hh:50
#define UNSERIALIZE_SCALAR(scalar)
Definition: serialize.hh:645
pollfd pfd
Definition: pollevent.hh:49
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: pollevent.cc:96
int num_fds
Definition: pollevent.hh:75
bool enabled
Definition: pollevent.hh:51
Defines global host-dependent types: Counter, Tick, and (indirectly) {int,uint}{8,16,32,64}_t.
void enable()
Definition: pollevent.cc:86
Bitfield< 10, 5 > event
bool enabled()
Definition: statistics.cc:546
static void setupAsyncIO(int fd, bool set)
Definition: pollevent.cc:229
PollEvent(int fd, int event)
Definition: pollevent.cc:61
#define SERIALIZE_SCALAR(scalar)
Definition: serialize.hh:643
std::ostream CheckpointOut
Definition: serialize.hh:68
void remove(PollEvent *event)
Definition: pollevent.cc:141
volatile bool async_io
Async I/O request (SIGIO).
Definition: async.cc:35
int max_size
Definition: pollevent.hh:74
Bitfield< 14, 12 > fd
Definition: types.hh:160
volatile bool async_event
Some asynchronous event has happened.
Definition: async.cc:31

Generated on Fri Feb 28 2020 16:26:58 for gem5 by doxygen 1.8.13