eventq.hh (5768:ba6f2477d870) eventq.hh (5769:e53bdd0e4bf1)
1/*
2 * Copyright (c) 2000-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;

--- 30 unchanged lines hidden (view full) ---

39#include <algorithm>
40#include <cassert>
41#include <climits>
42#include <map>
43#include <string>
44#include <vector>
45
46#include "base/fast_alloc.hh"
1/*
2 * Copyright (c) 2000-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;

--- 30 unchanged lines hidden (view full) ---

39#include <algorithm>
40#include <cassert>
41#include <climits>
42#include <map>
43#include <string>
44#include <vector>
45
46#include "base/fast_alloc.hh"
47#include "base/flags.hh"
47#include "base/misc.hh"
48#include "base/trace.hh"
49#include "sim/serialize.hh"
50#include "sim/host.hh"
51
52class EventQueue; // forward declaration
53
54extern EventQueue mainEventQueue;

--- 4 unchanged lines hidden (view full) ---

59 * process() member function.
60 *
61 * Caution, the order of members is chosen to maximize data packing.
62 */
63class Event : public Serializable, public FastAlloc
64{
65 friend class EventQueue;
66
48#include "base/misc.hh"
49#include "base/trace.hh"
50#include "sim/serialize.hh"
51#include "sim/host.hh"
52
53class EventQueue; // forward declaration
54
55extern EventQueue mainEventQueue;

--- 4 unchanged lines hidden (view full) ---

60 * process() member function.
61 *
62 * Caution, the order of members is chosen to maximize data packing.
63 */
64class Event : public Serializable, public FastAlloc
65{
66 friend class EventQueue;
67
68 protected:
69 typedef short FlagsType;
70 typedef ::Flags<FlagsType> Flags;
71
72 static const FlagsType PublicRead = 0x003f;
73 static const FlagsType PublicWrite = 0x001d;
74 static const FlagsType Squashed = 0x0001;
75 static const FlagsType Scheduled = 0x0002;
76 static const FlagsType AutoDelete = 0x0004;
77 static const FlagsType AutoSerialize = 0x0008;
78 static const FlagsType IsExitEvent = 0x0010;
79 static const FlagsType IsMainQueue = 0x0020;
80
67 private:
68 // The event queue is now a linked list of linked lists. The
69 // 'nextBin' pointer is to find the bin, where a bin is defined as
70 // when+priority. All events in the same bin will be stored in a
71 // second linked list (a stack) maintained by the 'nextInBin'
72 // pointer. The list will be accessed in LIFO order. The end
73 // result is that the insert/removal in 'nextBin' is
74 // linear/constant, and the lookup/removal in 'nextInBin' is
75 // constant/constant. Hopefully this is a significant improvement
76 // over the current fully linear insertion.
77 Event *nextBin;
78 Event *nextInBin;
79
80 static Event *insertBefore(Event *event, Event *curr);
81 static Event *removeItem(Event *event, Event *last);
82
83 Tick _when; //!< timestamp when event should be processed
84 short _priority; //!< event priority
81 private:
82 // The event queue is now a linked list of linked lists. The
83 // 'nextBin' pointer is to find the bin, where a bin is defined as
84 // when+priority. All events in the same bin will be stored in a
85 // second linked list (a stack) maintained by the 'nextInBin'
86 // pointer. The list will be accessed in LIFO order. The end
87 // result is that the insert/removal in 'nextBin' is
88 // linear/constant, and the lookup/removal in 'nextInBin' is
89 // constant/constant. Hopefully this is a significant improvement
90 // over the current fully linear insertion.
91 Event *nextBin;
92 Event *nextInBin;
93
94 static Event *insertBefore(Event *event, Event *curr);
95 static Event *removeItem(Event *event, Event *last);
96
97 Tick _when; //!< timestamp when event should be processed
98 short _priority; //!< event priority
85 short _flags;
99 Flags flags;
86
87#ifndef NDEBUG
88 /// Global counter to generate unique IDs for Event instances
89 static Counter instanceCounter;
90
91 /// This event's unique ID. We can also use pointer values for
92 /// this but they're not consistent across runs making debugging
93 /// more difficult. Thus we use a global counter value when

--- 18 unchanged lines hidden (view full) ---

112 queue = q;
113#endif
114#ifdef EVENTQ_DEBUG
115 whenScheduled = curTick;
116#endif
117 }
118
119 protected:
100
101#ifndef NDEBUG
102 /// Global counter to generate unique IDs for Event instances
103 static Counter instanceCounter;
104
105 /// This event's unique ID. We can also use pointer values for
106 /// this but they're not consistent across runs making debugging
107 /// more difficult. Thus we use a global counter value when

--- 18 unchanged lines hidden (view full) ---

126 queue = q;
127#endif
128#ifdef EVENTQ_DEBUG
129 whenScheduled = curTick;
130#endif
131 }
132
133 protected:
120 enum Flags {
121 None = 0x0,
122 Squashed = 0x1,
123 Scheduled = 0x2,
124 AutoDelete = 0x4,
125 AutoSerialize = 0x8,
126 IsExitEvent = 0x10,
127 IsMainQueue = 0x20
128 };
134 /// Accessor for flags.
135 Flags
136 getFlags() const
137 {
138 return flags & PublicRead;
139 }
129
140
130 bool getFlags(Flags f) const { return (_flags & f) == f; }
131 void setFlags(Flags f) { _flags |= f; }
132 void clearFlags(Flags f) { _flags &= ~f; }
141 Flags
142 getFlags(Flags _flags) const
143 {
144 assert(flags.noneSet(~PublicRead));
145 return flags.isSet(_flags);
146 }
133
147
134 protected:
148 Flags
149 allFlags(Flags _flags) const
150 {
151 assert(_flags.noneSet(~PublicRead));
152 return flags.allSet(_flags);
153 }
154
155 /// Accessor for flags.
156 void
157 setFlags(Flags _flags)
158 {
159 assert(_flags.noneSet(~PublicWrite));
160 flags.set(_flags);
161 }
162
163 void
164 clearFlags(Flags _flags)
165 {
166 assert(_flags.noneSet(~PublicWrite));
167 flags.clear(_flags);
168 }
169
170 void
171 clearFlags()
172 {
173 flags.clear(PublicWrite);
174 }
175
135 // This function isn't really useful if TRACING_ON is not defined
136 virtual void trace(const char *action); //!< trace event activity
137
138 public:
139 /// Event priorities, to provide tie-breakers for events scheduled
140 /// at the same cycle. Most events are scheduled at the default
141 /// priority; these values are used to control events that need to
142 /// be ordered within a cycle.

