about summary refs log tree commit diff
path: root/linuxthreads
diff options
context:
space:
mode:
Diffstat (limited to 'linuxthreads')
-rw-r--r--linuxthreads/ChangeLog35
-rw-r--r--linuxthreads/descr.h26
-rw-r--r--linuxthreads/manager.c12
-rw-r--r--linuxthreads/pthread.c8
-rw-r--r--linuxthreads/sysdeps/ia64/tcb-offsets.sym2
-rw-r--r--linuxthreads/sysdeps/powerpc/powerpc32/tcb-offsets.sym9
-rw-r--r--linuxthreads/sysdeps/powerpc/tcb-offsets.sym24
-rw-r--r--linuxthreads/sysdeps/powerpc/tls.h36
-rw-r--r--linuxthreads/sysdeps/sh/tcb-offsets.sym2
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/ia64/sysdep-cancel.h2
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h4
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h2
12 files changed, 100 insertions, 62 deletions
diff --git a/linuxthreads/ChangeLog b/linuxthreads/ChangeLog
index 59204cbc51..b8cd2282df 100644
--- a/linuxthreads/ChangeLog
+++ b/linuxthreads/ChangeLog
@@ -1,3 +1,38 @@
+2003-04-22  Jakub Jelinek  <jakub@redhat.com>
+
+	* descr.h (p_multiple_threads): Define as function-like macro.
+	(struct _pthread_descr_struct) [TLS_MULTIPLE_THREADS_IN_TCB]:
+	Move multiple_threads to last int in the structure.
+	* pthread.c (__pthread_initialize_manager): Use p_multiple_threads
+	macro.  Subtract TLS_PRE_TCB_SIZE bytes from tcbp to get to descr.
+	* manager.c (pthread_handle_create): Use p_multiple_threads macro.
+	Subtract or add TLS_PRE_TCB_SIZE instead of sizeof (pthread_descr).
+	(pthread_free): Add TLS_PRE_TCB_SIZE instead of
+	sizeof (pthread_descr).
+	* sysdeps/powerpc/tls.h: Don't include tcb-offsets.h.
+	(TLS_INIT_TCB_SIZE, TLS_TCB_SIZE): Define to 0.
+	(TLS_INIT_TCB_ALIGN, TLS_TCB_ALIGN): Define to alignment of
+	pthread_descr.
+	(TLS_PRE_TCB_SIZE): Increase to cover tcbhead_t preceeded by pad
+	to TLS_TCB_ALIGN.
+	(INSTALL_DTV, GET_DTV, THREAD_DTV): tcbhead_t is immediately before
+	tcbp.
+	(TLS_INIT_TP, THREAD_SELF, INIT_THREAD_SELF): Don't add TLS_TCB_SIZE
+	unneccessarily.
+	(NO_TLS_OFFSET): Define.
+	* sysdeps/powerpc/powerpc32/tcb-offsets.sym: New file.
+	* sysdeps/powerpc/tcb-offsets.sym: Removed.
+	* sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h: Include
+	tcb-offsets.h if __ASSEMBLER__.
+	(SINGLE_THREAD_P): Use p_multiple_threads macro.
+	* sysdeps/ia64/tcb-offsets.sym (MULTIPLE_THREADS): Define to
+	-sizeof(int).
+	* sysdeps/unix/sysv/linux/ia64/sysdep-cancel.h (SINGLE_THREAD_P):
+	Use p_multiple_threads macro.
+	* sysdeps/unix/sysv/linux/sh/sysdep-cancel.h (SINGLE_THREAD_P):
+	Likewise.
+	* sysdeps/sh/tcb-offsets.sym (MULTIPLE_THREADS): Likewise.
+
 2003-04-22  Roland McGrath  <roland@redhat.com>
 
 	* Makeconfig (shared-thread-library): Reverse link order to work
diff --git a/linuxthreads/descr.h b/linuxthreads/descr.h
index 2dcb37642a..dd496f6d0f 100644
--- a/linuxthreads/descr.h
+++ b/linuxthreads/descr.h
@@ -120,17 +120,14 @@ struct _pthread_descr_struct
       union dtv *dtvp;
       pthread_descr self;	/* Pointer to this structure */
       int multiple_threads;
