aboutsummaryrefslogtreecommitdiff
path: root/linuxthreads
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 /linuxthreads
parentb8a5737a496ae3893f5f924852ad2cec565457b4 (diff)
downloadglibc-de9a5225bfa876c0830a207b879d9df7b8a3255e.tar
glibc-de9a5225bfa876c0830a207b879d9df7b8a3255e.tar.gz
glibc-de9a5225bfa876c0830a207b879d9df7b8a3255e.tar.bz2
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.
Diffstat (limited to 'linuxthreads')
-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); \
})