sim: fix reference counting of PythonEvent
authorCurtis Dunham <Curtis.Dunham@arm.com>
Tue, 23 Dec 2014 17:51:40 +0000 (11:51 -0600)
committerCurtis Dunham <Curtis.Dunham@arm.com>
Tue, 23 Dec 2014 17:51:40 +0000 (11:51 -0600)
When gem5 is a slave to another simulator and the Python is only used
to initialize the configuration (and not perform actual simulation), a
"debug start" (--debug-start) event will get freed during or immediately
after the initial Python frame's execution rather than remaining in the
event queue. This tricky patch fixes the GC issue causing this.

src/python/swig/event.i
src/python/swig/pyevent.cc
src/python/swig/pyevent.hh

index 23bb31364323bff7a640ccb6b51f3900e5e5b196..cc72794ed3b05b2cc60d617555e3ded8d35b37c0 100644 (file)
     }
 }
 
+%typemap(out) PythonEvent* {
+   result->object = $result = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_PythonEvent, SWIG_POINTER_NEW);
+}
+
 %ignore EventQueue::schedule;
 %ignore EventQueue::deschedule;
 
index 6d80a00cdeddab88508bb0c9b4028748643509e0..d83d57cbf432c6cad12c9cfb4ebb7568ea4f26c3 100644 (file)
 #include "sim/async.hh"
 #include "sim/eventq.hh"
 
-PythonEvent::PythonEvent(PyObject *obj, Priority priority)
-    : Event(priority), object(obj)
+PythonEvent::PythonEvent(PyObject *code, Priority priority)
+    : Event(priority), eventCode(code)
 {
-    if (object == NULL)
+    if (code == NULL)
         panic("Passed in invalid object");
 }
 
@@ -49,7 +49,7 @@ void
 PythonEvent::process()
 {
     PyObject *args = PyTuple_New(0);
-    PyObject *result = PyObject_Call(object, args, NULL);
+    PyObject *result = PyObject_Call(eventCode, args, NULL);
     Py_DECREF(args);
 
     if (result) {
index f34fbd99698661c177da9cfa6e9a0faa5e97cc4f..f668c1d9a0ead5c53333bc6597ab3dad0ec454d5 100644 (file)
 class PythonEvent : public Event
 {
   private:
-    PyObject *object;
-
+    PyObject *eventCode; // PyObject to call to perform event
   public:
+    PyObject *object;    // PyObject wrapping this PythonEvent
+
     PythonEvent(PyObject *obj, Event::Priority priority);
     ~PythonEvent();