Am 23.04.2012 08:41, schrieb Benjamin Thaut:
I wrote a small "bad example" program for a presentation. It calls
malloc/free very frequently and I wanted to profile the impact of this
compared to a pool allocator solution. Unfortunately I had to notice
that the program only runs for a fraction of a second before
deadlocking. As it seems the following situation accurs:
1) Thread 1 calls malloc(), and locks the internal malloc mutex
2) Thread 2 triggers garbage collection and stops thread 1
3) Thread 2 is done collecting garbage and calls all destructors. One of
these calls free(), as the malloc mutex is still locked by Thread 1 and
Thread 1 will never release the mutex, as it is stoped, Thread 2 deadlocks.
Now this is not limited to malloc / free, it can happen with any kind of
locking that is done within a destructor.
Currently I can only think of two ways to fix this:
1) Don't use free inside a destructor (goodbye manual memory management)
2) A callback triggered by the GC before it starts stopping any threads,
and after it is done destructing all objects to manually lock / unlock
necessary synchronization primitives to prevent this kind of
deadlocking. The default implementation of this callback should lock /
unlock the malloc mutex.
That's nearly the same with OpenGL, never, really never put a
glDelete*-Call in a Dtor, I had this for a few commits in glamour (a
OpenGL wrapper) and it kept raining Segfaults.
The bigger problem was, that was only caused by the GC, I didn't tell
him to collect garbage from another Thread, it happend when it jumped
in, and called dtors.
The way I have fixed it was with "scope" and an additional .remove
method. Maybe this is the way you can solve your problem.