about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRoland McGrath <roland@gnu.org>2003-03-10 08:50:36 +0000
committerRoland McGrath <roland@gnu.org>2003-03-10 08:50:36 +0000
commitd4f64e1ad7d7836fbd9b01f9c5d410db930c38ce (patch)
tree9b74633f12b5a6d7d4cd277aa0b68409cb928c18
parentf9cd7dfd6b27129e677f6526b5f86fbb11030044 (diff)
downloadglibc-d4f64e1ad7d7836fbd9b01f9c5d410db930c38ce.tar.gz
glibc-d4f64e1ad7d7836fbd9b01f9c5d410db930c38ce.tar.xz
glibc-d4f64e1ad7d7836fbd9b01f9c5d410db930c38ce.zip
2003-03-10 Roland McGrath <roland@redhat.com>
	* allocatestack.c (allocate_stack) [!TLS_MULTIPLE_THREADS_IN_TCB]:
	Instead of setting PD->multiple_threads, set globals
	__pthread_multiple_threads and __libc_multiple_threads.
	* sysdeps/pthread/createthread.c (create_thread): Likewise.
	* sysdeps/i386/tls.h (TLS_MULTIPLE_THREADS_IN_TCB): Define it.
	* sysdeps/s390/tls.h (TLS_MULTIPLE_THREADS_IN_TCB): Likewise.
	* descr.h (struct pthread): Conditionalize first member on
	[!TLS_DTV_AT_TP].  Replace the `header' member with an anonymous union
	containing an anonymous tcbhead_t.  Move `list' member out.
	[TLS_MULTIPLE_THREADS_IN_TCB]: Define a `multiple_threads' member.
	* allocatestack.c: Remove use of `header.data.' prefix.
	* pthread_create.c: Likewise.
	* init.c (__pthread_initialize_minimal_internal): Likewise.
	* sysdeps/pthread/createthread.c (create_thread): Likewise.
	* sysdeps/i386/tls.h (INSTALL_DTV): Add parens.
	(THREAD_SELF, THREAD_DTV, INSTALL_NEW_DTV): No `header.data.' prefix.
	* sysdeps/x86_64/tls.h: Likewise.
	* sysdeps/unix/sysv/linux/i386/sysdep-cancel.h
	(SINGLE_THREAD_P): Likewise.
	* sysdeps/unix/sysv/linux/sh/sysdep-cancel.h
	(SINGLE_THREAD_P): Likewise.
	* sysdeps/i386/tls.h (tcbhead_t): Remove `list' member.
	* sysdeps/s390/tls.h (tcbhead_t): Likewise.
