summaryrefslogtreecommitdiff
path: root/src/sim
diff options
context:
space:
mode:
Diffstat (limited to 'src/sim')
-rw-r--r--src/sim/eventq.cc8
-rw-r--r--src/sim/eventq.hh304
-rw-r--r--src/sim/sim_object.cc2
-rw-r--r--src/sim/sim_object.hh4
-rw-r--r--src/sim/sim_object_params.hh2
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 &section)
{
- 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 &section)
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 &section);
-};
-
-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 &section);
+#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;
};