aboutsummaryrefslogtreecommitdiff
path: root/linuxthreads
diff options
context:
space:
mode:
Diffstat (limited to 'linuxthreads')
-rw-r--r--linuxthreads/ChangeLog6
-rw-r--r--linuxthreads/pthread.c42
2 files changed, 48 insertions, 0 deletions
diff --git a/linuxthreads/ChangeLog b/linuxthreads/ChangeLog
index b151dc3406..288d3523ab 100644
--- a/linuxthreads/ChangeLog
+++ b/linuxthreads/ChangeLog
@@ -1,3 +1,9 @@
+2003-07-30 Jakub Jelinek <jakub@redhat.com>
+
+ * pthread.c (init_one_static_tls, __pthread_init_static_tls): New
+ functions.
+ (pthread_initialize): Initialize GL(dl_init_static_tls).
+
2003-06-19 Daniel Jacobowitz <drow@mvista.com>
* sysdeps/pthread/timer_create.c (timer_create): Call timer_delref
diff --git a/linuxthreads/pthread.c b/linuxthreads/pthread.c
index 6211124b31..f7081139b2 100644
--- a/linuxthreads/pthread.c
+++ b/linuxthreads/pthread.c
@@ -462,6 +462,44 @@ __libc_dl_error_tsd (void)
# endif
#endif
+#ifdef USE_TLS
+static inline void __attribute__((always_inline))
+init_one_static_tls (pthread_descr descr, struct link_map *map)
+{
+# if TLS_TCB_AT_TP
+ dtv_t *dtv = GET_DTV (descr);
+ void *dest = (char *) descr - map->l_tls_offset;
+# elif TLS_DTV_AT_TP
+ dtv_t *dtv = GET_DTV ((pthread_descr) ((char *) descr + TLS_PRE_TCB_SIZE));
+ void *dest = (char *) descr + map->l_tls_offset + TLS_PRE_TCB_SIZE;
+# else
+# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
+# endif
+
+ /* Fill in the DTV slot so that a later LD/GD access will find it. */
+ dtv[map->l_tls_modid].pointer = dest;
+
+ /* Initialize the memory. */
+ memset (__mempcpy (dest, map->l_tls_initimage, map->l_tls_initimage_size),
+ '\0', map->l_tls_blocksize - map->l_tls_initimage_size);
+}
+
+static void
+__pthread_init_static_tls (struct link_map *map)
+{
+ size_t i;
+
+ for (i = 0; i < PTHREAD_THREADS_MAX; ++i)
+ if (__pthread_handles[i].h_descr != NULL && i != 1)
+ {
+ __pthread_lock (&__pthread_handles[i].h_lock, NULL);
+ if (__pthread_handles[i].h_descr != NULL)
+ init_one_static_tls (__pthread_handles[i].h_descr, map);
+ __pthread_unlock (&__pthread_handles[i].h_lock);
+ }
+}
+#endif
+
static void pthread_initialize(void)
{
struct sigaction sa;
@@ -551,6 +589,10 @@ static void pthread_initialize(void)
*__libc_dl_error_tsd () = *(*GL(dl_error_catch_tsd)) ();
GL(dl_error_catch_tsd) = &__libc_dl_error_tsd;
#endif
+
+#ifdef USE_TLS
+ GL(dl_init_static_tls) = &__pthread_init_static_tls;
+#endif
}
void __pthread_initialize(void)