-rw-r--r--nptl/allocatestack.c44
-rw-r--r--nptl/descr.h27
-rw-r--r--nptl/init.c2
-rw-r--r--nptl/pthread_create.c10
-rw-r--r--nptl/sysdeps/i386/tls.h13
-rw-r--r--nptl/sysdeps/pthread/createthread.c15
-rw-r--r--nptl/sysdeps/s390/tls.h3
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/sysdep-cancel.h5
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h3
-rw-r--r--nptl/sysdeps/x86_64/tls.h10
10 files changed, 69 insertions, 63 deletions
diff --git a/nptl/allocatestack.c b/nptl/allocatestack.c
index 31cff2a1c2..3c9d54fc64 100644
--- a/nptl/allocatestack.c
+++ b/nptl/allocatestack.c
@@ -112,7 +112,7 @@ get_cached_stack (size_t *sizep, void **memp)
     {
       struct pthread *curr;
 
-      curr = list_entry (entry, struct pthread, header.data.list);
+      curr = list_entry (entry, struct pthread, list);
       if (FREE_P (curr) && curr->stackblock_size >= size)
 	{
 	  if (curr->stackblock_size == size)
@@ -139,10 +139,10 @@ get_cached_stack (size_t *sizep, void **memp)
     }
 
   /* Dequeue the entry.  */
-  list_del (&result->header.data.list);
+  list_del (&result->list);
 
   /* And add to the list of stacks in use.  */
-  list_add (&result->header.data.list, &stack_used);
+  list_add (&result->list, &stack_used);
 
   /* And decrease the cache size.  */
   stack_cache_actsize -= result->stackblock_size;
@@ -178,7 +178,7 @@ queue_stack (struct pthread *stack)
   /* We unconditionally add the stack to the list.  The memory may
      still be in use but it will not be reused until the kernel marks
      the stack as not used anymore.  */
-  list_add (&stack->header.data.list, &stack_cache);
+  list_add (&stack->list, &stack_cache);
 
   stack_cache_actsize += stack->stackblock_size;
   if (__builtin_expect (stack_cache_actsize > stack_cache_maxsize, 0))
@@ -193,7 +193,7 @@ queue_stack (struct pthread *stack)
 	{
 	  struct pthread *curr;
 
-	  curr = list_entry (entry, struct pthread, header.data.list);
+	  curr = list_entry (entry, struct pthread, list);
 	  if (FREE_P (curr))
 	    {
 	      /* Unlink the block.  */
@@ -277,13 +277,16 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp,
 	 stack cache nor will the memory (except the TLS memory) be freed.  */
       pd->user_stack = true;
 
+#ifdef TLS_MULTIPLE_THREADS_IN_TCB
       /* This is at least the second thread.  */
-      pd->header.data.multiple_threads = 1;
+      pd->multiple_threads = 1;
+#else
+      __pthread_multiple_threads = __libc_multiple_threads = 1;
+#endif
 
 #ifdef NEED_DL_SYSINFO
       /* Copy the sysinfo value from the parent.  */
-      pd->header.data.sysinfo
-	= THREAD_GETMEM (THREAD_SELF, header.data.sysinfo);
+      pd->sysinfo = THREAD_GETMEM (THREAD_SELF, sysinfo);
 #endif
 
       /* Allocate the DTV for this thread.  */
@@ -296,7 +299,7 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp,
       lll_lock (stack_cache_lock);
 
       /* And add to the list of stacks in use.  */
-      list_add (&pd->header.data.list, &__stack_user);
+      list_add (&pd->list, &__stack_user);
 
       lll_unlock (stack_cache_lock);
     }
@@ -384,13 +387,16 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp,
 	  pd->lock = LLL_LOCK_INITIALIZER;
 #endif
 
+#ifdef TLS_MULTIPLE_THREADS_IN_TCB
 	  /* This is at least the second thread.  */
-	  pd->header.data.multiple_threads = 1;
+	  pd->multiple_threads = 1;
+#else
+	  __pthread_multiple_threads = __libc_multiple_threads = 1;
+#endif
 
 #ifdef NEED_DL_SYSINFO
 	  /* Copy the sysinfo value from the parent.  */
-	  pd->header.data.sysinfo
-	    = THREAD_GETMEM (THREAD_SELF, header.data.sysinfo);
+	  pd->sysinfo = THREAD_GETMEM (THREAD_SELF, sysinfo);
 #endif
 
 	  /* Allocate the DTV for this thread.  */
@@ -410,7 +416,7 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp,
 	  lll_lock (stack_cache_lock);
 
 	  /* And add to the list of stacks in use.  */
-	  list_add (&pd->header.data.list, &stack_used);
+	  list_add (&pd->list, &stack_used);
 
 	  lll_unlock (stack_cache_lock);
 
@@ -435,7 +441,7 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp,
 	      lll_lock (stack_cache_lock);
 
 	      /* Remove the thread from the list.  */
-	      list_del (&pd->header.data.list);
+	      list_del (&pd->list);
 
 	      lll_unlock (stack_cache_lock);
 
@@ -492,7 +498,7 @@ __deallocate_stack (struct pthread *pd)
 
   /* Remove the thread from the list of threads with user defined
      stacks.  */
-  list_del (&pd->header.data.list);
+  list_del (&pd->list);
 
   /* Not much to do.  Just free the mmap()ed memory.  Note that we do
      not reset the 'used' flag in the 'tid' field.  This is done by
@@ -525,7 +531,7 @@ __reclaim_stacks (void)
     {
       struct pthread *curp;
 
-      curp = list_entry (runp, struct pthread, header.data.list);
+      curp = list_entry (runp, struct pthread, list);
       if (curp != self)
 	{
 	  /* This marks the stack as free.  */
@@ -542,16 +548,16 @@ __reclaim_stacks (void)
   /* Remove the entry for the current thread to from the cache list
      and add it to the list of running threads.  Which of the two
      lists is decided by the user_stack flag.  */
-  list_del (&self->header.data.list);
+  list_del (&self->list);
 
   /* Re-initialize the lists for all the threads.  */
   INIT_LIST_HEAD (&stack_used);
   INIT_LIST_HEAD (&__stack_user);
 
   if (__builtin_expect (THREAD_GETMEM (self, user_stack), 0))
-    list_add (&self->header.data.list, &__stack_user);
+    list_add (&self->list, &__stack_user);
   else
-    list_add (&self->header.data.list, &stack_used);
+    list_add (&self->list, &stack_used);
 
   /* There is one thread running.  */
   __nptl_nthreads = 1;
diff --git a/nptl/descr.h b/nptl/descr.h
index f189a6ed7b..cbaa38fc3c 100644
--- a/nptl/descr.h
+++ b/nptl/descr.h
@@ -31,6 +31,7 @@
 #include <pthreaddef.h>
 #include <dl-sysdep.h>
 #include "../nptl_db/thread_db.h"
+#include <tls.h>
 
 
 #ifndef TCB_ALIGNMENT
@@ -56,25 +57,19 @@
 /* Thread descriptor data structure.  */
 struct pthread
 {
-  /* XXX Remove this union for IA-64 style TLS module */
+#if !TLS_DTV_AT_TP
+  /* This overlaps tcbhead_t (see tls.h), as used for TLS without threads.  */
   union
   {
-    /* It is very important to always append new elements.  The offsets
-       of some of the elements of the struct are used in assembler code.  */
-    struct
-    {
-      void *tcb;                /* Pointer to the TCB.  This is not always
-                                   the address of this thread descriptor.  */
-      union dtv *dtvp;
-      struct pthread *self;       /* Pointer to this structure */
-      int multiple_threads;
-#ifdef NEED_DL_SYSINFO
-      uintptr_t sysinfo;
-#endif
-      list_t list;
-    } data;
+    tcbhead_t;
     void *__padding[16];
-  } header;
+  };
+#elif TLS_MULTIPLE_THREADS_IN_TCB
+  int multiple_threads;
+#endif
+
+  /* This descriptor's link on the `stack_used' or `__stack_user' list.  */
+  list_t list;
 
   /* Thread ID - which is also a 'is this thread descriptor (and
      therefore stack) used' flag.  */
diff --git a/nptl/init.c b/nptl/init.c
index 16926e4712..e0100ee479 100644
--- a/nptl/init.c
+++ b/nptl/init.c
@@ -194,7 +194,7 @@ __pthread_initialize_minimal_internal (void)
 
   /* Initialize the list of all running threads with the main thread.  */
   INIT_LIST_HEAD (&__stack_user);
-  list_add (&pd->header.data.list, &__stack_user);
+  list_add (&pd->list, &__stack_user);
 
 
   /* Install the cancellation signal handler.  If for some reason we
diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c
index 2ec70ea32e..c1da67db79 100644
--- a/nptl/pthread_create.c
+++ b/nptl/pthread_create.c
@@ -78,7 +78,7 @@ __find_in_stack_list (pd)
     {
       struct pthread *curp;
 
-      curp = list_entry (entry, struct pthread, header.data.list);
+      curp = list_entry (entry, struct pthread, list);
       if (curp == pd)
 	{
 	  result = curp;
@@ -91,7 +91,7 @@ __find_in_stack_list (pd)
       {
 	struct pthread *curp;
 
-	curp = list_entry (entry, struct pthread, header.data.list);
+	curp = list_entry (entry, struct pthread, list);
 	if (curp == pd)
 	  {
 	    result = curp;
@@ -345,11 +345,11 @@ __pthread_create_2_1 (newthread, attr, start_routine, arg)
      the stack freshly allocated with 'mmap'.  */
 
   /* Reference to the TCB itself.  */
-  pd->header.data.self = pd;
+  pd->self = pd;
 
 #ifdef TLS_TCB_AT_TP
-  /* Self-reference.  */
-  pd->header.data.tcb = pd;
+  /* Self-reference for TLS.  */
+  pd->tcb = pd;
 #endif
 
   /* Store the address of the start routine and the parameter.  Since
diff --git a/nptl/sysdeps/i386/tls.h b/nptl/sysdeps/i386/tls.h
index 9c4c481ccb..5b70586f27 100644
--- a/nptl/sysdeps/i386/tls.h
+++ b/nptl/sysdeps/i386/tls.h
@@ -44,9 +44,10 @@ typedef struct
   void *self;		/* Pointer to the thread descriptor.  */
   int multiple_threads;
   uintptr_t sysinfo;
-  list_t list;
 } tcbhead_t;
 
+# define TLS_MULTIPLE_THREADS_IN_TCB 1
+
 #else /* __ASSEMBLER__ */
 # include <tcb-offsets.h>
 #endif
@@ -116,12 +117,12 @@ union user_desc_init
 /* Install the dtv pointer.  The pointer passed is to the element with
    index -1 which contain the length.  */
 # define INSTALL_DTV(descr, dtvp) \
-  ((tcbhead_t *) (descr))->dtv = dtvp + 1
+  ((tcbhead_t *) (descr))->dtv = (dtvp) + 1
 
 /* Install new dtv for current thread.  */
-# define INSTALL_NEW_DTV(dtv) \
+# define INSTALL_NEW_DTV(dtvp) \
   ({ struct pthread *__pd;						      \
-     THREAD_SETMEM (__pd, header.data.dtvp, dtv); })
+     THREAD_SETMEM (__pd, dtv, (dtvp)); })
 
 /* Return dtv of given thread descriptor.  */
 # define GET_DTV(descr) \
