summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mem/port.cc17
-rw-r--r--src/mem/port.hh11
-rw-r--r--src/python/m5/event.py33
-rw-r--r--src/python/swig/event.i26
-rw-r--r--src/python/swig/pyevent.cc38
-rw-r--r--src/python/swig/pyevent.hh28
-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
11 files changed, 254 insertions, 219 deletions
diff --git a/src/mem/port.cc b/src/mem/port.cc
index 0e03194c9..a666c968b 100644
--- a/src/mem/port.cc
+++ b/src/mem/port.cc
@@ -49,7 +49,7 @@ class DefaultPeerPort : public Port
public:
DefaultPeerPort()
- : Port("default_port")
+ : Port("default_port", NULL)
{ }
bool recvTiming(PacketPtr)
@@ -90,13 +90,9 @@ class DefaultPeerPort : public Port
DefaultPeerPort defaultPeerPort;
-Port::Port()
- : peer(&defaultPeerPort), owner(NULL)
-{
-}
-
Port::Port(const std::string &_name, MemObject *_owner)
- : portName(_name), peer(&defaultPeerPort), owner(_owner)
+ : EventManager(_owner), portName(_name), peer(&defaultPeerPort),
+ owner(_owner)
{
}
@@ -113,6 +109,13 @@ Port::setPeer(Port *port)
}
void
+Port::setOwner(MemObject *_owner)
+{
+ eventq = _owner->queue();
+ owner = _owner;
+}
+
+void
Port::removeConn()
{
if (peer->getOwner())
diff --git a/src/mem/port.hh b/src/mem/port.hh
index 15fda2164..1d9135ae6 100644
--- a/src/mem/port.hh
+++ b/src/mem/port.hh
@@ -47,6 +47,7 @@
#include "base/range.hh"
#include "mem/packet.hh"
#include "mem/request.hh"
+#include "sim/eventq.hh"
/** This typedef is used to clean up the parameter list of
* getDeviceAddressRanges() and getPeerAddressRanges(). It's declared
@@ -58,6 +59,7 @@
typedef std::list<Range<Addr> > AddrRangeList;
typedef std::list<Range<Addr> >::iterator AddrRangeIter;
+class EventQueue;
class MemObject;
/**
@@ -71,7 +73,7 @@ class MemObject;
* Send accessor functions are being called from the device the port is
* associated with, and it will call the peer recv. accessor function.
*/
-class Port
+class Port : public EventManager
{
protected:
/** Descriptive name (for DPRINTF output) */
@@ -86,9 +88,6 @@ class Port
MemObject *owner;
public:
-
- Port();
-
/**
* Constructor.
*
@@ -97,7 +96,7 @@ class Port
* @param _owner Pointer to the MemObject that owns this port.
* Will not necessarily be set.
*/
- Port(const std::string &_name, MemObject *_owner = NULL);
+ Port(const std::string &_name, MemObject *_owner);
/** Return port name (for DPRINTF). */
const std::string &name() const { return portName; }
@@ -121,7 +120,7 @@ class Port
Port *getPeer() { return peer; }
/** Function to set the owner of this port. */
- void setOwner(MemObject *_owner) { owner = _owner; }
+ void setOwner(MemObject *_owner);
/** Function to return the owner of this port. */
MemObject *getOwner() { return owner; }
diff --git a/src/python/m5/event.py b/src/python/m5/event.py
index 2d6497464..5d50448e7 100644
--- a/src/python/m5/event.py
+++ b/src/python/m5/event.py
@@ -26,17 +26,32 @@
#
# Authors: Nathan Binkert
-from internal.event import create
-from internal.event import SimLoopExitEvent as SimExit
+import internal.event
-class ProgressEvent(object):
- def __init__(self, period):
- self.period = int(period)
- self.schedule()
+from internal.event import PythonEvent, SimLoopExitEvent as SimExit
+
+mainq = internal.event.cvar.mainEventQueue
+
+def create(obj, priority=None):
+ if priority is None:
+ priority = internal.event.Event.Default_Pri
+ return internal.event.PythonEvent(obj, priority)
- def schedule(self):
- create(self, m5.curTick() + self.period)
+class Event(PythonEvent):
+ def __init__(self, priority=None):
+ if priority is None:
+ priority = internal.event.Event.Default_Pri
+ super(PythonEvent, self).__init__(self, priority)
+
+class ProgressEvent(Event):
+ def __init__(self, eventq, period):
+ super(ProgressEvent, self).__init__()
+ self.period = int(period)
+ self.eventq = eventq
+ self.eventq.schedule(self, m5.curTick() + self.period)
def __call__(self):
print "Progress! Time now %fs" % (m5.curTick()/1e12)
- self.schedule()
+ self.eventq.schedule(self, m5.curTick() + self.period)
+
+__all__ = [ 'create', 'Event', 'ProgressEvent', 'SimExit', 'mainq' ]
diff --git a/src/python/swig/event.i b/src/python/swig/event.i
index 9a2093c99..10d75d2de 100644
--- a/src/python/swig/event.i
+++ b/src/python/swig/event.i
@@ -32,34 +32,36 @@
%{
#include "python/swig/pyevent.hh"
-
+#include "sim/host.hh"
+#include "sim/eventq.hh"
#include "sim/sim_events.hh"
#include "sim/sim_exit.hh"
#include "sim/simulate.hh"
%}
+#pragma SWIG nowarn=350,351
+
+%import "base/fast_alloc.hh"
+%import "sim/serialize.hh"
+
%include "stdint.i"
%include "std_string.i"
%include "sim/host.hh"
+%include "sim/eventq.hh"
+%include "python/swig/pyevent.hh"
-void create(PyObject *object, Tick when);
-
-class Event;
-class CountedDrainEvent : public Event {
- public:
+struct CountedDrainEvent : public Event
+{
void setCount(int _count);
};
-CountedDrainEvent *createCountedDrain();
-void cleanupCountedDrain(Event *drain_event);
-
// minimal definition of SimExitEvent interface to wrap
-class SimLoopExitEvent {
+class SimLoopExitEvent : public Event
+{
public:
std::string getCause();
int getCode();
- SimLoopExitEvent(EventQueue *q, Tick _when, Tick _repeat,
- const std::string &_cause, int c = 0);
+ SimLoopExitEvent(const std::string &_cause, int c, Tick _repeat = 0);
};
%exception simulate {
diff --git a/src/python/swig/pyevent.cc b/src/python/swig/pyevent.cc
index 7f23b8874..bf993bc3e 100644
--- a/src/python/swig/pyevent.cc
+++ b/src/python/swig/pyevent.cc
@@ -33,8 +33,8 @@
#include "python/swig/pyevent.hh"
#include "sim/async.hh"
-PythonEvent::PythonEvent(PyObject *obj, Tick when, Priority priority)
- : Event(&mainEventQueue, priority), object(obj)
+PythonEvent::PythonEvent(PyObject *obj, Priority priority)
+ : Event(priority), object(obj)
{
if (object == NULL)
panic("Passed in invalid object");
@@ -42,7 +42,6 @@ PythonEvent::PythonEvent(PyObject *obj, Tick when, Priority priority)
Py_INCREF(object);
setFlags(AutoDelete);
- schedule(when);
}
PythonEvent::~PythonEvent()
@@ -67,3 +66,36 @@ PythonEvent::process()
async_exception = true;
}
}
+
+Event *
+createCountedDrain()
+{
+ return new CountedDrainEvent();
+}
+
+void
+cleanupCountedDrain(Event *counted_drain)
+{
+ CountedDrainEvent *event =
+ dynamic_cast<CountedDrainEvent *>(counted_drain);
+ if (event == NULL) {
+ fatal("Called cleanupCountedDrain() on an event that was not "
+ "a CountedDrainEvent.");
+ }
+ assert(event->getCount() == 0);
+ delete event;
+}
+
+#if 0
+Event *
+create(PyObject *object, Event::Priority priority)
+{
+ return new PythonEvent(object, priority);
+}
+
+void
+destroy(Event *event)
+{
+ delete event;
+}
+#endif
diff --git a/src/python/swig/pyevent.hh b/src/python/swig/pyevent.hh
index 65e80e9e4..c6d6ac993 100644
--- a/src/python/swig/pyevent.hh
+++ b/src/python/swig/pyevent.hh
@@ -40,35 +40,13 @@ class PythonEvent : public Event
PyObject *object;
public:
- PythonEvent(PyObject *obj, Tick when, Priority priority = Default_Pri);
+ PythonEvent(PyObject *obj, Event::Priority priority);
~PythonEvent();
virtual void process();
};
-inline void
-create(PyObject *object, Tick when)
-{
- new PythonEvent(object, when);
-}
-
-inline Event *
-createCountedDrain()
-{
- return new CountedDrainEvent();
-}
-
-inline void
-cleanupCountedDrain(Event *counted_drain)
-{
- CountedDrainEvent *event =
- dynamic_cast<CountedDrainEvent *>(counted_drain);
- if (event == NULL) {
- fatal("Called cleanupCountedDrain() on an event that was not "
- "a CountedDrainEvent.");
- }
- assert(event->getCount() == 0);
- delete event;
-}
+Event *createCountedDrain();
+void cleanupCountedDrain(Event *counted_drain);
#endif // __PYTHON_SWIG_PYEVENT_HH__
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;
};