May I use gomp_free_thread as a destructor for pthread_key_create? Then I'll make initial_thread_tls_data global for the first case, but how can I differentiate thread created by gomp_thread_start (second case)?
2014-09-01 14:51 GMT+04:00 Jakub Jelinek <ja...@redhat.com>: > On Fri, Aug 29, 2014 at 10:40:57AM -0700, Richard Henderson wrote: >> On 08/06/2014 03:05 AM, Varvara Rainchik wrote: >> > * libgomp.h (gomp_thread): For non TLS case create thread data. >> > * team.c (create_non_tls_thread_data): New function. >> > >> > >> > --- >> > diff --git a/libgomp/libgomp.h b/libgomp/libgomp.h >> > index a1482cc..cf3ec8f 100644 >> > --- a/libgomp/libgomp.h >> > +++ b/libgomp/libgomp.h >> > @@ -479,9 +479,15 @@ static inline struct gomp_thread *gomp_thread (void) >> > } >> > #else >> > extern pthread_key_t gomp_tls_key; >> > +extern struct gomp_thread *create_non_tls_thread_data (void); >> > static inline struct gomp_thread *gomp_thread (void) >> > { >> > - return pthread_getspecific (gomp_tls_key); >> > + struct gomp_thread *thr = pthread_getspecific (gomp_tls_key); >> > + if (thr == NULL) >> > + { >> > + thr = create_non_tls_thread_data (); >> > + } >> > + return thr; >> > } >> >> This should never happen. > > I guess it can happen if you mix up explicit pthread_create and libgomp APIs. > initialize_team will only initialize it in the initial thread, while if you > use #pragma omp ... or omp_* calls from a thread created with > pthread_create, in the !HAVE_TLS case pthread_getspecific will return NULL. > > Now, the patch doesn't handle that case completely though (and is badly > formatted), the problem is that if we allocate in the !HAVE_TLS case > in non-initial thread the TLS data, we want to free them again, so that > would mean pthread_key_create with non-NULL destructor, and then we need to > differentiate in between the 3 cases - key equal to &initial_thread_tls_data > (would need to move out of the block context), no freeing needed, thread > created by gomp_thread_start, no freeing needed, otherwise free. > >> The thread-specific data is set in gomp_thread_start and initialize_team. >> >> Where are you getting a call to gomp_thread that hasn't been through one of >> those functions? > > Jakub