@@ -227,7 +228,7 @@ union user_desc_init
 /* Return the address of the dtv for the current thread.  */
 # define THREAD_DTV() \
   ({ struct pthread *__pd;						      \
-     THREAD_GETMEM (__pd, header.data.dtvp); })
+     THREAD_GETMEM (__pd, dtv); })
 
 
 /* Return the thread descriptor for the current thread.
@@ -239,7 +240,7 @@ union user_desc_init
 # define THREAD_SELF \
   ({ struct pthread *__self;						      \
      asm ("movl %%gs:%c1,%0" : "=r" (__self)				      \
-	  : "i" (offsetof (struct pthread, header.data.self))); 	      \
+	  : "i" (offsetof (struct pthread, self))); 			      \
      __self;})
 
 
diff --git a/nptl/sysdeps/pthread/createthread.c b/nptl/sysdeps/pthread/createthread.c
index beee434c62..2fac2d1a4e 100644
--- a/nptl/sysdeps/pthread/createthread.c
+++ b/nptl/sysdeps/pthread/createthread.c
@@ -42,7 +42,7 @@ create_thread (struct pthread *pd, STACK_VARIABLES_PARMS)
   PREPARE_CREATE;
 #endif
 
-  assert (pd->header.data.tcb != NULL);
+  assert (pd->tcb != NULL);
 
 
   if (__builtin_expect (THREAD_GETMEM (THREAD_SELF, report_events), 0))
@@ -70,8 +70,12 @@ create_thread (struct pthread *pd, STACK_VARIABLES_PARMS)
 	    /* Failed.  */
 	    return errno;
 
