GC + malloc/free = deadlock

Benjamin Thaut code at benjamin-thaut.de
Mon Apr 23 03:51:46 PDT 2012


Am 23.04.2012 08:52, schrieb David:
> 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.

Well the issue with OpenGL is that you can only make OpenGL calls from 
the thread that actually owns the OpenGL context, so this is not quite 
the same. Because I'm perfectly allowed to call free from a different 
thread then where I called malloc. Also this is not only my problem, 
std.container.Array uses malloc & free so it can happen there too.


More information about the Digitalmars-d mailing list