python: Fix the reference counting for python events placed on the eventq.
authorNathan Binkert <nate@binkert.org>
Mon, 10 Nov 2008 19:51:18 +0000 (11:51 -0800)
committerNathan Binkert <nate@binkert.org>
Mon, 10 Nov 2008 19:51:18 +0000 (11:51 -0800)
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.

src/python/m5/event.py
src/python/swig/event.i
src/python/swig/pyevent.cc
src/python/swig/pyevent.hh
src/sim/eventq.hh

index 2b43e578ec04329110b338e511d4c0721b0283c8..ce003defb194eb375d957165dbf00a6d70d3b8dd 100644 (file)
@@ -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):
index 10d75d2de1e7d092e090da3a19547c6d4a4302f6..b40e59a4b711fd374efc66b5d202a62e48fdd38b 100644 (file)
 
 #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"
 
index a201e01856db2fd1cf20292784224b812084e482..0695ed2d36cb313623d31c48844533d92bdf51e9 100644 (file)
@@ -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
index 22b562de1b23adeaa36abdf5704858e002884d96..9006a0404042c6e98919699fabc06585aa17b89e 100644 (file)
@@ -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();
 };
 
index 2db652b549c3d5aa6586bb056fa2855f1e5bcc3c..281df2dc32f87eaa47860b437293dae787f2ce42 100644 (file)
@@ -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();