+#ifdef TLS_MULTIPLE_THREADS_IN_TCB
 	  /* We now have for sure more than one thread.  */
-	  pd->header.data.multiple_threads = 1;
+	  pd->multiple_threads = 1;
+#else
+	  __pthread_multiple_threads = __libc_multiple_threads = 1;
+#endif
 
 	  /* Now fill in the information about the new thread in
 	     the newly created thread's data structure.  We cannot let
@@ -97,8 +101,7 @@ create_thread (struct pthread *pd, STACK_VARIABLES_PARMS)
     }
 
 #ifdef NEED_DL_SYSINFO
-  assert (THREAD_GETMEM (THREAD_SELF, header.data.sysinfo)
-	  == pd->header.data.sysinfo);
+  assert (THREAD_GETMEM (THREAD_SELF, sysinfo) == pd->sysinfo);
 #endif
 
   /* We rely heavily on various flags the CLONE function understands:
@@ -139,8 +142,10 @@ create_thread (struct pthread *pd, STACK_VARIABLES_PARMS)
     /* Failed.  */
     return errno;
 
+#ifdef TLS_MULTIPLE_THREADS_IN_TCB
   /* We now have for sure more than one thread.  */
-  THREAD_SETMEM (THREAD_SELF, header.data.multiple_threads, 1);
+  THREAD_SETMEM (THREAD_SELF, multiple_threads, 1);
+#endif
 
   return 0;
 }
