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 --- |