-#ifdef NEED_DL_SYSINFO
+# define p_multiple_threads(descr) (descr)->p_header.data.multiple_threads
+# ifdef NEED_DL_SYSINFO
       uintptr_t sysinfo;
-#endif
+# endif
     } 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 */
@@ -189,7 +186,22 @@ struct _pthread_descr_struct
 #endif
   size_t p_alloca_cutoff;	/* Maximum size which should be allocated
 				   using alloca() instead of malloc().  */
-  /* New elements must be added at the end.  */
+  /* New elements must be added at the end before __multiple_threads.  */
+#if TLS_MULTIPLE_THREADS_IN_TCB
+  /* This field here isn't necessarily multiple_threads, which is really
+     the last integer in struct _pthread_descr_struct.  */
+  int __multiple_threads;
+# define p_multiple_threads(descr) \
+  (((union								      \
+     {									      \
+       struct _pthread_descr_struct s;					      \
+       struct								      \
+       {								      \
+	 char dummy[sizeof (struct _pthread_descr_struct) - sizeof (int)];    \
+	 int multiple_threads;						      \
+       } m;								      \
+     } *)(descr))->m.multiple_threads)
+#endif
 } __attribute__ ((aligned(32))); /* We need to align the structure so that
 				    doubles are aligned properly.  This is 8
 				    bytes on MIPS and 16 bytes on MIPS64.
diff --git a/linuxthreads/manager.c b/linuxthreads/manager.c
index 3ecf7d16f8..b4893c19f2 100644
--- a/linuxthreads/manager.c
+++ b/linuxthreads/manager.c
@@ -591,8 +591,8 @@ static int pthread_handle_create(pthread_t *thread, const pthread_attr_t *attr,
   if (new_thread == NULL)
     return EAGAIN;
 # if TLS_DTV_AT_TP
-  /* pthread_descr is right below TP.  */
-  --new_thread;
+  /* pthread_descr is below TP.  */
+  new_thread = (pthread_descr) ((char *) new_thread - TLS_PRE_TCB_SIZE);
 # endif
 #else
   /* Prevent warnings.  */
