D1 garbage collector + threads + malloc = garbage?

Leandro Lucarella llucax at gmail.com
Fri Dec 11 20:16:07 PST 2009


Bane, el 11 de diciembre a las 06:00 me escribiste:
> Bug with GC fullCollect() in multithreaded environment. Grauzone explained it here http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=99610
> 
> Test case that freezes app (tested on 1.053):
> 
> 
> import std.c.stdlib;
> import std.stdio;
> import std.gc;
> import std.thread;
> import std.c.time;
> 
> 
> class Foo {
>   void* p;
>   this(){
>     synchronized(this.classinfo) {
>       writefln("malloc begin");
>       p = std.c.stdlib.malloc(1024*1024);
>       writefln("malloc finished");
>     }
>   }
> 
>   ~this(){
>     synchronized(this.classinfo){
>       writefln("free begin");
>       std.c.stdlib.free(p);
>       writefln("free finished");
>     }
>   }
> }
> 
> class MyThread : Thread {
>   int run(){
>     while(true){
>       new Foo;
>       msleep(1);
>     }
>     return 0;
>   }
> }
> 
> void main(){
>   for(int i=0; i<10; i++){
>     (new MyThread).start;
>   }
>   
>   while(true){
>     writefln("collect begin");
>     std.gc.fullCollect;
>     writefln("collect finished");
>     msleep(1000);
>   }
> }
> 
> 
> 
> Can it be fixed or adleast mentioned somewhere in docs as known limitation of D1 GC? It would save a lot of time to some people (too late for me :).

The patch is very simple (as pointed by Grauzone), I guess it should make it
into D1 (I hope):

------------------------------------------------------------
diff --git a/phobos/internal/gc/gcx.d b/phobos/internal/gc/gcx.d
index b0d2821..7b1a7a3 100644
--- a/phobos/internal/gc/gcx.d
+++ b/phobos/internal/gc/gcx.d
@@ -2033,8 +2033,6 @@ struct Gcx
            }
        }
 
-       Thread.resumeAll();
-
        // Free up everything not marked
        debug(COLLECT_PRINTF) printf("\tfree'ing\n");
        size_t freedpages = 0;
@@ -2194,6 +2192,8 @@ struct Gcx
        debug(COLLECT_PRINTF) printf("recovered pages = %d\n", recoveredpages);
        debug(COLLECT_PRINTF) printf("\tfree'd %u bytes, %u pages from %u pools\
 
+       Thread.resumeAll();
+
        return freedpages + recoveredpages;
     }
 
------------------------------------------------------------

I wanted to reproduce it to make a bug report to attach the patch but
I couldn't. I replaced msleep() with usleep() (and multiplied the values
by 1000) because I'm in Linux, but that's all I changed. I have an old AMD
Athlon 1.8GHz. How do you reproduce it?

I want to be sure the bug is present before the patch and fixed after the
patch before submiting the patch via Bugzilla.

Thanks!

-- 
Leandro Lucarella (AKA luca)                     http://llucax.com.ar/
----------------------------------------------------------------------
GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145  104C 949E BFB6 5F5A 8D05)
----------------------------------------------------------------------
Nos retiramos hasta la semana que viene reflexionando sobre nuestras
vidas: "Qué vida de mier'... Qué vida de mier'!"
	-- Sidharta Kiwi



More information about the Digitalmars-d mailing list