This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[vxworks] vxlib-tls patch


I've applied this patch to fix a couple of vxworks issues.

1) we need to enter the right context in the delete hook for kernel modules

2) one cannot call taskDeleteHookDelete from inside a delete hook. If you do that, the hook will be deleted, but because of the implementation, then next hook in the list will be skipped. This is undocumented. Anyway, there's no need to be so tidy, the normal process termination goo DTRT.

nathan
--
Nathan Sidwell    ::   http://www.codesourcery.com   ::         CodeSourcery

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.

Index: config/vxlib-tls.c
===================================================================
--- config/vxlib-tls.c	(revision 146639)
+++ config/vxlib-tls.c	(working copy)
@@ -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_UNU
   
   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_UNU
 	    }
 	}
       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 k
   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)

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]