@@ -612,7 +612,7 @@ static int pthread_handle_create(pthread_t *thread, const pthread_attr_t *attr,
 	{
 #ifdef USE_TLS
 # if TLS_DTV_AT_TP
-	  ++new_thread;
+	  new_thread = (pthread_descr) ((char *) new_thread + TLS_PRE_TCB_SIZE);
 # endif
 	  _dl_deallocate_tls (new_thread, true);
 #endif
@@ -643,7 +643,7 @@ static int pthread_handle_create(pthread_t *thread, const pthread_attr_t *attr,
   new_thread->p_header.data.self = new_thread;
 #endif
 #if TLS_MULTIPLE_THREADS_IN_TCB || !defined USE_TLS || !TLS_DTV_AT_TP
-  new_thread->p_multiple_threads = 1;
+  p_multiple_threads (new_thread) = 1;
 #endif
   new_thread->p_tid = new_thread_id;
   new_thread->p_lock = &(__pthread_handles[sseg].h_lock);
@@ -806,7 +806,7 @@ static int pthread_handle_create(pthread_t *thread, const pthread_attr_t *attr,
       }
 #ifdef USE_TLS
 # if TLS_DTV_AT_TP
-    ++new_thread;
+    new_thread = (pthread_descr) ((char *) new_thread + TLS_PRE_TCB_SIZE);
 # endif
     _dl_deallocate_tls (new_thread, true);
 #endif
@@ -896,7 +896,7 @@ static void pthread_free(pthread_descr th)
 
 #ifdef USE_TLS
 # if TLS_DTV_AT_TP
-      ++th;
+      th = (pthread_descr) ((char *) th + TLS_PRE_TCB_SIZE);
 # endif
       _dl_deallocate_tls (th, true);
 #endif
diff --git a/linuxthreads/pthread.c b/linuxthreads/pthread.c
index 8b1b14fff9..38a9f7df6e 100644
--- a/linuxthreads/pthread.c
+++ b/linuxthreads/pthread.c
@@ -571,7 +571,7 @@ int __pthread_initialize_manager(void)
 
   __pthread_multiple_threads = 1;
 #if TLS_MULTIPLE_THREADS_IN_TCB || !defined USE_TLS || !TLS_DTV_AT_TP
-  __pthread_main_thread->p_multiple_threads = 1;
+  p_multiple_threads (__pthread_main_thread) = 1;
 #endif
   *__libc_multiple_threads_ptr = 1;
 
@@ -612,7 +612,7 @@ int __pthread_initialize_manager(void)
 # elif TLS_DTV_AT_TP
   /* pthread_descr is located right below tcbhead_t which _dl_allocate_tls
      returns.  */
-  mgr = (pthread_descr) tcbp - 1;
+  mgr = (pthread_descr) ((char *) tcbp - TLS_PRE_TCB_SIZE);
 # endif
   __pthread_handles[1].h_descr = manager_thread = mgr;
 
@@ -620,9 +620,9 @@ int __pthread_initialize_manager(void)
 #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;
+  p_multiple_threads (mgr) = 1;
 #elif TLS_MULTIPLE_THREADS_IN_TCB
-  mgr->p_multiple_threads = 1;
+  p_multiple_threads (mgr) = 1;
 #endif
   mgr->p_lock = &__pthread_handles[1].h_lock;
 # ifndef HAVE___THREAD
diff --git a/linuxthreads/sysdeps/ia64/tcb-offsets.sym b/linuxthreads/sysdeps/ia64/tcb-offsets.sym
index f7793f7665..c1d307dbc3 100644
--- a/linuxthreads/sysdeps/ia64/tcb-offsets.sym
+++ b/linuxthreads/sysdeps/ia64/tcb-offsets.sym
@@ -3,7 +3,7 @@
 
 --
 #ifdef USE_TLS
-MULTIPLE_THREADS_OFFSET offsetof (struct _pthread_descr_struct, p_multiple_threads) - sizeof (struct _pthread_descr_struct)
+MULTIPLE_THREADS_OFFSET -sizeof(int)
 #else
 MULTIPLE_THREADS_OFFSET offsetof (tcbhead_t, multiple_threads)
 #endif
diff --git a/linuxthreads/sysdeps/powerpc/powerpc32/tcb-offsets.sym b/linuxthreads/sysdeps/powerpc/powerpc32/tcb-offsets.sym
new file mode 100644
index 0000000000..8c6bddb456
--- /dev/null
+++ b/linuxthreads/sysdeps/powerpc/powerpc32/tcb-offsets.sym
@@ -0,0 +1,9 @@
+#include <sysdep.h>
+#include <tls.h>
+
+--
+#ifdef USE_TLS
+MULTIPLE_THREADS_OFFSET	((void *) &p_multiple_threads ((pthread_descr) ((void *) 0 - TLS_TCB_OFFSET - TLS_PRE_TCB_SIZE)) - (void *) 0)
+#else
+MULTIPLE_THREADS_OFFSET	offsetof (tcbhead_t, multiple_threads)
+#endif
diff --git a/linuxthreads/sysdeps/powerpc/tcb-offsets.sym b/linuxthreads/sysdeps/powerpc/tcb-offsets.sym
deleted file mode 100644
index bb4226fb3a..0000000000
--- a/linuxthreads/sysdeps/powerpc/tcb-offsets.sym
+++ /dev/null
@@ -1,24 +0,0 @@
-#include <sysdep.h>
-#include <tls.h>
-
---
-
--- 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
diff --git a/linuxthreads/sysdeps/powerpc/tls.h b/linuxthreads/sysdeps/powerpc/tls.h
index d946d06fae..55e915e440 100644
--- a/linuxthreads/sysdeps/powerpc/tls.h
+++ b/linuxthreads/sysdeps/powerpc/tls.h
@@ -32,8 +32,6 @@ typedef union dtv
   void *pointer;
 } dtv_t;
 
-#else /* __ASSEMBLER__ */
-# include <tcb-offsets.h>
 #endif /* __ASSEMBLER__ */
 
 #ifdef HAVE_TLS_SUPPORT
@@ -52,27 +50,29 @@ typedef struct
 } tcbhead_t;
 
 /* This is the size of the initial TCB.  */
-#  define TLS_INIT_TCB_SIZE	sizeof (tcbhead_t)
+#  define TLS_INIT_TCB_SIZE	0
 
 /* Alignment requirements for the initial TCB.  */
-#  define TLS_INIT_TCB_ALIGN	__alignof__ (tcbhead_t)
+#  define TLS_INIT_TCB_ALIGN	__alignof__ (struct _pthread_descr_struct)
 
 /* This is the size of the TCB.  */
-#  define TLS_TCB_SIZE		sizeof (tcbhead_t)
+#  define TLS_TCB_SIZE		0
 
 /* Alignment requirements for the TCB.  */
-#  define TLS_TCB_ALIGN		__alignof__ (tcbhead_t)
+#  define TLS_TCB_ALIGN		__alignof__ (struct _pthread_descr_struct)
 
 /* This is the size we need before TCB.  */
-#  define TLS_PRE_TCB_SIZE	sizeof (struct _pthread_descr_struct)
+#  define TLS_PRE_TCB_SIZE \
+  (sizeof (struct _pthread_descr_struct)				      \
+   + ((sizeof (tcbhead_t) + TLS_TCB_ALIGN - 1) & ~(TLS_TCB_ALIGN - 1)))
 
 /* The following assumes that TP (R2 or R13) is points to the end of the
    TCB + 0x7000 (per the ABI).  This implies that TCB address is
-   TP-(TLS_TCB_SIZE + 0x7000).  As we define TLS_DTV_AT_TP we can
+   TP - 0x7000.  As we define TLS_DTV_AT_TP we can
    assume that the pthread_descr is allocated immediately ahead of the
    TCB.  This implies that the pthread_descr address is
-   TP-(TLS_PRE_TCB_SIZE + TLS_TCB_SIZE + 0x7000).  */
-#  define TLS_TCB_OFFSET	0x7000
+   TP - (TLS_PRE_TCB_SIZE + 0x7000).  */
+#define TLS_TCB_OFFSET		0x7000
 
 /* The DTV is allocated at the TP; the TCB is placed elsewhere.  */
 /* This is not really true for powerpc64.  We are following alpha
@@ -82,13 +82,13 @@ typedef struct
 /* Install the dtv pointer.  The pointer passed is to the element with
    index -1 which contain the length.  */
 #  define INSTALL_DTV(TCBP, DTVP) \
-  (((tcbhead_t *) (TCBP))->dtv = (DTVP) + 1)
+  (((tcbhead_t *) (TCBP))[-1].dtv = (DTVP) + 1)
 
 /* Install new dtv for current thread.  */
 #  define INSTALL_NEW_DTV(DTV) (THREAD_DTV() = (DTV))
 
 /* Return dtv of given thread descriptor.  */
-#  define GET_DTV(TCBP)	(((tcbhead_t *) (TCBP))->dtv)
+#  define GET_DTV(TCBP)	(((tcbhead_t *) (TCBP))[-1].dtv)
 
 /* The global register variable is declared in pt-machine.h with
    the wrong type, but the compiler doesn't like us declaring another.  */
@@ -98,22 +98,22 @@ typedef struct
    special attention since 'errno' is not yet available and if the
    operation can cause a failure 'errno' must not be touched.  */
 # define TLS_INIT_TP(TCBP, SECONDCALL) \
-    (__thread_register = (void *) (TCBP) + TLS_TCB_OFFSET + TLS_TCB_SIZE, NULL)
+    (__thread_register = (void *) (TCBP) + TLS_TCB_OFFSET, NULL)
 
 /* Return the address of the dtv for the current thread.  */
 #  define THREAD_DTV() \
-     (((tcbhead_t *) (__thread_register - TLS_TCB_OFFSET - TLS_TCB_SIZE))->dtv)
+     (((tcbhead_t *) (__thread_register - TLS_TCB_OFFSET))[-1].dtv)
 
 /* Return the thread descriptor for the current thread.  */
 #  undef THREAD_SELF
 #  define THREAD_SELF \
     ((pthread_descr) (__thread_register \
-		      - TLS_TCB_OFFSET - TLS_TCB_SIZE - TLS_PRE_TCB_SIZE))
+		      - TLS_TCB_OFFSET - TLS_PRE_TCB_SIZE))
 
 #  undef INIT_THREAD_SELF
 #  define INIT_THREAD_SELF(DESCR, NR) \
      (__thread_register = ((void *) (DESCR) \
-		           + TLS_TCB_OFFSET + TLS_TCB_SIZE + TLS_PRE_TCB_SIZE))
+		           + TLS_TCB_OFFSET + TLS_PRE_TCB_SIZE))
 
 /* Make sure we have the p_multiple_threads member in the thread structure.
    See below.  */
