diff options
-rw-r--r-- | src/mem/port.cc | 17 | ||||
-rw-r--r-- | src/mem/port.hh | 11 | ||||
-rw-r--r-- | src/python/m5/event.py | 33 | ||||
-rw-r--r-- | src/python/swig/event.i | 26 | ||||
-rw-r--r-- | src/python/swig/pyevent.cc | 38 | ||||
-rw-r--r-- | src/python/swig/pyevent.hh | 28 | ||||
-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 |
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 §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; }; |