--- 49 unchanged lines hidden (view full) ---

192 Maximum_Pri = SHRT_MAX
193 };
194
195 /*
196 * Event constructor
197 * @param queue that the event gets scheduled on
198 */
199 Event(Priority p = Default_Pri)
176 // This function isn't really useful if TRACING_ON is not defined
177 virtual void trace(const char *action); //!< trace event activity
178
179 public:
180 /// Event priorities, to provide tie-breakers for events scheduled
181 /// at the same cycle. Most events are scheduled at the default
182 /// priority; these values are used to control events that need to
183 /// be ordered within a cycle.

--- 49 unchanged lines hidden (view full) ---

233 Maximum_Pri = SHRT_MAX
234 };
235
236 /*
237 * Event constructor
238 * @param queue that the event gets scheduled on
239 */
240 Event(Priority p = Default_Pri)
200 : nextBin(NULL), nextInBin(NULL), _priority(p), _flags(None)
241 : nextBin(NULL), nextInBin(NULL), _priority(p)
201 {
202#ifndef NDEBUG
203 instance = ++instanceCounter;
204 queue = NULL;
205#endif
206#ifdef EVENTQ_DEBUG
207 whenCreated = curTick;
208 whenScheduled = 0;

--- 20 unchanged lines hidden (view full) ---

229 * statically allocated event objects).
230 *
231 * If the AutoDestroy flag is set, the object is deleted once it
232 * is processed.
233 */
234 virtual void process() = 0;
235
236 /// Determine if the current event is scheduled
242 {
243#ifndef NDEBUG
244 instance = ++instanceCounter;
245 queue = NULL;
246#endif
247#ifdef EVENTQ_DEBUG
248 whenCreated = curTick;
249 whenScheduled = 0;

--- 20 unchanged lines hidden (view full) ---

270 * statically allocated event objects).
271 *
272 * If the AutoDestroy flag is set, the object is deleted once it
273 * is processed.
274 */
275 virtual void process() = 0;
276
277 /// Determine if the current event is scheduled
237 bool scheduled() const { return getFlags(Scheduled); }
278 bool scheduled() const { return flags.isSet(Scheduled); }
238
239 /// Squash the current event
279
280 /// Squash the current event
240 void squash() { setFlags(Squashed); }
281 void squash() { flags.set(Squashed); }
241
242 /// Check whether the event is squashed
282
283 /// Check whether the event is squashed
243 bool squashed() const { return getFlags(Squashed); }
284 bool squashed() const { return flags.isSet(Squashed); }
244
245 /// See if this is a SimExitEvent (without resorting to RTTI)
285
286 /// See if this is a SimExitEvent (without resorting to RTTI)
246 bool isExitEvent() const { return getFlags(IsExitEvent); }
287 bool isExitEvent() const { return flags.isSet(IsExitEvent); }
247
248 /// Get the time that the event is scheduled
249 Tick when() const { return _when; }
250
251 /// Get the event priority
252 int priority() const { return _priority; }
253
254#ifndef SWIG

