From b2f21330f7bc725e088522d63070b05f0253a672 Mon Sep 17 00:00:00 2001
From: Nathan Sidwell <nathan@codesourcery.com>
Date: Thu, 23 Apr 2009 10:39:24 +0000
Subject: [PATCH] vxlib-tls.c (active_tls_threads): Delete.

	* config/vxlib-tls.c (active_tls_threads): Delete.
	(delete_hook_installed): New.
	(tls_delete_hook): Don't delete the delete hook.
	(tls_destructor): Delete it here.
	(__gthread_set_specific): Adjust installing the delete hook.
	(tls_delete_hook): Use __gthread_enter_tsd_dtor_context and
	__gthread_leave_tsd_dtor_context.

From-SVN: r146641
---
 gcc/ChangeLog          | 10 ++++++++
 gcc/config/vxlib-tls.c | 52 ++++++++++++++++++++++--------------------
 2 files changed, 37 insertions(+), 25 deletions(-)

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index f44140d569f4..916b30a6f0ea 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,13 @@
+2009-04-23  Nathan Sidwell  <nathan@codesourcery.com>
+
+	* config/vxlib-tls.c (active_tls_threads): Delete.
+	(delete_hook_installed): New.
+	(tls_delete_hook): Don't delete the delete hook.
+	(tls_destructor): Delete it here.
+	(__gthread_set_specific): Adjust installing the delete hook.
+	(tls_delete_hook): Use __gthread_enter_tsd_dtor_context and
+	__gthread_leave_tsd_dtor_context.
+
 2009-04-23  Rafael Avila de Espindola  <espindola@google.com>
 
 	* c-format.c (gcc_tdiag_char_table): Add support for %E.
diff --git a/gcc/config/vxlib-tls.c b/gcc/config/vxlib-tls.c
index 9747aa3b28fc..c4696768f0f1 100644
--- a/gcc/config/vxlib-tls.c
+++ b/gcc/config/vxlib-tls.c
@@ -91,9 +91,9 @@ struct tls_data
    include a pointer to a local variable in the TLS data object.  */
 static int self_owner;
 
-/* The number of threads for this module which have active TLS data.
-   This is protected by tls_lock.  */
-static int active_tls_threads;
+/* Flag to check whether the delete hook is installed.  Once installed
+   it is only removed when unloading this module.  */
+static volatile int delete_hook_installed;
 
 /* kernel provided routines */
 extern void *__gthread_get_tls_data (void);
@@ -166,7 +166,11 @@ tls_delete_hook (void *tcb ATTRIBUTE_UNUSED)
   
   if (data && data->owner == &self_owner)
     {
+#ifdef __RTP__
       __gthread_enter_tls_dtor_context ();
+#else
+      __gthread_enter_tsd_dtor_context (tcb);
+#endif
       for (key = 0; key < MAX_KEYS; key++)
 	{
 	  if (data->generation[key] == tls_keys.generation[key])
@@ -178,22 +182,17 @@ tls_delete_hook (void *tcb ATTRIBUTE_UNUSED)
 	    }
 	}
       free (data);
+#ifdef __RTP__
+      __gthread_leave_tls_dtor_context ();
+#else
+      __gthread_leave_tsd_dtor_context ();
+#endif
 
-      /* We can't handle an error here, so just leave the thread
-	 marked as loaded if one occurs.  */
-      if (__gthread_mutex_lock (&tls_lock) != ERROR)
-	{
-	  active_tls_threads--;
-	  if (active_tls_threads == 0)
-	    taskDeleteHookDelete ((FUNCPTR)tls_delete_hook);
-	  __gthread_mutex_unlock (&tls_lock);
-	}
 #ifdef __RTP__
       __gthread_set_tls_data (0);
 #else
       __gthread_set_tsd_data (tcb, 0);
 #endif
-      __gthread_leave_tls_dtor_context ();
     }
 } 
 
@@ -211,13 +210,10 @@ tls_destructor (void)
 #ifdef __RTP__
   /* All threads but this one should have exited by now.  */
   tls_delete_hook (NULL);
-#else
-  /* Unregister the hook forcibly.  The counter of active threads may
-     be incorrect, because constructors (like the C++ library's) and
-     destructors (like this one) run in the context of the shell rather
-     than in a task spawned from this module.  */
-  taskDeleteHookDelete ((FUNCPTR)tls_delete_hook);
 #endif
+  /* Unregister the hook.  */
+  if (delete_hook_installed)
+    taskDeleteHookDelete ((FUNCPTR)tls_delete_hook);
 
   if (tls_init_guard.done && __gthread_mutex_lock (&tls_lock) != ERROR)
     semDelete (tls_lock);
@@ -331,12 +327,18 @@ __gthread_setspecific (__gthread_key_t key, void *value)
   data = __gthread_get_tls_data ();
   if (!data)
     {
-      if (__gthread_mutex_lock (&tls_lock) == ERROR)
-	return ENOMEM;
-      if (active_tls_threads == 0)
-	taskDeleteHookAdd ((FUNCPTR)tls_delete_hook);
-      active_tls_threads++;
-      __gthread_mutex_unlock (&tls_lock);
+      if (!delete_hook_installed)
+	{
+	  /* Install the delete hook.  */
+	  if (__gthread_mutex_lock (&tls_lock) == ERROR)
+	    return ENOMEM;
+	  if (!delete_hook_installed)
+	    {
+	      taskDeleteHookAdd ((FUNCPTR)tls_delete_hook);
+	      delete_hook_installed = 1;
+	    }
+	  __gthread_mutex_unlock (&tls_lock);
+	}
 
       data = malloc (sizeof (struct tls_data));
       if (!data)
-- 
GitLab