diff options
author | Roland McGrath <roland@gnu.org> | 2002-08-22 23:47:18 +0000 |
---|---|---|
committer | Roland McGrath <roland@gnu.org> | 2002-08-22 23:47:18 +0000 |
commit | de9a5225bfa876c0830a207b879d9df7b8a3255e (patch) | |
tree | 47d4423975f30b61ac2dc8ab1068337cbbc8430a | |
parent | b8a5737a496ae3893f5f924852ad2cec565457b4 (diff) | |
download | glibc-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.h | 53 |
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); \ }) |