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.
This commit is contained in:
Nathan Binkert 2008-11-10 11:51:18 -08:00
parent 1adfe5c7f3
commit 4e02e7c217
5 changed files with 40 additions and 23 deletions

View 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):

View file

@ -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"

View 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

View 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();
};

View 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();