w32pthreads: Fixed some minor bugs in the pthread_testcancel optimization I implemented some weeks ago; ifdef'd out some code that was specific to __CLEANUP_C mode.

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@2062 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
Jake.Stine 2009-10-23 20:09:16 +00:00
parent 2ede953125
commit cdb2d8f276
7 changed files with 47 additions and 8 deletions

View File

@ -44,6 +44,8 @@
* SEH or C++ destructor support.
*/
#ifdef __CLEANUP_C
ptw32_cleanup_t *
ptw32_pop_cleanup (int execute)
/*
@ -144,3 +146,5 @@ ptw32_push_cleanup (ptw32_cleanup_t * cleanup,
pthread_setspecific (ptw32_cleanupKey, (void *) cleanup);
} /* ptw32_push_cleanup */
#endif

View File

@ -35,6 +35,7 @@
*/
#include "ptw32pch.h"
#include <assert.h>
#ifndef PTW32_STATIC_LIB
@ -81,6 +82,10 @@ DllMain (HINSTANCE hinstDll, DWORD fdwReason, LPVOID lpvReserved)
case DLL_PROCESS_DETACH:
(void) pthread_win32_thread_detach_np ();
result = pthread_win32_process_detach_np ();
if( ptw32_testcancel_enable != 0 )
assert(0);
break;
}

View File

@ -970,7 +970,7 @@ extern void PTW32_CDECL pthread_testcancel (void);
PTW32_DLLPORT int PTW32_CDECL pthread_once (pthread_once_t * once_control,
void (*init_routine) (void));
#if PTW32_LEVEL >= PTW32_LEVEL_MAX
#if PTW32_LEVEL >= PTW32_LEVEL_MAX && defined(__CLEANUP_C)
PTW32_DLLPORT ptw32_cleanup_t * PTW32_CDECL ptw32_pop_cleanup (int execute);
PTW32_DLLPORT void PTW32_CDECL ptw32_push_cleanup (ptw32_cleanup_t * cleanup,

View File

@ -94,10 +94,6 @@ pthread_cancel (pthread_t thread)
cancel_self = pthread_equal (thread, self);
tp = (ptw32_thread_t *) thread.p;
// enables full cancel testing in pthread_testcancel, which is normally
// disabled because
_InterlockedIncrement( &ptw32_testcancel_enable );
/*
* Lock for async-cancel safety.
*/
@ -127,8 +123,18 @@ pthread_cancel (pthread_t thread)
/*
* Set for deferred cancellation.
*/
if (tp->state < PThreadStateCancelPending)
{
// enables full cancel testing in pthread_testcancel, which is normally disabled because
// the full test requires a DLL function invocation and TLS lookup. This provides an
// inlinable first-step shortcut for much speedier testing. :)
// Increment is performed here such that a thread that is already canceling won't get
// counted multiple times.
_InterlockedIncrement( &ptw32_testcancel_enable );
tp->state = PThreadStateCancelPending;
if (!SetEvent (tp->cancelEvent))
{

View File

@ -90,8 +90,6 @@ pthread_testcancel (void)
return;
}
_InterlockedDecrement( &ptw32_testcancel_enable );
(void) pthread_mutex_lock (&sp->cancelLock);
if (sp->cancelState != PTHREAD_CANCEL_DISABLE)

View File

@ -36,6 +36,27 @@
*/
#include "ptw32pch.h"
#include <assert.h>
// This is a "safe" cleanup handler for the cancel optimization. It ensures
// the testcancel_enable flag gets cleared even when threads commit grotesque
// exceptions.
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)
)
{
assert( ptw32_testcancel_enable > 0 );
if( ptw32_testcancel_enable > 0 )
(void) _InterlockedDecrement( &ptw32_testcancel_enable );
}
}
#ifdef __CLEANUP_SEH
@ -175,7 +196,9 @@ ptw32_threadStart (void *vthreadParms)
/*
* Run the caller's routine;
*/
pthread_cleanup_push( _cleanup_testcancel_optimization, sp );
status = sp->exitStatus = (*start) (arg);
pthread_cleanup_pop( 1 );
#ifdef _UWIN
if (--pthread_count <= 0)
@ -324,6 +347,8 @@ ptw32_threadStart (void *vthreadParms)
#endif /* __CLEANUP_C */
#endif /* __CLEANUP_SEH */
//_cleanup_testcancel_optimization();
#if defined(PTW32_STATIC_LIB)
/*
* We need to cleanup the pthread now if we have

View File

@ -142,6 +142,7 @@ ptw32_throw (DWORD exception)
}
#ifdef __CLEANUP_C
void
ptw32_pop_cleanup_all (int execute)
{
@ -149,7 +150,7 @@ ptw32_pop_cleanup_all (int execute)
{
}
}
#endif
DWORD
ptw32_get_exception_services_code (void)