@@ -124,6 +124,10 @@ typedef struct
 /* Get the thread descriptor definition.  */
 #  include <linuxthreads/descr.h>
 
+/* l_tls_offset == 0 is perfectly valid on PPC, so we have to use some
+   different value to mean unset l_tls_offset.  */
+#  define NO_TLS_OFFSET	-1
+
 # endif /* __ASSEMBLER__ */
 
 #elif !defined __ASSEMBLER__ && !defined __powerpc64__
diff --git a/linuxthreads/sysdeps/sh/tcb-offsets.sym b/linuxthreads/sysdeps/sh/tcb-offsets.sym
index 328eb05738..7537daa915 100644
--- a/linuxthreads/sysdeps/sh/tcb-offsets.sym
+++ b/linuxthreads/sysdeps/sh/tcb-offsets.sym
@@ -3,7 +3,7 @@
 
 --
 #ifdef USE_TLS
-MULTIPLE_THREADS_OFFSET offsetof (struct _pthread_descr_struct, p_multiple_threads)
+MULTIPLE_THREADS_OFFSET ((char *) &p_multiple_threads ((struct _pthread_descr_struct *)0) - (char *) 0)
 TLS_PRE_TCB_SIZE	sizeof (struct _pthread_descr_struct)
 #else
 MULTIPLE_THREADS_OFFSET offsetof (tcbhead_t, multiple_threads)
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/ia64/sysdep-cancel.h b/linuxthreads/sysdeps/unix/sysv/linux/ia64/sysdep-cancel.h
index af45b19356..7982d272d8 100644
--- a/linuxthreads/sysdeps/unix/sysv/linux/ia64/sysdep-cancel.h
+++ b/linuxthreads/sysdeps/unix/sysv/linux/ia64/sysdep-cancel.h
@@ -101,7 +101,7 @@ __syscall_error_##args:							      \
 
 # ifndef __ASSEMBLER__
 #  define SINGLE_THREAD_P \
