@@ -467,9 +467,15 @@ static inline struct gomp_thread *gomp_thread (void)
}
#else
extern pthread_key_t gomp_tls_key;
-static inline struct gomp_thread *gomp_thread (void)
+extern struct gomp_thread *create_non_tls_thread_data (void);
+static 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;
}
#endif
@@ -41,6 +41,7 @@ pthread_key_t gomp_thread_destructor;
__thread struct gomp_thread gomp_tls_data;
#else
pthread_key_t gomp_tls_key;
+struct gomp_thread initial_thread_tls_data;
#endif
@@ -130,6 +131,9 @@ gomp_thread_start (void *xdata)
gomp_sem_destroy (&thr->release);
thr->thread_pool = NULL;
thr->task = NULL;
+#ifndef HAVE_TLS
+ pthread_setspecific (gomp_tls_key, NULL);
+#endif
return NULL;
}
@@ -222,8 +226,16 @@ gomp_free_pool_helper (void *thread_pool)
void
gomp_free_thread (void *arg __attribute__((unused)))
{
- struct gomp_thread *thr = gomp_thread ();
- struct gomp_thread_pool *pool = thr->thread_pool;
+ struct gomp_thread *thr;
+ struct gomp_thread_pool *pool;
+#ifdef HAVE_TLS
+ thr = gomp_thread ();
+#else
+ thr = pthread_getspecific (gomp_tls_key);
+ if (thr == NULL)
+ return;
+#endif
+ pool = thr->thread_pool;
if (pool)
{
if (pool->threads_used > 0)
@@ -910,6 +922,21 @@ gomp_team_end (void)
}
}
+/* Destructor for data created in create_non_tls_thread_data. */
+
+#ifndef HAVE_TLS
+void
+non_tls_thread_data_destructor (void *arg __attribute__((unused)))
+{
+ struct gomp_thread *thr = pthread_getspecific (gomp_tls_key);
+ if (thr != NULL && thr != &initial_thread_tls_data)
+ {
+ gomp_free_thread (arg);
+ free (thr);
+ pthread_setspecific (gomp_tls_key, NULL);
+ }
+}
+#endif
/* Constructors for this file. */
@@ -917,9 +944,7 @@ static void __attribute__((constructor))
initialize_team (void)
{
#ifndef HAVE_TLS
- static struct gomp_thread initial_thread_tls_data;
-
- pthread_key_create (&gomp_tls_key, NULL);
+ pthread_key_create (&gomp_tls_key, non_tls_thread_data_destructor);
pthread_setspecific (gomp_tls_key, &initial_thread_tls_data);
#endif
@@ -927,6 +952,19 @@ initialize_team (void)
gomp_fatal ("could not create thread pool destructor.");
}
+/* Create data for thread created by pthread_create. */
+
+#ifndef HAVE_TLS
+struct gomp_thread *create_non_tls_thread_data (void)
+{
+ struct gomp_thread *thr = gomp_malloc_cleared (sizeof (struct gomp_thread));
+ pthread_setspecific (gomp_tls_key, thr);
+ gomp_sem_init (&thr->release, 0);
+
+ return thr;
+}
+#endif
+
static void __attribute__((destructor))
team_destructor (void)
{