Thread overview
[Issue 3054] New: multithreading GC problem. And Stdio not multithreading safe
Jun 06, 2009
davidl@126.com
Jun 12, 2009
Sean Kelly
Jun 14, 2009
david
Jun 17, 2009
Sean Kelly
Jun 17, 2009
david
Jun 17, 2009
david
Jun 17, 2009
Sean Kelly
Jun 17, 2009
Frits van Bommel
Jun 17, 2009
Sean Kelly
June 06, 2009
http://d.puremagic.com/issues/show_bug.cgi?id=3054

           Summary: multithreading GC problem. And Stdio not
                    multithreading safe
           Product: D
           Version: 2.028
          Platform: Other
        OS/Version: Windows
            Status: NEW
          Severity: critical
          Priority: P2
         Component: Phobos
        AssignedTo: bugzilla@digitalmars.com
        ReportedBy: davidl@126.com


import core.thread;
import std.stdio;
class threadid
{
    static int threadid;
    static int threadnum;
    int getId(){threadid++; return threadid; }
}
threadid TID;
void main()
{
    TID = new threadid;
    while(true)
    {
        try
        {
            synchronized(TID) if (TID.threadnum<500)
            {
                auto stress = (new Thread(
                    (){
                        int tid;
                        synchronized(TID){ tid = TID.getId(); }
                        scope(exit) synchronized(TID){TID.threadnum--;}
                        synchronized(TID){TID.threadnum++;}
                        //writefln("new thread:", tid, TID.threadnum);
                        void[] buffer;
                        try
                        {
                            buffer.length= 65536;
                        }
                        catch(Exception e)
                        {
                            writefln("thread:", tid);
                            writefln(e.msg);
                        }
                    }
                ));
                stress.start();
            }
            //writefln("outside:", TID.threadnum);
        }
        catch(Exception e)
        {
            //writefln("error: ", e.msg);
        }
    }
}

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
June 12, 2009
What is the expected behavior?
June 14, 2009
http://d.puremagic.com/issues/show_bug.cgi?id=3054





--- Comment #1 from david <davidl@126.com>  2009-06-14 07:52:45 PDT ---
the core.thread gets two problem:

1.
t = new Thread(
(){
while(true){}
}
);

delete t;

The last line should stuck there, because the thread is still running.

A possible solution is add a join in the dtor. It's quite fair your code stuck there if the thread is still running.


Another problem is thread_scanAll.

extern (C) void thread_scanAll( scanAllThreadsFn scan, void* curStackTop = null
)


Notice thread_scanAll may happen before the m_tls is set.

so the for loop:

    for( Thread t = Thread.sm_tbeg; t; t = t.next )
    {
+++        if (t.tlsvalid)
            scan( &t.m_tls[0], &t.m_tls[0] + t.m_tls.length );

        version( Windows )
        {
            scan( &t.m_reg[0], &t.m_reg[0] + t.m_reg.length );
        }
    }

add a tlsvalid bool var to the thread.

in : extern (Windows) uint thread_entryPoint( void* arg )



obj.m_tls = pstart[0 .. pend - pstart]; +++obj.tlsvalid = true;

POSIX version possiblly need some equivalent fixes either.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
June 17, 2009
http://d.puremagic.com/issues/show_bug.cgi?id=3054


Sean Kelly <sean@invisibleduck.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
                 CC|                            |sean@invisibleduck.org
         Resolution|                            |INVALID




--- Comment #2 from Sean Kelly <sean@invisibleduck.org>  2009-06-16 21:58:28 PDT ---
Regarding:

t = new Thread( (){while(true){}});
delete t;

This code will create and then destroy a thread object because t.start() is
never called.  Even if you call t.start() however, the delete will occur
immediately because it is not preceded by t.join().

As for the TLS issue, Thread.sm_tbeg will be null until thread_init() is called
by the GC, so the loop containing the scan(tls) call won't execute before the
TLS slice is initialized.

I'm going to mark this ticket as resolved since the issues I addressed above aren't actually problems with the design.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
June 17, 2009
http://d.puremagic.com/issues/show_bug.cgi?id=3054


david <davidl@126.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|RESOLVED                    |REOPENED
         Resolution|INVALID                     |




--- Comment #3 from david <davidl@126.com>  2009-06-17 08:17:19 PDT ---
Have you tested the code?

I certainly get the range error in thread_scanAll of accessing m_tls

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
June 17, 2009
http://d.puremagic.com/issues/show_bug.cgi?id=3054





--- Comment #4 from david <davidl@126.com>  2009-06-17 08:41:44 PDT ---
I don't think let users delete the obj and leave the users to detect what's
going wrong later access violation in their threads. This is nasty.
I insist we choose either:
throw an exception or
just hang there if the underlying system thread is still alive.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
June 17, 2009
http://d.puremagic.com/issues/show_bug.cgi?id=3054





--- Comment #5 from Sean Kelly <sean@invisibleduck.org>  2009-06-17 11:55:33 PDT ---
Oh I see.  If the array is empty then &m_tls[0] will cause a RangeError.  I forget that DMD considers taking the address of an array element a dereferencing operation.  Fixed in Druntime revision 164.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
June 17, 2009
http://d.puremagic.com/issues/show_bug.cgi?id=3054


Frits van Bommel <fvbommel@wxs.nl> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |fvbommel@wxs.nl




--- Comment #6 from Frits van Bommel <fvbommel@wxs.nl>  2009-06-17 12:53:34 PDT ---
(In reply to comment #5)
> Oh I see.  If the array is empty then &m_tls[0] will cause a RangeError.  I forget that DMD considers taking the address of an array element a dereferencing operation.

It's not the address-taking that is a dereference, it's the indexing
(regardless of whether the address of the result is taken). :)

(and if you didn't know, why didn't you use "&t.m_tls[$]" instead of
"&t.m_tls[0] + t.m_tls.length"?)

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
June 17, 2009
http://d.puremagic.com/issues/show_bug.cgi?id=3054





--- Comment #7 from Sean Kelly <sean@invisibleduck.org>  2009-06-17 13:09:32 PDT ---
That's what I meant :-)  I dunno why I didn't use the [$] form though. Probably just an overlooked change during maintenance.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------