-  __builtin_expect (THREAD_GETMEM (THREAD_SELF, p_multiple_threads) == 0, 1)
+  __builtin_expect (p_multiple_threads (THREAD_SELF) == 0, 1)
 # else
 #  define SINGLE_THREAD_P \
   adds r14 = MULTIPLE_THREADS_OFFSET, r13 ;; ld4 r14 = [r14] ;; cmp4.ne p6, p7 = 0, r14
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h b/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h
index 2d191d115c..fb6ca06599 100644
--- a/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h
+++ b/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h
@@ -21,6 +21,8 @@
 #include <tls.h>
 #ifndef __ASSEMBLER__
 # include <linuxthreads/internals.h>
+#else
+# include <tcb-offsets.h>
 #endif
 
 #if !defined NOT_IN_libc || defined IS_IN_libpthread
@@ -85,7 +87,7 @@
 
 # ifndef __ASSEMBLER__
 #  define SINGLE_THREAD_P						\
-  __builtin_expect (THREAD_GETMEM (THREAD_SELF, p_multiple_threads) == 0, 1)
+  __builtin_expect (p_multiple_threads (THREAD_SELF) == 0, 1)
 # else
 #  define SINGLE_THREAD_P						\
   lwz 10,MULTIPLE_THREADS_OFFSET(2);					\
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h b/linuxthreads/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h
index e6d0cca252..57cced9479 100644
--- a/linuxthreads/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h
+++ b/linuxthreads/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h
@@ -121,7 +121,7 @@
 # ifndef __ASSEMBLER__
 #  if defined FLOATING_STACKS && USE___THREAD && defined PIC
 #   define SINGLE_THREAD_P \
-  __builtin_expect (THREAD_GETMEM (THREAD_SELF, p_multiple_threads) == 0, 1)
+  __builtin_expect (p_multiple_threads (THREAD_SELF) == 0, 1)
 #  else
 extern int __local_multiple_threads attribute_hidden;
 #   define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1)