forked from OSchip/llvm-project
Fix for pthread_setspecific (TLS and shutdown) problem
Some codes that use TLS fail intermittently because one thread tries to write TLS values after the TLS key has been destroyed by another thread. This happens when one thread executes library shutdown (and destroys TLS keys), while another thread starts to execute the TLS key destructor routine. Before this change, the kmp_init_runtime flag was checked before calling pthread_* TLS functions, but this flag is set to FALSE later than the destruction of the TLS keys, which leads to failure. The fix is to check kmp_init_gtid instead, as this flag is unset *before* the destruction of TLS keys. Differential Revision: http://reviews.llvm.org/D19022 llvm-svn: 266674
This commit is contained in:
parent
f5b25f83e3
commit
f252010f69
|
@ -3737,6 +3737,7 @@ __kmp_register_root( int initial_thread )
|
|||
|
||||
/* initialize the thread, get it ready to go */
|
||||
__kmp_initialize_info( root_thread, root->r.r_root_team, 0, gtid );
|
||||
TCW_4(__kmp_init_gtid, TRUE);
|
||||
|
||||
/* prepare the master thread for get_gtid() */
|
||||
__kmp_gtid_set_specific( gtid );
|
||||
|
@ -3748,7 +3749,6 @@ __kmp_register_root( int initial_thread )
|
|||
#endif
|
||||
__kmp_create_worker( gtid, root_thread, __kmp_stksize );
|
||||
KMP_DEBUG_ASSERT( __kmp_gtid_get_specific() == gtid );
|
||||
TCW_4(__kmp_init_gtid, TRUE);
|
||||
|
||||
KA_TRACE( 20, ("__kmp_register_root: T#%d init T#%d(%d:%d) arrived: join=%u, plain=%u\n",
|
||||
gtid, __kmp_gtid_from_tid( 0, root->r.r_hot_team ),
|
||||
|
|
|
@ -1897,18 +1897,21 @@ __kmp_yield( int cond )
|
|||
void
|
||||
__kmp_gtid_set_specific( int gtid )
|
||||
{
|
||||
int status;
|
||||
KMP_ASSERT( __kmp_init_runtime );
|
||||
status = pthread_setspecific( __kmp_gtid_threadprivate_key, (void*)(intptr_t)(gtid+1) );
|
||||
KMP_CHECK_SYSFAIL( "pthread_setspecific", status );
|
||||
if( __kmp_init_gtid ) {
|
||||
int status;
|
||||
status = pthread_setspecific( __kmp_gtid_threadprivate_key, (void*)(intptr_t)(gtid+1) );
|
||||
KMP_CHECK_SYSFAIL( "pthread_setspecific", status );
|
||||
} else {
|
||||
KA_TRACE( 50, ("__kmp_gtid_set_specific: runtime shutdown, returning\n" ) );
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
__kmp_gtid_get_specific()
|
||||
{
|
||||
int gtid;
|
||||
if ( !__kmp_init_runtime ) {
|
||||
KA_TRACE( 50, ("__kmp_get_specific: runtime shutdown, returning KMP_GTID_SHUTDOWN\n" ) );
|
||||
if ( !__kmp_init_gtid ) {
|
||||
KA_TRACE( 50, ("__kmp_gtid_get_specific: runtime shutdown, returning KMP_GTID_SHUTDOWN\n" ) );
|
||||
return KMP_GTID_SHUTDOWN;
|
||||
}
|
||||
gtid = (int)(size_t)pthread_getspecific( __kmp_gtid_threadprivate_key );
|
||||
|
|
|
@ -507,19 +507,22 @@ __kmp_yield( int cond )
|
|||
void
|
||||
__kmp_gtid_set_specific( int gtid )
|
||||
{
|
||||
KA_TRACE( 50, ("__kmp_gtid_set_specific: T#%d key:%d\n",
|
||||
gtid, __kmp_gtid_threadprivate_key ));
|
||||
KMP_ASSERT( __kmp_init_runtime );
|
||||
if( ! TlsSetValue( __kmp_gtid_threadprivate_key, (LPVOID)(gtid+1)) )
|
||||
KMP_FATAL( TLSSetValueFailed );
|
||||
if( __kmp_init_gtid ) {
|
||||
KA_TRACE( 50, ("__kmp_gtid_set_specific: T#%d key:%d\n",
|
||||
gtid, __kmp_gtid_threadprivate_key ));
|
||||
if( ! TlsSetValue( __kmp_gtid_threadprivate_key, (LPVOID)(gtid+1)) )
|
||||
KMP_FATAL( TLSSetValueFailed );
|
||||
} else {
|
||||
KA_TRACE( 50, ("__kmp_gtid_set_specific: runtime shutdown, returning\n" ) );
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
__kmp_gtid_get_specific()
|
||||
{
|
||||
int gtid;
|
||||
if( !__kmp_init_runtime ) {
|
||||
KA_TRACE( 50, ("__kmp_get_specific: runtime shutdown, returning KMP_GTID_SHUTDOWN\n" ) );
|
||||
if( !__kmp_init_gtid ) {
|
||||
KA_TRACE( 50, ("__kmp_gtid_get_specific: runtime shutdown, returning KMP_GTID_SHUTDOWN\n" ) );
|
||||
return KMP_GTID_SHUTDOWN;
|
||||
}
|
||||
gtid = (int)(kmp_intptr_t)TlsGetValue( __kmp_gtid_threadprivate_key );
|
||||
|
|
Loading…
Reference in New Issue