mirror of git://sourceware.org/git/glibc.git
				
				
				
			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.
This commit is contained in:
		
							parent
							
								
									f9cd7dfd6b
								
							
						
					
					
						commit
						d4f64e1ad7
					
				|  | @ -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; | ||||
|  |  | |||
							
								
								
									
										27
									
								
								nptl/descr.h
								
								
								
								
							
							
						
						
									
										27
									
								
								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.  */ | ||||
|  |  | |||
|  | @ -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
 | ||||
|  |  | |||
|  | @ -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
 | ||||
|  |  | |||
|  | @ -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;}) | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -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; | ||||
| } | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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; \ | ||||
|  |  | |||
|  | @ -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;}) | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue