about summary refs log tree commit diff
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)