D1 garbage collector + threads + malloc = garbage?
Bane
branimir.milosavljevic at gmail.com
Sat Dec 12 01:46:16 PST 2009
Leandro Lucarella Wrote:
> 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
Home computer I tested it in is winxp with phenom quad core, but this bug is confirmed with centos 5.2 + intel dual core and centos 5.2 + intel xeon.
Bug is present for a long time, thats for sure, It took me a while to track it because I thought its just me abusing keyboard, not a bug in phobos. Worst thing with this bug is that there is no output or exception when it happens - just that dreaded deadlock :)
Once thing I noted - if you reduce memory required in that malloc call from 1 MB to 1 KB or less (or increase sleep time between calls), chances for bug to occur drop drastically, so in most applications this probably will never happen.
More information about the Digitalmars-d
mailing list