about summary refs log tree commit diff
path: root/linuxthreads/manager.c
diff options
context:
space:
mode:
Diffstat (limited to 'linuxthreads/manager.c')
-rw-r--r--linuxthreads/manager.c23
1 files changed, 20 insertions, 3 deletions
diff --git a/linuxthreads/manager.c b/linuxthreads/manager.c
index 3268ea8a41..8f9b23841b 100644
--- a/linuxthreads/manager.c
+++ b/linuxthreads/manager.c
@@ -590,6 +590,10 @@ static int pthread_handle_create(pthread_t *thread, const pthread_attr_t *attr,
   new_thread = _dl_allocate_tls (NULL);
   if (new_thread == NULL)
     return EAGAIN;
+# if TLS_DTV_AT_TP
+  /* pthread_descr is right below TP.  */
+  --new_thread;
+# endif
 #else
   /* Prevent warnings.  */
   new_thread = NULL;
@@ -607,6 +611,9 @@ static int pthread_handle_create(pthread_t *thread, const pthread_attr_t *attr,
       if (sseg >= PTHREAD_THREADS_MAX)
 	{
 #ifdef USE_TLS
+# if TLS_DTV_AT_TP
+	  ++new_thread;
+# endif
 	  _dl_deallocate_tls (new_thread, true);
 #endif
 	  return EAGAIN;
@@ -631,7 +638,11 @@ static int pthread_handle_create(pthread_t *thread, const pthread_attr_t *attr,
   new_thread_id = sseg + pthread_threads_counter;
   /* Initialize the thread descriptor.  Elements which have to be
      initialized to zero already have this value.  */
+#if defined USE_TLS && TLS_DTV_AT_TP
+  new_thread->p_header.data.tcb = new_thread + 1;
+#else
   new_thread->p_header.data.tcb = new_thread;
+#endif
   new_thread->p_header.data.self = new_thread;
   new_thread->p_header.data.multiple_threads = 1;
   new_thread->p_tid = new_thread_id;
@@ -711,15 +722,15 @@ static int pthread_handle_create(pthread_t *thread, const pthread_attr_t *attr,
 	   other, to get less paging and fewer mmaps.  */
 	  pid = __clone2(pthread_start_thread_event,
   		 (void **)new_thread_bottom,
-			 (char *)new_thread - new_thread_bottom,
+			 (char *)stack_addr - new_thread_bottom,
 			 CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND |
 			 __pthread_sig_cancel, new_thread);
 #elif _STACK_GROWS_UP
-	  pid = __clone(pthread_start_thread_event, (void **) new_thread_bottom,
+	  pid = __clone(pthread_start_thread_event, (void *) new_thread_bottom,
 			CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND |
 			__pthread_sig_cancel, new_thread);
 #else
-	  pid = __clone(pthread_start_thread_event, (void **) new_thread,
+	  pid = __clone(pthread_start_thread_event, stack_addr,
 			CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND |
 			__pthread_sig_cancel, new_thread);
 #endif
@@ -794,6 +805,9 @@ static int pthread_handle_create(pthread_t *thread, const pthread_attr_t *attr,
 #endif
       }
 #ifdef USE_TLS
+# if TLS_DTV_AT_TP
+    ++new_thread;
+# endif
     _dl_deallocate_tls (new_thread, true);
 #endif
     __pthread_handles[sseg].h_descr = NULL;
@@ -881,6 +895,9 @@ static void pthread_free(pthread_descr th)
       munmap(guardaddr, stacksize + guardsize);
 
 #ifdef USE_TLS
+# if TLS_DTV_AT_TP
+      ++th;
+# endif
       _dl_deallocate_tls (th, true);
 #endif
     }