Skip to content
This repository has been archived by the owner on Oct 12, 2022. It is now read-only.

Commit

Permalink
Added thread_stackBottom() which correctly handles D-created fibers a…
Browse files Browse the repository at this point in the history
…s well as kernel-created thread stacks. Also reverted a change regarding fiber stack layout on Windows because the change was unnecessary. And quadrupled the default fiber stack size to 16K to fix backtraces (and make fiber use less unexpectedly crashy in general). I imagine fiber stacks could be tuned further, but 16K doesn't seem an unreasonable default.
  • Loading branch information
complexmath committed Sep 29, 2011
1 parent 0493e81 commit 9dca50f
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 41 deletions.
22 changes: 13 additions & 9 deletions src/core/runtime.d
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ private
extern (C) void* rt_loadLibrary( in char[] name );
extern (C) bool rt_unloadLibrary( void* ptr );

extern (C) void* rt_stackBottom();
extern (C) void* thread_stackBottom();

extern (C) string[] rt_args();

Expand Down Expand Up @@ -397,7 +397,7 @@ Throwable.TraceInfo defaultTraceHandler( void* ptr = null )
{
static enum MAXFRAMES = 128;
void*[MAXFRAMES] callstack;
numframes = backtrace( callstack, MAXFRAMES );
numframes = 0; //backtrace( callstack, MAXFRAMES );
if (numframes < 2) // backtrace() failed, do it ourselves
{
static void** getBasePtr()
Expand All @@ -411,16 +411,20 @@ Throwable.TraceInfo defaultTraceHandler( void* ptr = null )
return null;
}

void** stackTop = getBasePtr(), stackBottom = cast(void**)rt_stackBottom();
auto stackTop = getBasePtr();
auto stackBottom = cast(void**) thread_stackBottom();
void* dummy;
if (stackTop && &dummy < stackTop && stackTop < stackBottom)

if( stackTop && &dummy < stackTop && stackTop < stackBottom )
{
void** stackPtr = stackTop;
numframes = 0;
while (stackTop <= stackPtr && stackPtr < stackBottom && numframes < MAXFRAMES)
auto stackPtr = stackTop;

for( numframes = 0; stackTop <= stackPtr &&
stackPtr < stackBottom &&
numframes < MAXFRAMES; )
{
callstack[numframes++] = *(stackPtr+1);
stackPtr = cast(void**)*stackPtr;
callstack[numframes++] = *(stackPtr + 1);
stackPtr = cast(void**) *stackPtr;
}
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/core/sys/posix/pthread.d
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ version( linux )

//enum pthread_mutex_t PTHREAD_MUTEX_INITIALIZER = { 0, 0, null, PTHREAD_MUTEX_NORMAL, { 0, 0 } };

enum PTHREAD_ONCE_INIT = 0;
enum PTHREAD_ONCE_INIT = pthread_once_t.init;

enum
{
Expand Down Expand Up @@ -163,7 +163,7 @@ else version( OSX )

//enum pthread_mutex_t PTHREAD_MUTEX_INITIALIZER = { 0, 0, null, PTHREAD_MUTEX_NORMAL, { 0, 0 } };

enum PTHREAD_ONCE_INIT = 0;
enum PTHREAD_ONCE_INIT = pthread_once_t.init;

enum
{
Expand Down Expand Up @@ -203,7 +203,7 @@ else version( FreeBSD )
enum PTHREAD_NEEDS_INIT = 0;
enum PTHREAD_DONE_INIT = 1;

//enum PTHREAD_ONCE_INIT = { PTHREAD_NEEDS_INIT, null };
//enum pthread_once_t PTHREAD_ONCE_INIT = { PTHREAD_NEEDS_INIT, null };

enum PTHREAD_MUTEX_INITIALIZER = null;
enum PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP = null;
Expand Down
57 changes: 28 additions & 29 deletions src/core/thread.d
Original file line number Diff line number Diff line change
Expand Up @@ -294,14 +294,6 @@ else version( Posix )
}


// NOTE: On x86_64, if fiber throws an exception, backtrace() fails
// inside pthread_once() if pthread_once() has never been called
// for the thread. thread_initOnce() exists to fix this issue.
extern (C) void thread_initOnce()
{
}


//
// Entry point for POSIX threads
//
Expand Down Expand Up @@ -366,8 +358,6 @@ else version( Posix )
obj.m_tls = pstart[0 .. pend - pstart];
}

pthread_once_t once;
pthread_once( &once, &thread_initOnce );
obj.m_isRunning = true;
Thread.setThis( obj );
//Thread.add( obj );
Expand Down Expand Up @@ -806,8 +796,7 @@ class Thread
{
version( Windows )
{
assert(m_sz <= uint.max, "m_sz should not exceed uint.max");
m_hndl = cast(HANDLE) _beginthreadex( null, cast(uint)m_sz, &thread_entryPoint, cast(void*) this, 0, &m_addr );
m_hndl = cast(HANDLE) _beginthreadex( null, m_sz, &thread_entryPoint, cast(void*) this, 0, &m_addr );
if( cast(size_t) m_hndl == 0 )
throw new ThreadException( "Error creating thread" );
}
Expand Down Expand Up @@ -1932,8 +1921,6 @@ extern (C) Thread thread_attachThis()
thisContext.bstack = getStackBottom();
thisContext.tstack = thisContext.bstack;

pthread_once_t once;
pthread_once( &once, &thread_initOnce );
thisThread.m_isRunning = true;
}
thisThread.m_isDaemon = true;
Expand Down Expand Up @@ -2623,6 +2610,9 @@ extern(C) void thread_processGCMarks()
}


/**
*
*/
void[] thread_getTLSBlock()
{
version(OSX)
Expand All @@ -2642,6 +2632,15 @@ void[] thread_getTLSBlock()
}
}


