diff --git a/druntime/src/core/thread/osthread.d b/druntime/src/core/thread/osthread.d index 61ed05cac048..eb21f3197fd6 100644 --- a/druntime/src/core/thread/osthread.d +++ b/druntime/src/core/thread/osthread.d @@ -1129,6 +1129,33 @@ private extern(D) void* getStackBottom() nothrow @nogc static assert(false, "Platform not supported."); } + +// Returns true on success +// TODO: move to posix_impl module +version (Posix) +package bool suspendThreadImpl(Thread t) @nogc nothrow +{ + version (Darwin) + return thread_suspend(t.m_tmach) == KERN_SUCCESS; + else version (Solaris) + return thr_suspend(t.m_addr) == 0; + else + return pthread_kill(t.m_addr, suspendSignalNumber) == 0; +} + +// Returns true on success +// TODO: move to posix_impl module +version (Posix) +package bool resumeThreadImpl(Thread t) @nogc nothrow +{ + version (Darwin) + return thread_resume(t.m_tmach) == KERN_SUCCESS; + else version (Solaris) + return thr_continue(t.m_addr) == 0; + else + return pthread_kill(t.m_addr, resumeSignalNumber) == 0; +} + /** * Suspend the specified thread and load stack and register information for * use by thread_scanAll. If the supplied thread is the calling thread, @@ -1153,18 +1180,31 @@ private extern (D) bool suspend( Thread t ) nothrow @nogc return false; } - version (Windows) + const sameThread = t.m_addr == gettid(); + + if (!sameThread) { - if ( t.m_addr != GetCurrentThreadId() && SuspendThread( t.m_hndl ) == 0xFFFFFFFF ) + if (!suspendThreadImpl(t)) { - if ( !t.isRunning ) + if (t.isRunning) + onThreadError( "Unable to suspend thread" ); + else { Thread.remove( t ); return false; } - onThreadError( "Unable to suspend thread" ); } + } + + loadStackAndRegInfo(t, sameThread); + + return true; +} +private void loadStackAndRegInfo(Thread t, const bool sameThread) nothrow @nogc +{ + version (Windows) + { CONTEXT context = void; context.ContextFlags = CONTEXT_INTEGER | CONTEXT_CONTROL; @@ -1214,16 +1254,6 @@ private extern (D) bool suspend( Thread t ) nothrow @nogc } else version (Darwin) { - if ( t.m_addr != pthread_self() && thread_suspend( t.m_tmach ) != KERN_SUCCESS ) - { - if ( !t.isRunning ) - { - Thread.remove( t ); - return false; - } - onThreadError( "Unable to suspend thread" ); - } - version (X86) { x86_thread_state32_t state = void; @@ -1339,18 +1369,8 @@ private extern (D) bool suspend( Thread t ) nothrow @nogc } else version (Solaris) { - if (t.m_addr != pthread_self()) + if (!sameThread) { - if (thr_suspend(t.m_addr) != 0) - { - if (!t.isRunning) - { - Thread.remove(t); - return false; - } - onThreadError("Unable to suspend thread"); - } - static int getLwpStatus(ulong lwpid, out lwpstatus_t status) { import core.sys.posix.fcntl : open, O_RDONLY; @@ -1476,19 +1496,7 @@ private extern (D) bool suspend( Thread t ) nothrow @nogc } else version (Posix) { - if ( t.m_addr != pthread_self() ) - { - if ( pthread_kill( t.m_addr, suspendSignalNumber ) != 0 ) - { - if ( !t.isRunning ) - { - Thread.remove( t ); - return false; - } - onThreadError( "Unable to suspend thread" ); - } - } - else if ( !t.m_lock ) + if (sameThread && !t.m_lock) { t.m_curr.tstack = getStackTop(); } @@ -1499,7 +1507,6 @@ private extern (D) bool suspend( Thread t ) nothrow @nogc } else static assert(0, "unsupported os"); - return true; } /** @@ -1615,70 +1622,48 @@ extern (C) void thread_suspendAll() nothrow private extern (D) void resume(ThreadBase _t) nothrow @nogc { Thread t = _t.toThread; + const sameThread = t.m_addr == gettid(); - version (Windows) + if (!sameThread) { - if ( t.m_addr != GetCurrentThreadId() && ResumeThread( t.m_hndl ) == 0xFFFFFFFF ) + if (!resumeThreadImpl(t)) { - if ( !t.isRunning ) + if (t.isRunning) + onThreadError( "Unable to resume thread" ); + else { Thread.remove( t ); return; } - onThreadError( "Unable to resume thread" ); } + } + + storeStackAndRegInfo(t, sameThread); +} +private void storeStackAndRegInfo(Thread t, const bool sameThread) nothrow @nogc +{ + version (Windows) + { if ( !t.m_lock ) t.m_curr.tstack = t.m_curr.bstack; t.m_reg[0 .. $] = 0; } else version (Darwin) { - if ( t.m_addr != pthread_self() && thread_resume( t.m_tmach ) != KERN_SUCCESS ) - { - if ( !t.isRunning ) - { - Thread.remove( t ); - return; - } - onThreadError( "Unable to resume thread" ); - } - if ( !t.m_lock ) t.m_curr.tstack = t.m_curr.bstack; t.m_reg[0 .. $] = 0; } else version (Solaris) { - if (t.m_addr != pthread_self() && thr_continue(t.m_addr) != 0) - { - if (!t.isRunning) - { - Thread.remove(t); - return; - } - onThreadError("Unable to resume thread"); - } - if (!t.m_lock) t.m_curr.tstack = t.m_curr.bstack; t.m_reg[0 .. $] = 0; } else version (Posix) { - if ( t.m_addr != pthread_self() ) - { - if ( pthread_kill( t.m_addr, resumeSignalNumber ) != 0 ) - { - if ( !t.isRunning ) - { - Thread.remove( t ); - return; - } - onThreadError( "Unable to resume thread" ); - } - } - else if ( !t.m_lock ) + if (sameThread && !t.m_lock) { t.m_curr.tstack = t.m_curr.bstack; } diff --git a/druntime/src/core/thread/posix_impl.d b/druntime/src/core/thread/posix_impl.d index 036068184d6e..d284c4dc1034 100644 --- a/druntime/src/core/thread/posix_impl.d +++ b/druntime/src/core/thread/posix_impl.d @@ -584,3 +584,5 @@ class Thread : ThreadBase sched_yield(); } } + +package alias gettid = imported!"core.sys.posix.pthread".pthread_self; diff --git a/druntime/src/core/thread/wasi_impl.d b/druntime/src/core/thread/wasi_impl.d index 752634641819..16ad76ddce26 100644 --- a/druntime/src/core/thread/wasi_impl.d +++ b/druntime/src/core/thread/wasi_impl.d @@ -156,3 +156,23 @@ class Thread : ThreadBase // do nothing } } + +package ThreadID gettid() @nogc nothrow +{ + onThreadError( "Unable to get WASI thread ID" ); + assert(0); +} + +// Returns true on success +package bool suspendThreadImpl(Thread t) @nogc nothrow +{ + onThreadError( "Unable to suspend thread" ); + assert(0); +} + +// Returns true on success +package bool resumeThreadImpl(Thread t) @nogc nothrow +{ + onThreadError( "Unable to resume thread" ); + assert(0); +} diff --git a/druntime/src/core/thread/windows_impl.d b/druntime/src/core/thread/windows_impl.d index a3372fe18972..3de78afc3ccf 100644 --- a/druntime/src/core/thread/windows_impl.d +++ b/druntime/src/core/thread/windows_impl.d @@ -242,3 +242,17 @@ class Thread : ThreadBase SwitchToThread(); } } + +package alias gettid = imported!"core.sys.windows.winbase".GetCurrentThreadId; + +// Returns true on success +package bool suspendThreadImpl(Thread t) @nogc nothrow +{ + return SuspendThread(t.m_hndl) != 0xFFFFFFFF; +} + +// Returns true on success +package bool resumeThreadImpl(Thread t) @nogc nothrow +{ + return ResumeThread(t.m_hndl) != 0xFFFFFFFF; +}