Make include paths explicit and update makefile accordingly.
[gem5.git] / sim / eventq.hh
1 /*
2 * Copyright (c) 2003 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 /* @file
30 * EventQueue interfaces
31 */
32
33 #ifndef __EVENTQ_HH__
34 #define __EVENTQ_HH__
35
36 #include <assert.h>
37
38 #include <algorithm>
39 #include <map>
40 #include <string>
41 #include <vector>
42
43 #include "sim/host.hh" // for Tick
44
45 #include "base/fast_alloc.hh"
46 #include "sim/serialize.hh"
47 #include "base/trace.hh"
48
49 class EventQueue; // forward declaration
50
51 /*
52 * An item on an event queue. The action caused by a given
53 * event is specified by deriving a subclass and overriding the
54 * process() member function.
55 */
56 class Event : public Serializeable, public FastAlloc
57 {
58 friend class EventQueue;
59
60 private:
61 /// queue to which this event belongs (though it may or may not be
62 /// scheduled on this queue yet)
63 EventQueue *queue;
64
65 Event *next;
66
67 Tick _when; //!< timestamp when event should be processed
68 int _priority; //!< event priority
69 char _flags;
70
71 protected:
72 enum Flags {
73 None = 0x0,
74 Squashed = 0x1,
75 Scheduled = 0x2,
76 AutoDelete = 0x4
77 };
78
79 bool getFlags(Flags f) const { return (_flags & f) == f; }
80 void setFlags(Flags f) { _flags |= f; }
81 void clearFlags(Flags f) { _flags &= ~f; }
82
83 protected:
84 EventQueue *theQueue() const { return queue; }
85
86 #if TRACING_ON
87 Tick when_created; //!< Keep track of creation time For debugging
88 Tick when_scheduled; //!< Keep track of creation time For debugging
89
90 virtual void trace(const char *action); //!< trace event activity
91 #else
92 void trace(const char *) {}
93 #endif
94
95 unsigned annotated_value;
96
97 public:
98
99 static const std::string defaultName;
100
101 /*
102 * Event constructor
103 * @param queue that the event gets scheduled on
104 */
105 Event(EventQueue *q, int p = 0)
106 : Serializeable(defaultName), queue(q), next(NULL),
107 _priority(p), _flags(None),
108 #if TRACING_ON
109 when_created(curTick), when_scheduled(0),
110 #endif
111 annotated_value(0)
112 {
113 }
114
115 ~Event() {}
116
117 /// Determine if the current event is scheduled
118 bool scheduled() const { return getFlags(Scheduled); }
119
120 /// Schedule the event with the current priority or default priority
121 void schedule(Tick t);
122
123 /// Schedule the event with a specific priority
124 void schedule(Tick t, int priority);
125
126 /// Reschedule the event with the current priority
127 void reschedule(Tick t);
128
129 /// Reschedule the event with a specific priority
130 void reschedule(Tick t, int priority);
131
132 /// Remove the event from the current schedule
133 void deschedule();
134
135 /// Return a C string describing the event. This string should
136 /// *not* be dynamically allocated; just a const char array
137 /// describing the event class.
138 virtual const char *description();
139
140 /// Dump the current event data
141 void dump();
142
143 /*
144 * This member function is invoked when the event is processed
145 * (occurs). There is no default implementation; each subclass
146 * must provide its own implementation. The event is not
147 * automatically deleted after it is processed (to allow for
148 * statically allocated event objects).
149 *
150 * If the AutoDestroy flag is set, the object is deleted once it
151 * is processed.
152 */
153 virtual void process() = 0;
154
155 void annotate(unsigned value) { annotated_value = value; };
156 unsigned annotation() { return annotated_value; }
157
158 /// Squash the current event
159 void squash() { setFlags(Squashed); }
160
161 /// Check whether the event is squashed
162 bool squashed() { return getFlags(Squashed); }
163
164 /// Get the time that the event is scheduled
165 Tick when() const { return _when; }
166
167 /// Get the event priority
168 int priority() const { return _priority; }
169
170 struct priority_compare :
171 public std::binary_function<Event *, Event *, bool>
172 {
173 bool operator()(const Event *l, const Event *r) const {
174 return l->when() >= r->when() || l->priority() >= r->priority();
175 }
176 };
177 };
178
179 template <class T, void (T::* F)()>
180 void
181 DelayFunction(Tick when, T *object)
182 {
183 class DelayEvent : public Event
184 {
185 private:
186 T *object;
187
188 public:
189 DelayEvent(Tick when, T *o)
190 : Event(&mainEventQueue), object(o)
191 { setFlags(AutoDestroy); schedule(when); }
192 void process() { (object->*F)(); }
193 const char *description() { return "delay"; }
194 };
195
196 new DelayEvent(when, object);
197 }
198
199 /*
200 * Queue of events sorted in time order
201 */
202 class EventQueue : public Serializeable
203 {
204 private:
205 Event *head;
206
207 void insert(Event *event);
208 void remove(Event *event);
209
210 public:
211
212 // constructor
213 EventQueue(const std::string &n)
214 : Serializeable(n), head(NULL)
215 {}
216
217 // schedule the given event on this queue
218 void schedule(Event *ev);
219 void deschedule(Event *ev);
220 void reschedule(Event *ev);
221
222 Tick nextTick() { return head->when(); }
223 void serviceOne();
224
225 // process all events up to the given timestamp. we inline a
226 // quick test to see if there are any events to process; if so,
227 // call the internal out-of-line version to process them all.
228 void serviceEvents(Tick when) {
229 while (!empty()) {
230 if (nextTick() > when)
231 break;
232
233 assert(head->when() >= when && "event scheduled in the past");
234 serviceOne();
235 }
236 }
237
238 // default: process all events up to 'now' (curTick)
239 void serviceEvents() { serviceEvents(curTick); }
240
241 // return true if no events are queued
242 bool empty() { return head == NULL; }
243
244 void dump();
245
246 Tick nextEventTime() { return empty() ? curTick : head->when(); }
247
248 virtual void nameChildren();
249 virtual void serialize();
250 };
251
252
253 //////////////////////
254 //
255 // inline functions
256 //
257 // can't put these inside declaration due to circular dependence
258 // between Event and EventQueue classes.
259 //
260 //////////////////////
261
262 // schedule at specified time (place on event queue specified via
263 // constructor)
264 inline void
265 Event::schedule(Tick t)
266 {
267 assert(!scheduled());
268 setFlags(Scheduled);
269 #if TRACING_ON
270 when_scheduled = curTick;
271 #endif
272 _when = t;
273 queue->schedule(this);
274 }
275
276 inline void
277 Event::schedule(Tick t, int p)
278 {
279 _priority = p;
280 schedule(t);
281 }
282
283 inline void
284 Event::deschedule()
285 {
286 assert(scheduled());
287
288 clearFlags(Squashed);
289 clearFlags(Scheduled);
290 queue->deschedule(this);
291 }
292
293 inline void
294 Event::reschedule(Tick t)
295 {
296 assert(scheduled());
297 clearFlags(Squashed);
298
299 #if TRACING_ON
300 when_scheduled = curTick;
301 #endif
302 _when = t;
303 queue->reschedule(this);
304 }
305
306 inline void
307 Event::reschedule(Tick t, int p)
308 {
309 _priority = p;
310 reschedule(t);
311 }
312
313 inline void
314 EventQueue::schedule(Event *event)
315 {
316 insert(event);
317 if (DTRACE(Event))
318 event->trace("scheduled");
319 }
320
321 inline void
322 EventQueue::deschedule(Event *event)
323 {
324 remove(event);
325 if (DTRACE(Event))
326 event->trace("descheduled");
327 }
328
329 inline void
330 EventQueue::reschedule(Event *event)
331 {
332 remove(event);
333 insert(event);
334 if (DTRACE(Event))
335 event->trace("rescheduled");
336 }
337
338
339 //////////////////////
340 //
341 // Main Event Queue
342 //
343 // Events on this queue are processed at the *beginning* of each
344 // cycle, before the pipeline simulation is performed.
345 //
346 // defined in eventq.cc
347 //
348 //////////////////////
349 extern EventQueue mainEventQueue;
350
351 #endif // __EVENTQ_HH__