diff --git a/3rdparty/w32pthreads/dll.c b/3rdparty/w32pthreads/dll.c index 88b495b91d..bfbd11480e 100644 --- a/3rdparty/w32pthreads/dll.c +++ b/3rdparty/w32pthreads/dll.c @@ -83,8 +83,7 @@ DllMain (HINSTANCE hinstDll, DWORD fdwReason, LPVOID lpvReserved) (void) pthread_win32_thread_detach_np (); result = pthread_win32_process_detach_np (); - if( ptw32_testcancel_enable != 0 ) - assert(0); + assert(ptw32_testcancel_enable == 0); break; } diff --git a/3rdparty/w32pthreads/ptw32_threadStart.c b/3rdparty/w32pthreads/ptw32_threadStart.c index 5c86c22428..74216210eb 100644 --- a/3rdparty/w32pthreads/ptw32_threadStart.c +++ b/3rdparty/w32pthreads/ptw32_threadStart.c @@ -46,15 +46,26 @@ static void _cleanup_testcancel_optimization( void* specific ) { ptw32_thread_t * sp = (ptw32_thread_t*)specific; //(ptw32_thread_t *)pthread_getspecific (ptw32_selfThreadKey); - if( (sp != NULL) && - (sp->cancelType == PTHREAD_CANCEL_DEFERRED) && - (sp->state >= PThreadStateCancelPending) - ) + if( (sp != NULL) ) { - assert( ptw32_testcancel_enable > 0 ); + pthread_mutex_lock (&sp->cancelLock); + if( (sp->cancelType == PTHREAD_CANCEL_DEFERRED) && (sp->state == PThreadStateCancelPending) ) + { + int result = _InterlockedDecrement( &ptw32_testcancel_enable ); + assert( result >= 0 ); + sp->state = PThreadStateCanceling; + } + else + { + // We need to prevent other threads, which may try to cancel this thread + // in parallel to it's cancellation here, from incrementing the cancel_enable flag. + // (and without clobbering the StateException, if that's already been set) - if( ptw32_testcancel_enable > 0 ) - (void) _InterlockedDecrement( &ptw32_testcancel_enable ); + if( sp->state < PThreadStateCanceling ) + sp->state = PThreadStateCanceling; + } + + pthread_mutex_unlock (&sp->cancelLock); } } diff --git a/common/src/x86emitter/WinCpuDetect.cpp b/common/src/x86emitter/WinCpuDetect.cpp index e657fbce11..af87a20a69 100644 --- a/common/src/x86emitter/WinCpuDetect.cpp +++ b/common/src/x86emitter/WinCpuDetect.cpp @@ -87,6 +87,9 @@ SingleCoreAffinity::SingleCoreAffinity() availProcCpus, availSysCpus, i ); } + + // Force Windows to timeslice (hoping this fixes some affinity issues) + Sleep( 2 ); }; SingleCoreAffinity::~SingleCoreAffinity() throw()