diff options
author | Nathan Sidwell <nathan@codesourcery.com> | 2009-04-23 10:39:24 +0000 |
---|---|---|
committer | Nathan Sidwell <nathan@gcc.gnu.org> | 2009-04-23 10:39:24 +0000 |
commit | b2f21330f7bc725e088522d63070b05f0253a672 (patch) | |
tree | a68753e7f723e4501f53e6f560f35058bb22ce31 /gcc/config | |
parent | ee721644f5958a0bf1d40aabd8e0dfaa6f8ed870 (diff) | |
download | gcc-b2f21330f7bc725e088522d63070b05f0253a672.zip gcc-b2f21330f7bc725e088522d63070b05f0253a672.tar.gz gcc-b2f21330f7bc725e088522d63070b05f0253a672.tar.bz2 |
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
Diffstat (limited to 'gcc/config')
-rw-r--r-- | gcc/config/vxlib-tls.c | 52 |
1 files changed, 27 insertions, 25 deletions
diff --git a/gcc/config/vxlib-tls.c b/gcc/config/vxlib-tls.c index 9747aa3..c469676 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) |