diff --git a/nptl/sysdeps/s390/tls.h b/nptl/sysdeps/s390/tls.h
index 9b186f657f..4151f7fded 100644
--- a/nptl/sysdeps/s390/tls.h
+++ b/nptl/sysdeps/s390/tls.h
@@ -46,9 +46,10 @@ typedef struct
 #ifdef NEED_DL_SYSINFO
   uintptr_t sysinfo;
 #endif
-  list_t list;
 } tcbhead_t;
 
+# define TLS_MULTIPLE_THREADS_IN_TCB 1
+
 #else /* __ASSEMBLER__ */
 # include <tcb-offsets.h>
 #endif
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/sysdep-cancel.h b/nptl/sysdeps/unix/sysv/linux/i386/sysdep-cancel.h
index d9b51a4da5..6abb59a144 100644
--- a/nptl/sysdeps/unix/sysv/linux/i386/sysdep-cancel.h
+++ b/nptl/sysdeps/unix/sysv/linux/i386/sysdep-cancel.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Jakub Jelinek <jakub@redhat.com>, 2002.
 
@@ -78,8 +78,7 @@
 
 # ifndef __ASSEMBLER__
 #  define SINGLE_THREAD_P \
-  __builtin_expect (THREAD_GETMEM (THREAD_SELF,				      \
-				   header.data.multiple_threads) == 0, 1)
+  __builtin_expect (THREAD_GETMEM (THREAD_SELF, multiple_threads) == 0, 1)
 # else
 #  define SINGLE_THREAD_P cmpl $0, %gs:MULTIPLE_THREADS_OFFSET
 # endif
diff --git a/nptl/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h b/nptl/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h
index 07bac6d35d..27147476e2 100644
--- a/nptl/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h
+++ b/nptl/sysdeps/unix/sysv/linux/sh/sysdep-cancel.h
@@ -117,8 +117,7 @@
 
 # ifndef __ASSEMBLER__
 #  define SINGLE_THREAD_P \
-  __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
-				   header.data.multiple_threads) == 0, 1)
+  __builtin_expect (THREAD_GETMEM (THREAD_SELF, multiple_threads) == 0, 1)
 # else
 #  define SINGLE_THREAD_P \
 	stc gbr,r0; \
diff --git a/nptl/sysdeps/x86_64/tls.h b/nptl/sysdeps/x86_64/tls.h
index 66e878ef0b..ae1c66e373 100644
--- a/nptl/sysdeps/x86_64/tls.h
+++ b/nptl/sysdeps/x86_64/tls.h
@@ -84,12 +84,12 @@ typedef struct
 /* Install the dtv pointer.  The pointer passed is to the element with
    index -1 which contain the length.  */
 # define INSTALL_DTV(descr, dtvp) \
-  ((tcbhead_t *) (descr))->dtv = dtvp + 1
+  ((tcbhead_t *) (descr))->dtv = (dtvp) + 1
 
 /* Install new dtv for current thread.  */
-# define INSTALL_NEW_DTV(dtv) \
+# define INSTALL_NEW_DTV(dtvp) \
   ({ struct pthread *__pd;						      \
-     THREAD_SETMEM (__pd, header.data.dtvp, dtv); })
+     THREAD_SETMEM (__pd, dtv, (dtvp)); })
 
 /* Return dtv of given thread descriptor.  */
 # define GET_DTV(descr) \
@@ -133,7 +133,7 @@ typedef struct
 /* Return the address of the dtv for the current thread.  */
 # define THREAD_DTV() \
   ({ struct pthread *__pd;						      \
-     THREAD_GETMEM (__pd, header.data.dtvp); })
+     THREAD_GETMEM (__pd, dtv); })
 
 
 /* Return the thread descriptor for the current thread.
@@ -145,7 +145,7 @@ typedef struct
 # define THREAD_SELF \
   ({ struct pthread *__self;						      \
      asm ("movq %%fs:%c1,%0" : "=r" (__self)				      \
-	  : "i" (offsetof (struct pthread, header.data.self))); 	      \
+	  : "i" (offsetof (struct pthread, self)));		 	      \
      __self;})