about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRoland McGrath <roland@gnu.org>2002-08-22 23:47:18 +0000
committerRoland McGrath <roland@gnu.org>2002-08-22 23:47:18 +0000
commitde9a5225bfa876c0830a207b879d9df7b8a3255e (patch)
tree47d4423975f30b61ac2dc8ab1068337cbbc8430a
parentb8a5737a496ae3893f5f924852ad2cec565457b4 (diff)
downloadglibc-de9a5225bfa876c0830a207b879d9df7b8a3255e.tar.gz
glibc-de9a5225bfa876c0830a207b879d9df7b8a3255e.tar.xz
glibc-de9a5225bfa876c0830a207b879d9df7b8a3255e.zip
2002-08-22 Roland McGrath <roland@redhat.com>
	* sysdeps/i386/useldt.h (INIT_THREAD_SELF): Remove [HAVE_TLS_SUPPORT]
	conditional.
	(INIT_THREAD_SELF): Pass second arg to DO_SET_THREAD_AREA.
	(DO_SET_THREAD_AREA): Take second arg, pass to DO_SET_THREAD_AREA_REUSE
	macro.  That chooses whether to reuse %gs value or let kernel set it.
	[USE_TLS] (DO_SET_THREAD_AREA_REUSE): New macro, always 1.
	[!USE_TLS] (DO_SET_THREAD_AREA_REUSE): New macro, true if arg is
	not constant 0.
-rw-r--r--linuxthreads/sysdeps/i386/useldt.h53
1 files changed, 39 insertions, 14 deletions
diff --git a/linuxthreads/sysdeps/i386/useldt.h b/linuxthreads/sysdeps/i386/useldt.h
index 8c77c4a34b..91d7d7c1d8 100644
--- a/linuxthreads/sysdeps/i386/useldt.h
+++ b/linuxthreads/sysdeps/i386/useldt.h
@@ -79,28 +79,53 @@ extern int __modify_ldt (int, struct modify_ldt_ldt_s *, size_t);
    because we inherited the value set up in the main thread by TLS setup.
    We need to extract that value and set up the same segment in this
    thread.  */
-# define DO_SET_THREAD_AREA(descr)					      \
+# if USE_TLS
+#  define DO_SET_THREAD_AREA_REUSE(nr)	1
+# else
+/* Without TLS, we do the initialization of the main thread, where NR == 0.  */
+#  define DO_SET_THREAD_AREA_REUSE(nr)	(!__builtin_constant_p (nr) || (nr))
+# endif
+# define DO_SET_THREAD_AREA(descr, nr)					      \
 ({									      \
   int __gs;								      \
-  struct modify_ldt_ldt_s ldt_entry =					      \
-    { ({ asm ("movw %%gs, %w0" : "=q" (__gs)); (__gs & 0xffff) >> 3; }),      \
-      (unsigned long int) descr, sizeof (struct _pthread_descr_struct),	      \
-      1, 0, 0, 0, 0, 1, 0 };						      \
-  if (__builtin_expect (INLINE_SYSCALL (set_thread_area, 1, &ldt_entry) == 0, \
-      			1))						      \
-    asm ("movw %w0, %%gs" :: "q" (__gs));				      \
+  if (DO_SET_THREAD_AREA_REUSE (nr))					      \
+    {									      \
+      asm ("movw %%gs, %w0" : "=q" (__gs));				      \
+      struct modify_ldt_ldt_s ldt_entry =				      \
+	{ (__gs & 0xffff) >> 3,						      \
+	  (unsigned long int) descr, sizeof (struct _pthread_descr_struct),   \
+	  1, 0, 0, 0, 0, 1, 0 };					      \
+      if (__builtin_expect (INLINE_SYSCALL (set_thread_area, 1, &ldt_entry),  \
+			    0) == 0)					      \
+	asm ("movw %w0, %%gs" :: "q" (__gs));				      \
+      else								      \
+	__gs = -1;							      \
+    }									      \
   else									      \
-    __gs = -1;								      \
-  __gs;		      							      \
+    {									      \
+      struct modify_ldt_ldt_s ldt_entry =				      \
+	{ -1,								      \
+	  (unsigned long int) descr, sizeof (struct _pthread_descr_struct),   \
+	  1, 0, 0, 0, 0, 1, 0 };					      \
+      if (__builtin_expect (INLINE_SYSCALL (set_thread_area, 1, &ldt_entry),  \
+			    0) == 0)					      \
+	{								      \
+	  __gs = (ldt_entry.entry_number << 3) + 3;			      \
+	  asm ("movw %w0, %%gs" : : "q" (__gs));			      \
+	}								      \
+      else								      \
+	__gs = -1;							      \
+    }									      \
+  __gs;									      \
 })
 
-#if defined __ASSUME_SET_THREAD_AREA_SYSCALL && defined HAVE_TLS_SUPPORT
-# define INIT_THREAD_SELF(descr, nr)	DO_SET_THREAD_AREA (descr)
-#elif defined __NR_set_thread_area && defined HAVE_TLS_SUPPORT
+#if defined __ASSUME_SET_THREAD_AREA_SYSCALL
+# define INIT_THREAD_SELF(descr, nr)	DO_SET_THREAD_AREA (descr, nr)
+#elif defined __NR_set_thread_area
 # define INIT_THREAD_SELF(descr, nr)					      \
 ({									      \
   if (__builtin_expect (__have_no_set_thread_area, 0)			      \
-      || (DO_SET_THREAD_AREA (descr) == -1				      \
+      || (DO_SET_THREAD_AREA (descr, DO_SET_THREAD_AREA_REUSE (nr)) == -1     \
 	  && (__have_no_set_thread_area = 1)))				      \
     DO_MODIFY_LDT (descr, nr);						      \
 })