This is the mail archive of the libc-alpha@sources.redhat.com mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] PPC linuxthreads tls.h fix


> I couldn't get linuxthreads/sysdeps/powerpc/tcb-offsets.sym to
> generate offsets relating to the _pthread_descr_struct.

Please try the follow patch against the current glibc cvs.  I am not
putting this in yet because it touches generic code and other platforms
(there are a few more diffs not included here).  It's only relevant to
TLS, and we might want to release 2.3.2 now without perturbing it more.
--without-tls will still be the default for 2.3.2, and it seems reasonable
to release it as is now and say that TLS only really works on x86/x86_64 yet.

Thanks,
Roland


Index: linuxthreads/descr.h
===================================================================
RCS file: /cvs/glibc/libc/linuxthreads/descr.h,v
retrieving revision 1.8
diff -p -u -r1.8 descr.h
--- linuxthreads/descr.h	28 Dec 2002 10:14:16 -0000	1.8
+++ linuxthreads/descr.h	28 Feb 2003 05:45:07 -0000
@@ -23,6 +23,7 @@
 #include <stdint.h>
 #include <sys/types.h>
 #include <hp-timing.h>
+#include <tls.h>
 
 /* Fast thread-specific data internal to libc.  */
 enum __libc_tsd_key_t { _LIBC_TSD_KEY_MALLOC = 0,
@@ -106,11 +107,14 @@ typedef struct _pthread_rwlock_info {
 
 union dtv;
 
-
-struct _pthread_descr_struct {
-  /* XXX Remove this union for IA-64 style TLS module */
-  union {
-    struct {
+struct _pthread_descr_struct
+{
+#if !defined USE_TLS || !TLS_DTV_AT_TP
+  /* This overlaps tcbhead_t (see tls.h), as used for TLS without threads.  */
+  union
+  {
+    struct
+    {
       void *tcb;		/* Pointer to the TCB.  This is not always
 				   the address of this thread descriptor.  */
       union dtv *dtvp;
@@ -122,6 +126,11 @@ struct _pthread_descr_struct {
     } data;
     void *__padding[16];
   } p_header;
+# define p_multiple_threads p_header.data.multiple_threads
+#elif TLS_MULTIPLE_THREADS_IN_TCB
+  int p_multiple_threads;
+#endif
+
   pthread_descr p_nextlive, p_prevlive;
                                 /* Double chaining of active threads */
   pthread_descr p_nextwaiting;  /* Next element in the queue holding the thr */
Index: linuxthreads/manager.c
===================================================================
RCS file: /cvs/glibc/libc/linuxthreads/manager.c,v
retrieving revision 1.90
diff -p -u -r1.90 manager.c
--- linuxthreads/manager.c	12 Jan 2003 08:42:38 -0000	1.90
+++ linuxthreads/manager.c	28 Feb 2003 05:45:07 -0000
@@ -638,13 +638,13 @@ static int pthread_handle_create(pthread
   new_thread_id = sseg + pthread_threads_counter;
   /* Initialize the thread descriptor.  Elements which have to be
      initialized to zero already have this value.  */
-#if defined USE_TLS && TLS_DTV_AT_TP
-  new_thread->p_header.data.tcb = new_thread + 1;
-#else
+#if !defined USE_TLS || !TLS_DTV_AT_TP
   new_thread->p_header.data.tcb = new_thread;
-#endif
   new_thread->p_header.data.self = new_thread;
-  new_thread->p_header.data.multiple_threads = 1;
+#endif
+#if TLS_MULTIPLE_THREADS_IN_TCB || !defined USE_TLS || !TLS_DTV_AT_TP
+  new_thread->p_multiple_threads = 1;
+#endif
   new_thread->p_tid = new_thread_id;
   new_thread->p_lock = &(__pthread_handles[sseg].h_lock);
   new_thread->p_cancelstate = PTHREAD_CANCEL_ENABLE;
Index: linuxthreads/pthread.c
===================================================================
RCS file: /cvs/glibc/libc/linuxthreads/pthread.c,v
retrieving revision 1.119
diff -p -u -r1.119 pthread.c
--- linuxthreads/pthread.c	16 Jan 2003 18:16:32 -0000	1.119
+++ linuxthreads/pthread.c	28 Feb 2003 05:45:08 -0000
@@ -566,8 +566,10 @@ int __pthread_initialize_manager(void)
 #endif
 
   __pthread_multiple_threads = 1;
-  __pthread_main_thread->p_header.data.multiple_threads = 1;
-  * __libc_multiple_threads_ptr = 1;
+#if TLS_MULTIPLE_THREADS_IN_TCB || !defined USE_TLS || !TLS_DTV_AT_TP
+  __pthread_main_thread->p_multiple_threads = 1;
+#endif
+  *__libc_multiple_threads_ptr = 1;
 
 #ifndef HAVE_Z_NODELETE
   if (__builtin_expect (&__dso_handle != NULL, 1))
@@ -611,9 +613,13 @@ int __pthread_initialize_manager(void)
   __pthread_handles[1].h_descr = manager_thread = mgr;
 
   /* Initialize the descriptor.  */
+#if !defined USE_TLS || !TLS_DTV_AT_TP
   mgr->p_header.data.tcb = tcbp;
   mgr->p_header.data.self = mgr;
   mgr->p_header.data.multiple_threads = 1;
+#elif TLS_MULTIPLE_THREADS_IN_TCB
+  mgr->p_multiple_threads = 1;
+#endif
   mgr->p_lock = &__pthread_handles[1].h_lock;
 # ifndef HAVE___THREAD
   mgr->p_errnop = &mgr->p_errno;
Index: linuxthreads/sysdeps/powerpc/tcb-offsets.sym
===================================================================
RCS file: /cvs/glibc/libc/linuxthreads/sysdeps/powerpc/tcb-offsets.sym,v
retrieving revision 1.1
diff -p -u -r1.1 tcb-offsets.sym
--- linuxthreads/sysdeps/powerpc/tcb-offsets.sym	17 Feb 2003 20:37:35 -0000	1.1
+++ linuxthreads/sysdeps/powerpc/tcb-offsets.sym	28 Feb 2003 05:45:09 -0000
@@ -1,4 +1,24 @@
 #include <sysdep.h>
 #include <tls.h>
 
-MULTIPLE_THREADS_OFFSET		offsetof (tcbhead_t, multiple_threads)
+--
+
+-- This could go into powerpc32/ instead and conditionalize #include of it.
+#ifndef __powerpc64__
+
+# ifdef USE_TLS
+
+/* Abuse tls.h macros to derive offsets relative to the thread register.  */
+#  undef __thread_register
+#  define __thread_register	((void *) 0)
+#  define thread_offsetof(mem)	((void *) &THREAD_SELF->p_##mem - (void *) 0)
+
+# else
+
+#  define thread_offsetof(mem)	offsetof (tcbhead_t, mem)
+
+# endif
+
+MULTIPLE_THREADS_OFFSET		thread_offsetof (multiple_threads)
+
+#endif
Index: linuxthreads/sysdeps/powerpc/tls.h
===================================================================
RCS file: /cvs/glibc/libc/linuxthreads/sysdeps/powerpc/tls.h,v
retrieving revision 1.2
diff -p -u -r1.2 tls.h
--- linuxthreads/sysdeps/powerpc/tls.h	27 Feb 2003 20:47:12 -0000	1.2
+++ linuxthreads/sysdeps/powerpc/tls.h	28 Feb 2003 05:45:09 -0000
@@ -32,15 +32,6 @@ typedef union dtv
   void *pointer;
 } dtv_t;
 
-typedef struct
-{
-  void *tcb;		/* Pointer to the TCB.  Not necessary the
-			   thread descriptor used by libpthread.  */
-  dtv_t *dtv;
-  void *self;		/* Pointer to the thread descriptor.  */
-  int multiple_threads;
-} tcbhead_t;
-
 #else /* __ASSEMBLER__ */
 # include <tcb-offsets.h>
 #endif /* __ASSEMBLER__ */
@@ -52,6 +43,14 @@ typedef struct
 
 # ifndef __ASSEMBLER__
 
+/* This layout is actually wholly private and not affected by the ABI.
+   Nor does it overlap the pthread data structure, so we need nothing
+   extra here at all.  */
+typedef struct
+{
+  dtv_t *dtv;
+} tcbhead_t;
+
 /* This is the size of the initial TCB.  */
 #  define TLS_INIT_TCB_SIZE	sizeof (tcbhead_t)
 
@@ -132,14 +131,33 @@ typedef struct
 #define THREAD_SETMEM_NC(descr, member, value) \
   THREAD_SETMEM ((descr), member, (value))
 
+/* Make sure we have the p_multiple_threads member in the thread structure.
+   See below.  */
+# ifndef __powerpc64__
+#  define TLS_MULTIPLE_THREADS_IN_TCB 1
+# endif
+
 # endif /* __ASSEMBLER__ */
 
-#else /* Not HAVE_TLS_SUPPORT.  */
+#elif !defined __ASSEMBLER__ && !defined __powerpc64__
+
+/* This overlaps the start of the pthread_descr.  On PPC32, system
+   calls and such use this to find the multiple_threads flag and need
+   to use the same offset relative to the thread register in both
+   single-threaded and multi-threaded code.  On PPC64, the global
+   variable is always used, so single-threaded code without TLS
+   never needs to initialize the thread register at all.  */
+typedef struct
+{
+  void *tcb;			/* Never used.  */
+  dtv_t *dtv;			/* Never used.  */
+  void *self;			/* Used only if multithreaded, and rarely.  */
+  int multiple_threads;		/* Only this member is really used.  */
+} tcbhead_t;
 
 #define NONTLS_INIT_TP							\
   do {									\
-    static const tcbhead_t nontls_init_tp				\
-      = { .multiple_threads = 0 };					\
+    static const tcbhead_t nontls_init_tp = { .multiple_threads = 0 };	\
     __thread_self = (__typeof (__thread_self)) &nontls_init_tp;		\
   } while (0)
 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]