summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorNathan Binkert <nate@binkert.org>2008-11-10 11:51:18 -0800
committerNathan Binkert <nate@binkert.org>2008-11-10 11:51:18 -0800
commit4e02e7c217a1ee81dc16c378582697dd5a14de47 (patch)
tree6d39beaabb1df252632af16931827544aab44480 /src
parent1adfe5c7f3368c4225ff685ddcd66b6280c7599f (diff)
downloadgem5-4e02e7c217a1ee81dc16c378582697dd5a14de47.tar.xz
python: Fix the reference counting for python events placed on the eventq.
We need to add a reference when an object is put on the C++ queue, and remove a reference when the object is removed from the queue. This was not happening before and caused a memory problem.
Diffstat (limited to 'src')
-rw-r--r--src/python/m5/event.py2
-rw-r--r--src/python/swig/event.i29
-rw-r--r--src/python/swig/pyevent.cc23
-rw-r--r--src/python/swig/pyevent.hh3
-rw-r--r--src/sim/eventq.hh6
5 files changed, 40 insertions, 23 deletions
diff --git a/src/python/m5/event.py b/src/python/m5/event.py
index 2b43e578e..ce003defb 100644
--- a/src/python/m5/event.py
+++ b/src/python/m5/event.py
@@ -36,7 +36,7 @@ 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)
+ return PythonEvent(obj, priority)
class Event(PythonEvent):
def __init__(self, priority=None):
diff --git a/src/python/swig/event.i b/src/python/swig/event.i
index 10d75d2de..b40e59a4b 100644
--- a/src/python/swig/event.i
+++ b/src/python/swig/event.i
@@ -41,6 +41,35 @@
#pragma SWIG nowarn=350,351
+%extend EventQueue {
+ void
+ schedule(Event *event, Tick when)
+ {
+ // Any python event that are scheduled must have their
+ // internal object's refcount incremented so that the object
+ // sticks around while it is in the event queue.
+ PythonEvent *pyevent = dynamic_cast<PythonEvent *>(event);
+ if (pyevent)
+ pyevent->incref();
+ $self->schedule(event, when);
+ }
+
+ void
+ deschedule(Event *event)
+ {
+ $self->deschedule(event);
+
+ // Now that we're removing the python object from the event
+ // queue, we need to decrement its reference count.
+ PythonEvent *pyevent = dynamic_cast<PythonEvent *>(event);
+ if (pyevent)
+ pyevent->decref();
+ }
+}
+
+%ignore EventQueue::schedule;
+%ignore EventQueue::deschedule;
+
%import "base/fast_alloc.hh"
%import "sim/serialize.hh"
diff --git a/src/python/swig/pyevent.cc b/src/python/swig/pyevent.cc
index a201e0185..0695ed2d3 100644
--- a/src/python/swig/pyevent.cc
+++ b/src/python/swig/pyevent.cc
@@ -38,15 +38,10 @@ PythonEvent::PythonEvent(PyObject *obj, Priority priority)
{
if (object == NULL)
panic("Passed in invalid object");
-
- Py_INCREF(object);
-
- setFlags(AutoDelete);
}
PythonEvent::~PythonEvent()
{
- Py_DECREF(object);
}
void
@@ -65,6 +60,10 @@ PythonEvent::process()
async_event = true;
async_exception = true;
}
+
+ // Since the object has been removed from the event queue, its
+ // reference count must be decremented.
+ Py_DECREF(object);
}
CountedDrainEvent *
@@ -85,17 +84,3 @@ cleanupCountedDrain(Event *counted_drain)
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 22b562de1..9006a0404 100644
--- a/src/python/swig/pyevent.hh
+++ b/src/python/swig/pyevent.hh
@@ -43,6 +43,9 @@ class PythonEvent : public Event
PythonEvent(PyObject *obj, Event::Priority priority);
~PythonEvent();
+ void incref() { Py_INCREF(object); }
+ void decref() { Py_DECREF(object); }
+
virtual void process();
};
diff --git a/src/sim/eventq.hh b/src/sim/eventq.hh
index 2db652b54..281df2dc3 100644
--- a/src/sim/eventq.hh
+++ b/src/sim/eventq.hh
@@ -299,9 +299,9 @@ class EventQueue : public Serializable
virtual const std::string name() const { return objName; }
// schedule the given event on this queue
- void schedule(Event *ev, Tick when);
- void deschedule(Event *ev);
- void reschedule(Event *ev, Tick when, bool always = false);
+ void schedule(Event *event, Tick when);
+ void deschedule(Event *event);
+ void reschedule(Event *event, Tick when, bool always = false);
Tick nextTick() const { return head->when(); }
Event *serviceOne();