From de9a5225bfa876c0830a207b879d9df7b8a3255e Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Thu, 22 Aug 2002 23:47:18 +0000 Subject: 2002-08-22 Roland McGrath * 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. --- linuxthreads/sysdeps/i386/useldt.h | 53 ++++++++++++++++++++++++++++---------- 1 file changed, 39 insertions(+), 14 deletions(-) (limited to 'linuxthreads') 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); \ }) -- cgit v1.2.3