/**
*
*/
extern (C) void* thread_stackBottom()
{
return Thread.getThis().topContext().bstack;
}

///////////////////////////////////////////////////////////////////////////////
// Thread Group
///////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -2939,13 +2938,13 @@ private
// save current stack state
push EBP;
mov EBP, ESP;
push EAX;
push EDI;
push ESI;
push EBX;
push dword ptr FS:[0];
push dword ptr FS:[4];
push dword ptr FS:[8];
push EBX;
push ESI;
push EDI;
push EAX;

// store oldp again with more accurate address
mov EAX, dword ptr 8[EBP];
Expand All @@ -2954,13 +2953,13 @@ private
mov ESP, dword ptr 12[EBP];

// load saved state from new stack
pop EDI;
pop ESI;
pop EBX;
pop EAX;
pop dword ptr FS:[8];
pop dword ptr FS:[4];
pop dword ptr FS:[0];
pop EAX;
pop EBX;
pop ESI;
pop EDI;
pop EBP;

// 'return' to complete switch
Expand Down Expand Up @@ -3161,7 +3160,7 @@ class Fiber
* In:
* fn must not be null.
*/
this( void function() fn, size_t sz = PAGESIZE )
this( void function() fn, size_t sz = PAGESIZE*4 )
in
{
assert( fn );
Expand All @@ -3187,7 +3186,7 @@ class Fiber
* In:
* dg must not be null.
*/
this( void delegate() dg, size_t sz = PAGESIZE )
this( void delegate() dg, size_t sz = PAGESIZE*4 )
in
{
assert( dg );
Expand Down Expand Up @@ -3698,8 +3697,10 @@ private:
version( AsmX86_Windows )
{
push( cast(size_t) &fiber_entryPoint ); // EIP
push( 0xFFFFFFFF ); // EBP
push( 0x00000000 ); // EAX
push( cast(size_t) m_ctxt.bstack ); // EBP
push( 0x00000000 ); // EDI
push( 0x00000000 ); // ESI
push( 0x00000000 ); // EBX
push( 0xFFFFFFFF ); // FS:[0]
version( StackGrowsDown )
{
Expand All @@ -3711,9 +3712,7 @@ private:
push( cast(size_t) m_ctxt.bstack ); // FS:[4]
push( cast(size_t) m_ctxt.bstack + m_size ); // FS:[8]
}
push( 0x00000000 ); // EBX
push( 0x00000000 ); // ESI
push( 0x00000000 ); // EDI
push( 0x00000000 ); // EAX
}
else version( AsmX86_64_Windows )
{
Expand Down

0 comments on commit 9dca50f

Please sign in to comment.