Mercurial > hg > CbC > CbC_gcc
comparison gcc/config/vxlib-tls.c @ 55:77e2b8dfacca gcc-4.4.5
update it from 4.4.3 to 4.5.0
author | ryoma <e075725@ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 12 Feb 2010 23:39:51 +0900 |
parents | a06113de4d67 |
children |
comparison
equal
deleted
inserted
replaced
52:c156f1bd5cd9 | 55:77e2b8dfacca |
---|---|
89 | 89 |
90 /* To make sure we only delete TLS data associated with this object, | 90 /* To make sure we only delete TLS data associated with this object, |
91 include a pointer to a local variable in the TLS data object. */ | 91 include a pointer to a local variable in the TLS data object. */ |
92 static int self_owner; | 92 static int self_owner; |
93 | 93 |
94 /* The number of threads for this module which have active TLS data. | 94 /* Flag to check whether the delete hook is installed. Once installed |
95 This is protected by tls_lock. */ | 95 it is only removed when unloading this module. */ |
96 static int active_tls_threads; | 96 static volatile int delete_hook_installed; |
97 | 97 |
98 /* kernel provided routines */ | 98 /* kernel provided routines */ |
99 extern void *__gthread_get_tls_data (void); | 99 extern void *__gthread_get_tls_data (void); |
100 extern void __gthread_set_tls_data (void *data); | 100 extern void __gthread_set_tls_data (void *data); |
101 | 101 |
164 data = __gthread_get_tsd_data (tcb); | 164 data = __gthread_get_tsd_data (tcb); |
165 #endif | 165 #endif |
166 | 166 |
167 if (data && data->owner == &self_owner) | 167 if (data && data->owner == &self_owner) |
168 { | 168 { |
169 #ifdef __RTP__ | |
169 __gthread_enter_tls_dtor_context (); | 170 __gthread_enter_tls_dtor_context (); |
171 #else | |
172 __gthread_enter_tsd_dtor_context (tcb); | |
173 #endif | |
170 for (key = 0; key < MAX_KEYS; key++) | 174 for (key = 0; key < MAX_KEYS; key++) |
171 { | 175 { |
172 if (data->generation[key] == tls_keys.generation[key]) | 176 if (data->generation[key] == tls_keys.generation[key]) |
173 { | 177 { |
174 tls_dtor dtor = tls_keys.dtor[key]; | 178 tls_dtor dtor = tls_keys.dtor[key]; |
176 if (dtor) | 180 if (dtor) |
177 dtor (data->values[key]); | 181 dtor (data->values[key]); |
178 } | 182 } |
179 } | 183 } |
180 free (data); | 184 free (data); |
181 | 185 #ifdef __RTP__ |
182 /* We can't handle an error here, so just leave the thread | 186 __gthread_leave_tls_dtor_context (); |
183 marked as loaded if one occurs. */ | 187 #else |
184 if (__gthread_mutex_lock (&tls_lock) != ERROR) | 188 __gthread_leave_tsd_dtor_context (); |
185 { | 189 #endif |
186 active_tls_threads--; | 190 |
187 if (active_tls_threads == 0) | |
188 taskDeleteHookDelete ((FUNCPTR)tls_delete_hook); | |
189 __gthread_mutex_unlock (&tls_lock); | |
190 } | |
191 #ifdef __RTP__ | 191 #ifdef __RTP__ |
192 __gthread_set_tls_data (0); | 192 __gthread_set_tls_data (0); |
193 #else | 193 #else |
194 __gthread_set_tsd_data (tcb, 0); | 194 __gthread_set_tsd_data (tcb, 0); |
195 #endif | 195 #endif |
196 __gthread_leave_tls_dtor_context (); | |
197 } | 196 } |
198 } | 197 } |
199 | 198 |
200 /* Initialize global data used by the TLS system. */ | 199 /* Initialize global data used by the TLS system. */ |
201 static void | 200 static void |
209 tls_destructor (void) | 208 tls_destructor (void) |
210 { | 209 { |
211 #ifdef __RTP__ | 210 #ifdef __RTP__ |
212 /* All threads but this one should have exited by now. */ | 211 /* All threads but this one should have exited by now. */ |
213 tls_delete_hook (NULL); | 212 tls_delete_hook (NULL); |
214 #else | 213 #endif |
215 /* Unregister the hook forcibly. The counter of active threads may | 214 /* Unregister the hook. */ |
216 be incorrect, because constructors (like the C++ library's) and | 215 if (delete_hook_installed) |
217 destructors (like this one) run in the context of the shell rather | 216 taskDeleteHookDelete ((FUNCPTR)tls_delete_hook); |
218 than in a task spawned from this module. */ | |
219 taskDeleteHookDelete ((FUNCPTR)tls_delete_hook); | |
220 #endif | |
221 | 217 |
222 if (tls_init_guard.done && __gthread_mutex_lock (&tls_lock) != ERROR) | 218 if (tls_init_guard.done && __gthread_mutex_lock (&tls_lock) != ERROR) |
223 semDelete (tls_lock); | 219 semDelete (tls_lock); |
224 } | 220 } |
225 | 221 |
329 return EINVAL; | 325 return EINVAL; |
330 | 326 |
331 data = __gthread_get_tls_data (); | 327 data = __gthread_get_tls_data (); |
332 if (!data) | 328 if (!data) |
333 { | 329 { |
334 if (__gthread_mutex_lock (&tls_lock) == ERROR) | 330 if (!delete_hook_installed) |
335 return ENOMEM; | 331 { |
336 if (active_tls_threads == 0) | 332 /* Install the delete hook. */ |
337 taskDeleteHookAdd ((FUNCPTR)tls_delete_hook); | 333 if (__gthread_mutex_lock (&tls_lock) == ERROR) |
338 active_tls_threads++; | 334 return ENOMEM; |
339 __gthread_mutex_unlock (&tls_lock); | 335 if (!delete_hook_installed) |
336 { | |
337 taskDeleteHookAdd ((FUNCPTR)tls_delete_hook); | |
338 delete_hook_installed = 1; | |
339 } | |
340 __gthread_mutex_unlock (&tls_lock); | |
341 } | |
340 | 342 |
341 data = malloc (sizeof (struct tls_data)); | 343 data = malloc (sizeof (struct tls_data)); |
342 if (!data) | 344 if (!data) |
343 return ENOMEM; | 345 return ENOMEM; |
344 | 346 |