2002-12-05 Roland McGrath <roland@redhat.com>
authorroland <roland>
Fri, 6 Dec 2002 11:12:08 +0000 (11:12 +0000)
committerroland <roland>
Fri, 6 Dec 2002 11:12:08 +0000 (11:12 +0000)
* sysdeps/i386/tls.h (TLS_INIT_TP): Make it return zero or an error
string.
(TLS_DO_SET_THREAD_AREA, TLS_DO_MODIFY_LDT, TLS_SETUP_GS_SEGMENT):
Submacros updated.
* sysdeps/x86_64/tls.h (TLS_INIT_TP): Likewise.
* sysdeps/alpha/tls.h (TLS_INIT_TP): Likewise (always zero).

linuxthreads/sysdeps/alpha/tls.h
linuxthreads/sysdeps/i386/tls.h
linuxthreads/sysdeps/x86_64/tls.h

index c5cdc0a..98d0d9f 100644 (file)
@@ -92,6 +92,7 @@ typedef struct
     register tcbhead_t *__self = (void *)(descr);              \
     __self->tcb = __self;                                      \
     __builtin_set_thread_pointer(__self);                      \
+    0;                                                         \
   })
 
 /* Return the address of the dtv for the current thread.  */
index 8bbe5f2..c244801 100644 (file)
@@ -106,20 +106,18 @@ typedef struct
 #  endif
 
 #  if __ASSUME_LDT_WORKS > 0
-#   define TLS_DO_MODIFY_LDT_KERNEL_CHECK /* Nothing to do.  */
+#   define TLS_DO_MODIFY_LDT_KERNEL_CHECK(doit) (doit) /* Nothing to check.  */
 #  else
 #   include "useldt.h"         /* For the structure.  */
-#   define TLS_DO_MODIFY_LDT_KERNEL_CHECK                                    \
-  if (__builtin_expect (GL(dl_osversion) < 131939, 0))                       \
-    _dl_fatal_printf ("kernel %u.%u.%u cannot support thread-local storage\n",\
-                     (GL(dl_osversion) >> 16) & 0xff,                        \
-                     (GL(dl_osversion) >> 8) & 0xff,                         \
-                     (GL(dl_osversion) >> 0) & 0xff);
+#   define TLS_DO_MODIFY_LDT_KERNEL_CHECK(doit)                                      \
+  (__builtin_expect (GL(dl_osversion) < 131939, 0)                           \
+   ? "kernel too old for thread-local storage support"                       \
+   : (doit))
 #  endif
 
 #  define TLS_DO_MODIFY_LDT(descr, nr)                                       \
+TLS_DO_MODIFY_LDT_KERNEL_CHECK(                                                      \
 ({                                                                           \
-  TLS_DO_MODIFY_LDT_KERNEL_CHECK                                             \
   struct modify_ldt_ldt_s ldt_entry =                                        \
     { nr, (unsigned long int) (descr), 0xfffff /* 4GB in pages */,           \
       1, 0, 0, 1, 0, 1, 0 };                                                 \
@@ -134,8 +132,10 @@ typedef struct
                   here.  */                                                  \
                "m" (ldt_entry), TLS_EBX_ARG (1), "c" (&ldt_entry),           \
                "d" (sizeof (ldt_entry)));                                    \
-  __builtin_expect (result, 0) != 0 ? -1 : nr * 8 + 7;                       \
-})
+  __builtin_expect (result, 0) == 0                                          \
+  ? ({ asm ("movw %w0, %%gs" : : "q" ((nr) * 8 + 7)); NULL; })               \
+  : "cannot set up LDT for thread-local storage";                            \
+}))
 
 #  define TLS_DO_SET_THREAD_AREA(descr, secondcall)                          \
 ({                                                                           \
@@ -156,41 +156,40 @@ typedef struct
                   to let the compiler know that we are accessing LDT_ENTRY   \
                   here.  */                                                  \
                TLS_EBX_ARG (&ldt_entry), "m" (ldt_entry));                   \
-    __builtin_expect (result, 0) == 0 ? ldt_entry.entry_number * 8 + 3 : -1;  \
+  if (__builtin_expect (result, 0) == 0)                                     \
+    asm ("movw %w0, %%gs" : : "q" (ldt_entry.entry_number * 8 + 3));         \
+  result;                                                                    \
 })
 
 #  ifdef __ASSUME_SET_THREAD_AREA_SYSCALL
-#   define TLS_SETUP_GS_SEGMENT(descr, secondcall) \
-  TLS_DO_SET_THREAD_AREA (descr, firstcall)
+#   define TLS_SETUP_GS_SEGMENT(descr, secondcall)                           \
+  (TLS_DO_SET_THREAD_AREA (descr, firstcall)                                 \
+   ? "set_thread_area failed when setting up thread-local storage" : NULL)
 #  elif defined __NR_set_thread_area
 #   define TLS_SETUP_GS_SEGMENT(descr, secondcall) \
-  ({ int __seg = TLS_DO_SET_THREAD_AREA (descr, secondcall); \
-     __seg == -1 ? TLS_DO_MODIFY_LDT (descr, 0) : __seg; })
+  (TLS_DO_SET_THREAD_AREA (descr, secondcall)                                \
+   ? TLS_DO_MODIFY_LDT (descr, 0) : NULL)
 #  else
 #   define TLS_SETUP_GS_SEGMENT(descr, secondcall) \
   TLS_DO_MODIFY_LDT ((descr), 0)
 #  endif
 
+
 /* Code to initially initialize the thread pointer.  This might need
    special attention since 'errno' is not yet available and if the
-   operation can cause a failure 'errno' must not be touched.  */
+   operation can cause a failure 'errno' must not be touched.
+
+   The value of this macro is null if successful, or an error string.  */
 #  define TLS_INIT_TP(descr, secondcall)                                     \
   ({                                                                         \
     void *_descr = (descr);                                                  \
     tcbhead_t *head = _descr;                                                \
-    int __gs;                                                                \
                                                                              \
     head->tcb = _descr;                                                              \
     /* For now the thread descriptor is at the same address.  */             \
     head->self = _descr;                                                     \
                                                                              \
-    __gs = TLS_SETUP_GS_SEGMENT (_descr, secondcall);                        \
-    if (__builtin_expect (__gs, 7) != -1)                                    \
-      {                                                                              \
-       asm ("movw %w0, %%gs" : : "q" (__gs));                                \
-       __gs = 0;                                                             \
-      }                                                                              \
-    __gs;                                                                    \
+    TLS_SETUP_GS_SEGMENT (_descr, secondcall);                               \
   })
 
 
index e886760..a649898 100644 (file)
@@ -105,7 +105,8 @@ typedef struct
                    "D" ((unsigned long int) ARCH_SET_FS),                    \
                    "S" (_descr)                                              \
                  : "memory", "cc", "r11", "cx");                             \
-    _result ? -1 : 0;                                                        \
+                                                                             \
+    _result ? "cannot set %fs base address for thread-local storage" : 0;     \
   })
 
 /* Return the address of the dtv for the current thread.  */