[Openmp-commits] [PATCH] D19022: Fix for pthread_setspecific (TLS and shutdown) problem

Jonathan Peyton via Openmp-commits openmp-commits at lists.llvm.org
Tue Apr 12 10:31:11 PDT 2016


jlpeyton created this revision.
jlpeyton added a reviewer: AndreyChurbanov.
jlpeyton added a subscriber: openmp-commits.
jlpeyton set the repository for this revision to rL LLVM.

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.


Repository:
  rL LLVM

http://reviews.llvm.org/D19022

Files:
  runtime/src/kmp_runtime.c
  runtime/src/z_Linux_util.c
  runtime/src/z_Windows_NT_util.c

Index: runtime/src/z_Windows_NT_util.c
===================================================================
--- runtime/src/z_Windows_NT_util.c
+++ runtime/src/z_Windows_NT_util.c
@@ -507,19 +507,22 @@
 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 );
Index: runtime/src/z_Linux_util.c
===================================================================
--- runtime/src/z_Linux_util.c
+++ runtime/src/z_Linux_util.c
@@ -1897,18 +1897,21 @@
 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 );
Index: runtime/src/kmp_runtime.c
===================================================================
--- runtime/src/kmp_runtime.c
+++ runtime/src/kmp_runtime.c
@@ -3737,6 +3737,7 @@
 
     /* 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 @@
     #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 ),


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D19022.53426.patch
Type: text/x-patch
Size: 3342 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/openmp-commits/attachments/20160412/3d44d3e1/attachment-0001.bin>


More information about the Openmp-commits mailing list