changeset 6ea35903c420 in /z/repo/m5
details: http://repo.m5sim.org/m5?cmd=changeset;node=6ea35903c420
description:
        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:

4 files changed, 15 insertions(+), 6 deletions(-)
src/python/swig/event.i    |   14 ++++++++++++++
src/python/swig/pyevent.cc |    4 ----
src/python/swig/pyevent.hh |    1 +
src/sim/eventq.hh          |    2 --

diffs (128 lines):

diff -r f43dbc09fad3 -r 6ea35903c420 src/python/m5/event.py
--- a/src/python/m5/event.py    Mon Nov 10 11:51:18 2008 -0800
+++ b/src/python/m5/event.py    Mon Nov 10 11:51:18 2008 -0800
@@ -36,7 +36,7 @@
 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 -r f43dbc09fad3 -r 6ea35903c420 src/python/swig/event.i
--- a/src/python/swig/event.i   Mon Nov 10 11:51:18 2008 -0800
+++ b/src/python/swig/event.i   Mon Nov 10 11:51:18 2008 -0800
@@ -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 -r f43dbc09fad3 -r 6ea35903c420 src/python/swig/pyevent.cc
--- a/src/python/swig/pyevent.cc        Mon Nov 10 11:51:18 2008 -0800
+++ b/src/python/swig/pyevent.cc        Mon Nov 10 11:51:18 2008 -0800
@@ -38,15 +38,10 @@
 {
     if (object == NULL)
         panic("Passed in invalid object");
-
-    Py_INCREF(object);
-
-    setFlags(AutoDelete);
 }
 
 PythonEvent::~PythonEvent()
 {
-    Py_DECREF(object);
 }
 
 void
@@ -65,6 +60,10 @@
         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 @@
     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 -r f43dbc09fad3 -r 6ea35903c420 src/python/swig/pyevent.hh
--- a/src/python/swig/pyevent.hh        Mon Nov 10 11:51:18 2008 -0800
+++ b/src/python/swig/pyevent.hh        Mon Nov 10 11:51:18 2008 -0800
@@ -43,6 +43,9 @@
     PythonEvent(PyObject *obj, Event::Priority priority);
     ~PythonEvent();
 
+    void incref() { Py_INCREF(object); }
+    void decref() { Py_DECREF(object); }
+
     virtual void process();
 };
 
diff -r f43dbc09fad3 -r 6ea35903c420 src/sim/eventq.hh
--- a/src/sim/eventq.hh Mon Nov 10 11:51:18 2008 -0800
+++ b/src/sim/eventq.hh Mon Nov 10 11:51:18 2008 -0800
@@ -299,9 +299,9 @@
     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();
_______________________________________________
m5-dev mailing list
m5-dev@m5sim.org
http://m5sim.org/mailman/listinfo/m5-dev

Reply via email to