class EventQueue; // forward declaration
-//////////////////////
-//
-// Main Event Queue
-//
-// Events on this queue are processed at the *beginning* of each
-// cycle, before the pipeline simulation is performed.
-//
-// defined in eventq.cc
-//
-//////////////////////
extern EventQueue mainEventQueue;
/*
static Event *insertBefore(Event *event, Event *curr);
static Event *removeItem(Event *event, Event *last);
- /// queue to which this event belongs (though it may or may not be
- /// scheduled on this queue yet)
- EventQueue *_queue;
-
Tick _when; //!< timestamp when event should be processed
short _priority; //!< event priority
short _flags;
/// more difficult. Thus we use a global counter value when
/// debugging.
Counter instance;
+
+ /// queue to which this event belongs (though it may or may not be
+ /// scheduled on this queue yet)
+ EventQueue *queue;
#endif
#ifdef EVENTQ_DEBUG
Tick whenScheduled; //!< time scheduled
#endif
- protected:
void
- setWhen(Tick when)
+ setWhen(Tick when, EventQueue *q)
{
_when = when;
+#ifndef NDEBUG
+ queue = q;
+#endif
#ifdef EVENTQ_DEBUG
whenScheduled = curTick;
#endif
Scheduled = 0x2,
AutoDelete = 0x4,
AutoSerialize = 0x8,
- IsExitEvent = 0x10
+ IsExitEvent = 0x10,
+ IsMainQueue = 0x20
};
bool getFlags(Flags f) const { return (_flags & f) == f; }
void clearFlags(Flags f) { _flags &= ~f; }
protected:
- EventQueue *queue() const { return _queue; }
-
// This function isn't really useful if TRACING_ON is not defined
virtual void trace(const char *action); //!< trace event activity
* Event constructor
* @param queue that the event gets scheduled on
*/
- Event(EventQueue *q, Priority p = Default_Pri)
- : nextBin(NULL), nextInBin(NULL), _queue(q), _priority(p), _flags(None)
+ Event(Priority p = Default_Pri)
+ : nextBin(NULL), nextInBin(NULL), _priority(p), _flags(None)
{
#ifndef NDEBUG
instance = ++instanceCounter;
+ queue = NULL;
#endif
#ifdef EVENTQ_DEBUG
whenCreated = curTick;
/// Determine if the current event is scheduled
bool scheduled() const { return getFlags(Scheduled); }
- /// Schedule the event with the current priority or default priority
- void schedule(Tick t);
-
- /// Reschedule the event with the current priority
- // always parameter means to schedule if not already scheduled
- void reschedule(Tick t, bool always = false);
-
- /// Remove the event from the current schedule
- void deschedule();
-
/// Squash the current event
void squash() { setFlags(Squashed); }
/// Get the event priority
int priority() const { return _priority; }
+#ifndef SWIG
struct priority_compare
: public std::binary_function<Event *, Event *, bool>
{
virtual void serialize(std::ostream &os);
virtual void unserialize(Checkpoint *cp, const std::string §ion);
-};
-
-template <class T, void (T::* F)()>
-void
-DelayFunction(Tick when, T *object)
-{
- class DelayEvent : public Event
- {
- private:
- T *object;
-
- public:
- DelayEvent(Tick when, T *o)
- : Event(&mainEventQueue), object(o)
- { setFlags(this->AutoDestroy); schedule(when); }
- void process() { (object->*F)(); }
- const char *description() const { return "delay"; }
- };
-
- new DelayEvent(when, object);
-}
-
-template <class T, void (T::* F)()>
-class EventWrapper : public Event
-{
- private:
- T *object;
-
- public:
- EventWrapper(T *obj, bool del = false,
- EventQueue *q = &mainEventQueue,
- Priority p = Default_Pri)
- : Event(q, p), object(obj)
- {
- if (del)
- setFlags(AutoDelete);
- }
-
- EventWrapper(T *obj, Tick t, bool del = false,
- EventQueue *q = &mainEventQueue,
- Priority p = Default_Pri)
- : Event(q, p), object(obj)
- {
- if (del)
- setFlags(AutoDelete);
- schedule(t);
- }
-
- void process() { (object->*F)(); }
+#endif
};
/*
*/
class EventQueue : public Serializable
{
- protected:
- std::string objName;
-
private:
+ std::string objName;
Event *head;
void insert(Event *event);
void remove(Event *event);
public:
-
- // constructor
EventQueue(const std::string &n)
: objName(n), head(NULL)
{}
// schedule the given event on this queue
void schedule(Event *ev, Tick when);
void deschedule(Event *ev);
- void reschedule(Event *ev, Tick when);
+ void reschedule(Event *ev, Tick when, bool always = false);
Tick nextTick() const { return head->when(); }
Event *serviceOne();
bool debugVerify() const;
+#ifndef SWIG
virtual void serialize(std::ostream &os);
virtual void unserialize(Checkpoint *cp, const std::string §ion);
+#endif
};
+#ifndef SWIG
+class EventManager
+{
+ protected:
+ /** A pointer to this object's event queue */
+ EventQueue *eventq;
-//////////////////////
-//
-// inline functions
-//
-// can't put these inside declaration due to circular dependence
-// between Event and EventQueue classes.
-//
-//////////////////////
+ public:
+ EventManager(EventManager &em) : eventq(em.queue()) {}
+ EventManager(EventManager *em) : eventq(em ? em->queue() : NULL) {}
+ EventManager(EventQueue *eq) : eventq(eq) {}
-// schedule at specified time (place on event queue specified via
-// constructor)
-inline void
-Event::schedule(Tick when)
-{
- _queue->schedule(this, when);
-}
+ EventQueue *
+ queue() const
+ {
+ return eventq;
+ }
-inline void
-Event::deschedule()
-{
- _queue->deschedule(this);
-}
+ void
+ schedule(Event &event, Tick when)
+ {
+ eventq->schedule(&event, when);
+ }
-inline void
-Event::reschedule(Tick when, bool always)
-{
- if (scheduled()) {
- _queue->reschedule(this, when);
- } else {
- assert(always);
- _queue->schedule(this, when);
+ void
+ deschedule(Event &event)
+ {
+ eventq->deschedule(&event);
}
-}
-inline bool
-operator<(const Event &l, const Event &r)
-{
- return l.when() < r.when() ||
- (l.when() == r.when() && l.priority() < r.priority());
-}
+ void
+ reschedule(Event &event, Tick when, bool always = false)
+ {
+ eventq->reschedule(&event, when, always);
+ }
-inline bool
-operator>(const Event &l, const Event &r)
-{
- return l.when() > r.when() ||
- (l.when() == r.when() && l.priority() > r.priority());
-}
+ void
+ schedule(Event *event, Tick when)
+ {
+ eventq->schedule(event, when);
+ }
-inline bool
-operator<=(const Event &l, const Event &r)
-{
- return l.when() < r.when() ||
- (l.when() == r.when() && l.priority() <= r.priority());
-}
-inline bool
-operator>=(const Event &l, const Event &r)
-{
- return l.when() > r.when() ||
- (l.when() == r.when() && l.priority() >= r.priority());
-}
+ void
+ deschedule(Event *event)
+ {
+ eventq->deschedule(event);
+ }
-inline bool
-operator==(const Event &l, const Event &r)
+ void
+ reschedule(Event *event, Tick when, bool always = false)
+ {
+ eventq->reschedule(event, when, always);
+ }
+};
+
+template <class T, void (T::* F)()>
+void
+DelayFunction(EventQueue *eventq, Tick when, T *object)
{
- return l.when() == r.when() && l.priority() == r.priority();
+ class DelayEvent : public Event
+ {
+ private:
+ T *object;
+
+ public:
+ DelayEvent(T *o)
+ : object(o)
+ { setFlags(this->AutoDestroy); }
+ void process() { (object->*F)(); }
+ const char *description() const { return "delay"; }
+ };
+
+ eventq->schedule(new DelayEvent(object), when);
}
-inline bool
-operator!=(const Event &l, const Event &r)
+template <class T, void (T::* F)()>
+class EventWrapper : public Event
{
- return l.when() != r.when() || l.priority() != r.priority();
-}
+ private:
+ T *object;
+
+ public:
+ EventWrapper(T *obj, bool del = false, Priority p = Default_Pri)
+ : Event(p), object(obj)
+ {
+ if (del)
+ setFlags(AutoDelete);
+ }
+
+ void process() { (object->*F)(); }
+};
inline void
EventQueue::schedule(Event *event, Tick when)
assert(when >= curTick);
assert(!event->scheduled());
- event->setWhen(when);
+ event->setWhen(when, this);
insert(event);
event->setFlags(Event::Scheduled);
+ if (this == &mainEventQueue)
+ event->setFlags(Event::IsMainQueue);
+ else
+ event->clearFlags(Event::IsMainQueue);
if (DTRACE(Event))
event->trace("scheduled");
}
inline void
-EventQueue::reschedule(Event *event, Tick when)
+EventQueue::reschedule(Event *event, Tick when, bool always)
{
assert(when >= curTick);
- assert(event->scheduled());
+ assert(always || event->scheduled());
- remove(event);
- event->setWhen(when);
+ if (event->scheduled())
+ remove(event);
+
+ event->setWhen(when, this);
insert(event);
event->clearFlags(Event::Squashed);
+ event->setFlags(Event::Scheduled);
+ if (this == &mainEventQueue)
+ event->setFlags(Event::IsMainQueue);
+ else
+ event->clearFlags(Event::IsMainQueue);
if (DTRACE(Event))
event->trace("rescheduled");
}
+inline bool
+operator<(const Event &l, const Event &r)
+{
+ return l.when() < r.when() ||
+ (l.when() == r.when() && l.priority() < r.priority());
+}
+
+inline bool
+operator>(const Event &l, const Event &r)
+{
+ return l.when() > r.when() ||
+ (l.when() == r.when() && l.priority() > r.priority());
+}
+
+inline bool
+operator<=(const Event &l, const Event &r)
+{
+ return l.when() < r.when() ||
+ (l.when() == r.when() && l.priority() <= r.priority());
+}
+inline bool
+operator>=(const Event &l, const Event &r)
+{
+ return l.when() > r.when() ||
+ (l.when() == r.when() && l.priority() >= r.priority());
+}
+
+inline bool
+operator==(const Event &l, const Event &r)
+{
+ return l.when() == r.when() && l.priority() == r.priority();
+}
+
+inline bool
+operator!=(const Event &l, const Event &r)
+{
+ return l.when() != r.when() || l.priority() != r.priority();
+}
+#endif
+
#endif // __SIM_EVENTQ_HH__