--- 138 unchanged lines hidden (view full) ---

393 class DelayEvent : public Event
394 {
395 private:
396 T *object;
397
398 public:
399 DelayEvent(T *o)
400 : object(o)
288
289 /// Get the time that the event is scheduled
290 Tick when() const { return _when; }
291
292 /// Get the event priority
293 int priority() const { return _priority; }
294
295#ifndef SWIG

--- 138 unchanged lines hidden (view full) ---

434 class DelayEvent : public Event
435 {
436 private:
437 T *object;
438
439 public:
440 DelayEvent(T *o)
441 : object(o)
401 { setFlags(this->AutoDestroy); }
442 { this->setFlags(AutoDelete); }
402 void process() { (object->*F)(); }
403 const char *description() const { return "delay"; }
404 };
405
406 eventq->schedule(new DelayEvent(object), when);
407}
408
409template <class T, void (T::* F)()>

--- 16 unchanged lines hidden (view full) ---

426inline void
427EventQueue::schedule(Event *event, Tick when)
428{
429 assert(when >= curTick);
430 assert(!event->scheduled());
431
432 event->setWhen(when, this);
433 insert(event);
443 void process() { (object->*F)(); }
444 const char *description() const { return "delay"; }
445 };
446
447 eventq->schedule(new DelayEvent(object), when);
448}
449
450template <class T, void (T::* F)()>

--- 16 unchanged lines hidden (view full) ---

467inline void
468EventQueue::schedule(Event *event, Tick when)
469{
470 assert(when >= curTick);
471 assert(!event->scheduled());
472
473 event->setWhen(when, this);
474 insert(event);
434 event->setFlags(Event::Scheduled);
475 event->flags.set(Event::Scheduled);
435 if (this == &mainEventQueue)
476 if (this == &mainEventQueue)
436 event->setFlags(Event::IsMainQueue);
477 event->flags.set(Event::IsMainQueue);
437 else
478 else
438 event->clearFlags(Event::IsMainQueue);
479 event->flags.clear(Event::IsMainQueue);
439
440 if (DTRACE(Event))
441 event->trace("scheduled");
442}
443
444inline void
445EventQueue::deschedule(Event *event)
446{
447 assert(event->scheduled());
448
449 remove(event);
450
480
481 if (DTRACE(Event))
482 event->trace("scheduled");
483}
484
485inline void
486EventQueue::deschedule(Event *event)
487{
488 assert(event->scheduled());
489
490 remove(event);
491
451 event->clearFlags(Event::Squashed);
452 event->clearFlags(Event::Scheduled);
492 event->flags.clear(Event::Squashed);
493 event->flags.clear(Event::Scheduled);
453
494
454 if (event->getFlags(Event::AutoDelete))
495 if (event->flags.isSet(Event::AutoDelete))
455 delete event;
456
457 if (DTRACE(Event))
458 event->trace("descheduled");
459}
460
461inline void
462EventQueue::reschedule(Event *event, Tick when, bool always)
463{
464 assert(when >= curTick);
465 assert(always || event->scheduled());
466
467 if (event->scheduled())
468 remove(event);
469
470 event->setWhen(when, this);
471 insert(event);
496 delete event;
497
498 if (DTRACE(Event))
499 event->trace("descheduled");
500}
501
502inline void
503EventQueue::reschedule(Event *event, Tick when, bool always)
504{
505 assert(when >= curTick);
506 assert(always || event->scheduled());
507
508 if (event->scheduled())
509 remove(event);
510
511 event->setWhen(when, this);
512 insert(event);
472 event->clearFlags(Event::Squashed);
473 event->setFlags(Event::Scheduled);
513 event->flags.clear(Event::Squashed);
514 event->flags.set(Event::Scheduled);
474 if (this == &mainEventQueue)
515 if (this == &mainEventQueue)
475 event->setFlags(Event::IsMainQueue);
516 event->flags.set(Event::IsMainQueue);
476 else
517 else
477 event->clearFlags(Event::IsMainQueue);
518 event->flags.clear(Event::IsMainQueue);
478
479 if (DTRACE(Event))
480 event->trace("rescheduled");
481}
482
483inline bool
484operator<(const Event &l, const Event &r)
485{

--- 38 unchanged lines hidden ---
519
520 if (DTRACE(Event))
521 event->trace("rescheduled");
522}
523
524inline bool
525operator<(const Event &l, const Event &r)
526{

--- 38 unchanged lines hidden ---