diff options
Diffstat (limited to 'src/sim')
-rw-r--r-- | src/sim/eventq.cc | 8 | ||||
-rw-r--r-- | src/sim/eventq.hh | 304 | ||||
-rw-r--r-- | src/sim/sim_object.cc | 2 | ||||
-rw-r--r-- | src/sim/sim_object.hh | 4 | ||||
-rw-r--r-- | src/sim/sim_object_params.hh | 2 |
5 files changed, 163 insertions, 157 deletions
diff --git a/src/sim/eventq.cc b/src/sim/eventq.cc index 78d6a458f..f4fa0ac8b 100644 --- a/src/sim/eventq.cc +++ b/src/sim/eventq.cc @@ -51,7 +51,7 @@ using namespace std; // Events on this queue are processed at the *beginning* of each // cycle, before the pipeline simulation is performed. // -EventQueue mainEventQueue("MainEventQueue"); +EventQueue mainEventQueue("Main Event Queue"); #ifndef NDEBUG Counter Event::instanceCounter = 0; @@ -209,8 +209,7 @@ Event::serialize(std::ostream &os) void Event::unserialize(Checkpoint *cp, const string §ion) { - if (scheduled()) - deschedule(); + assert(!scheduled() && "we used to deschedule these events"); UNSERIALIZE_SCALAR(_when); UNSERIALIZE_SCALAR(_priority); @@ -224,7 +223,8 @@ Event::unserialize(Checkpoint *cp, const string §ion) if (wasScheduled) { DPRINTF(Config, "rescheduling at %d\n", _when); - schedule(_when); + panic("need to figure out how to unserialize scheduled events"); + //schedule(_when); } } diff --git a/src/sim/eventq.hh b/src/sim/eventq.hh index e0194a742..2db652b54 100644 --- a/src/sim/eventq.hh +++ b/src/sim/eventq.hh @@ -51,16 +51,6 @@ 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; /* @@ -90,10 +80,6 @@ class Event : public Serializable, public FastAlloc 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; @@ -107,6 +93,10 @@ class Event : public Serializable, public FastAlloc /// 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 @@ -114,11 +104,13 @@ class Event : public Serializable, public FastAlloc 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 @@ -131,7 +123,8 @@ class Event : public Serializable, public FastAlloc Scheduled = 0x2, AutoDelete = 0x4, AutoSerialize = 0x8, - IsExitEvent = 0x10 + IsExitEvent = 0x10, + IsMainQueue = 0x20 }; bool getFlags(Flags f) const { return (_flags & f) == f; } @@ -139,8 +132,6 @@ class Event : public Serializable, public FastAlloc 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 @@ -205,11 +196,12 @@ class Event : public Serializable, public FastAlloc * 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; @@ -256,16 +248,6 @@ class Event : public Serializable, public FastAlloc /// 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); } @@ -281,6 +263,7 @@ class Event : public Serializable, public FastAlloc /// Get the event priority int priority() const { return _priority; } +#ifndef SWIG struct priority_compare : public std::binary_function<Event *, Event *, bool> { @@ -293,55 +276,7 @@ class Event : public Serializable, public FastAlloc 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 }; /* @@ -349,18 +284,14 @@ class EventWrapper : public Event */ 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) {} @@ -370,7 +301,7 @@ class EventQueue : public Serializable // 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(); @@ -406,83 +337,103 @@ class EventQueue : public Serializable 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) @@ -490,9 +441,13 @@ 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"); @@ -516,18 +471,65 @@ EventQueue::deschedule(Event *event) } 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__ diff --git a/src/sim/sim_object.cc b/src/sim/sim_object.cc index 2c2213987..dad8f6e8b 100644 --- a/src/sim/sim_object.cc +++ b/src/sim/sim_object.cc @@ -59,7 +59,7 @@ SimObject::SimObjectList SimObject::simObjectList; // SimObject constructor: used to maintain static simObjectList // SimObject::SimObject(const Params *p) - : _params(p) + : EventManager(p->eventq), _params(p) { #ifdef DEBUG doDebugBreak = false; diff --git a/src/sim/sim_object.hh b/src/sim/sim_object.hh index 0141c16cc..d6d08f255 100644 --- a/src/sim/sim_object.hh +++ b/src/sim/sim_object.hh @@ -43,6 +43,7 @@ #include <vector> #include "params/SimObject.hh" +#include "sim/eventq.hh" #include "sim/serialize.hh" #include "sim/startup.hh" @@ -54,7 +55,8 @@ class Event; * correspond to physical components and can be specified via the * config file (CPUs, caches, etc.). */ -class SimObject : public Serializable, protected StartupCallback +class SimObject + : public EventManager, public Serializable, protected StartupCallback { public: enum State { diff --git a/src/sim/sim_object_params.hh b/src/sim/sim_object_params.hh index 5a629a949..74d433495 100644 --- a/src/sim/sim_object_params.hh +++ b/src/sim/sim_object_params.hh @@ -38,12 +38,14 @@ struct PyObject; #include <string> +struct EventQueue; struct SimObjectParams { virtual ~SimObjectParams() {} std::string name; PyObject *pyobj; + EventQueue *eventq; }; |