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:
Roland McGrath 2003-03-10 08:50:36 +00:00
parent f9cd7dfd6b
commit d4f64e1ad7
10 changed files with 69 additions and 63 deletions

View File

@ -112,7 +112,7 @@ get_cached_stack (size_t *sizep, void **memp)
{ {
struct pthread *curr; 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 (FREE_P (curr) && curr->stackblock_size >= size)
{ {
if (curr->stackblock_size == size) if (curr->stackblock_size == size)
@ -139,10 +139,10 @@ get_cached_stack (size_t *sizep, void **memp)
} }
/* Dequeue the entry. */ /* Dequeue the entry. */
list_del (&result->header.data.list); list_del (&result->list);
/* And add to the list of stacks in use. */ /* 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. */ /* And decrease the cache size. */
stack_cache_actsize -= result->stackblock_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 /* 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 still be in use but it will not be reused until the kernel marks
the stack as not used anymore. */ 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; stack_cache_actsize += stack->stackblock_size;
if (__builtin_expect (stack_cache_actsize > stack_cache_maxsize, 0)) if (__builtin_expect (stack_cache_actsize > stack_cache_maxsize, 0))
@ -193,7 +193,7 @@ queue_stack (struct pthread *stack)
{ {
struct pthread *curr; struct pthread *curr;
curr = list_entry (entry, struct pthread, header.data.list); curr = list_entry (entry, struct pthread, list);
if (FREE_P (curr)) if (FREE_P (curr))
{ {
/* Unlink the block. */ /* 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. */ stack cache nor will the memory (except the TLS memory) be freed. */
pd->user_stack = true; pd->user_stack = true;
#ifdef TLS_MULTIPLE_THREADS_IN_TCB
/* This is at least the second thread. */ /* 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 #ifdef NEED_DL_SYSINFO
/* Copy the sysinfo value from the parent. */ /* Copy the sysinfo value from the parent. */
pd->header.data.sysinfo pd->sysinfo = THREAD_GETMEM (THREAD_SELF, sysinfo);
= THREAD_GETMEM (THREAD_SELF, header.data.sysinfo);
#endif #endif
/* Allocate the DTV for this thread. */ /* 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); lll_lock (stack_cache_lock);
/* And add to the list of stacks in use. */ /* 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); lll_unlock (stack_cache_lock);
} }
@ -384,13 +387,16 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp,
pd->lock = LLL_LOCK_INITIALIZER; pd->lock = LLL_LOCK_INITIALIZER;
#endif #endif
#ifdef TLS_MULTIPLE_THREADS_IN_TCB
/* This is at least the second thread. */ /* 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 #ifdef NEED_DL_SYSINFO
/* Copy the sysinfo value from the parent. */ /* Copy the sysinfo value from the parent. */
pd->header.data.sysinfo pd->sysinfo = THREAD_GETMEM (THREAD_SELF, sysinfo);
= THREAD_GETMEM (THREAD_SELF, header.data.sysinfo);
#endif #endif
/* Allocate the DTV for this thread. */ /* 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); lll_lock (stack_cache_lock);
/* And add to the list of stacks in use. */ /* 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); lll_unlock (stack_cache_lock);
@ -435,7 +441,7 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp,
lll_lock (stack_cache_lock); lll_lock (stack_cache_lock);
/* Remove the thread from the list. */ /* Remove the thread from the list. */
list_del (&pd->header.data.list); list_del (&pd->list);
lll_unlock (stack_cache_lock); 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 /* Remove the thread from the list of threads with user defined
stacks. */ 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 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 not reset the 'used' flag in the 'tid' field. This is done by
@ -525,7 +531,7 @@ __reclaim_stacks (void)
{ {
struct pthread *curp; struct pthread *curp;
curp = list_entry (runp, struct pthread, header.data.list); curp = list_entry (runp, struct pthread, list);
if (curp != self) if (curp != self)
{ {
/* This marks the stack as free. */ /* 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 /* 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 and add it to the list of running threads. Which of the two
lists is decided by the user_stack flag. */ 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. */ /* Re-initialize the lists for all the threads. */
INIT_LIST_HEAD (&stack_used); INIT_LIST_HEAD (&stack_used);
INIT_LIST_HEAD (&__stack_user); INIT_LIST_HEAD (&__stack_user);
if (__builtin_expect (THREAD_GETMEM (self, user_stack), 0)) if (__builtin_expect (THREAD_GETMEM (self, user_stack), 0))
list_add (&self->header.data.list, &__stack_user); list_add (&self->list, &__stack_user);
else else
list_add (&self->header.data.list, &stack_used); list_add (&self->list, &stack_used);
/* There is one thread running. */ /* There is one thread running. */
__nptl_nthreads = 1; __nptl_nthreads = 1;

View File

@ -31,6 +31,7 @@
#include <pthreaddef.h> #include <pthreaddef.h>
#include <dl-sysdep.h> #include <dl-sysdep.h>
#include "../nptl_db/thread_db.h" #include "../nptl_db/thread_db.h"
#include <tls.h>
#ifndef TCB_ALIGNMENT #ifndef TCB_ALIGNMENT
@ -56,25 +57,19 @@
/* Thread descriptor data structure. */ /* Thread descriptor data structure. */
struct pthread 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 union
{ {
/* It is very important to always append new elements. The offsets tcbhead_t;
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;
void *__padding[16]; 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 /* Thread ID - which is also a 'is this thread descriptor (and
therefore stack) used' flag. */ therefore stack) used' flag. */

View File

@ -194,7 +194,7 @@ __pthread_initialize_minimal_internal (void)
/* Initialize the list of all running threads with the main thread. */ /* Initialize the list of all running threads with the main thread. */
INIT_LIST_HEAD (&__stack_user); 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 /* Install the cancellation signal handler. If for some reason we

View File

@ -78,7 +78,7 @@ __find_in_stack_list (pd)
{ {
struct pthread *curp; struct pthread *curp;
curp = list_entry (entry, struct pthread, header.data.list); curp = list_entry (entry, struct pthread, list);
if (curp == pd) if (curp == pd)
{ {
result = curp; result = curp;
@ -91,7 +91,7 @@ __find_in_stack_list (pd)
{ {
struct pthread *curp; struct pthread *curp;
curp = list_entry (entry, struct pthread, header.data.list); curp = list_entry (entry, struct pthread, list);
if (curp == pd) if (curp == pd)
{ {
result = curp; result = curp;
@ -345,11 +345,11 @@ __pthread_create_2_1 (newthread, attr, start_routine, arg)
the stack freshly allocated with 'mmap'. */ the stack freshly allocated with 'mmap'. */
/* Reference to the TCB itself. */ /* Reference to the TCB itself. */
pd->header.data.self = pd; pd->self = pd;
#ifdef TLS_TCB_AT_TP #ifdef TLS_TCB_AT_TP
/* Self-reference. */ /* Self-reference for TLS. */
pd->header.data.tcb = pd; pd->tcb = pd;
#endif #endif
/* Store the address of the start routine and the parameter. Since /* Store the address of the start routine and the parameter. Since

View File

@ -44,9 +44,10 @@ typedef struct
void *self; /* Pointer to the thread descriptor. */ void *self; /* Pointer to the thread descriptor. */
int multiple_threads; int multiple_threads;
uintptr_t sysinfo; uintptr_t sysinfo;
list_t list;
} tcbhead_t; } tcbhead_t;
# define TLS_MULTIPLE_THREADS_IN_TCB 1
#else /* __ASSEMBLER__ */ #else /* __ASSEMBLER__ */
# include <tcb-offsets.h> # include <tcb-offsets.h>
#endif #endif
@ -116,12 +117,12 @@ union user_desc_init
/* Install the dtv pointer. The pointer passed is to the element with /* Install the dtv pointer. The pointer passed is to the element with
index -1 which contain the length. */ index -1 which contain the length. */
# define INSTALL_DTV(descr, dtvp) \ # define INSTALL_DTV(descr, dtvp) \
((tcbhead_t *) (descr))->dtv = dtvp + 1 ((tcbhead_t *) (descr))->dtv = (dtvp) + 1
/* Install new dtv for current thread. */ /* Install new dtv for current thread. */
# define INSTALL_NEW_DTV(dtv) \ # define INSTALL_NEW_DTV(dtvp) \
({ struct pthread *__pd; \ ({ struct pthread *__pd; \
THREAD_SETMEM (__pd, header.data.dtvp, dtv); }) THREAD_SETMEM (__pd, dtv, (dtvp)); })
/* Return dtv of given thread descriptor. */ /* Return dtv of given thread descriptor. */
# define GET_DTV(descr) \ # define GET_DTV(descr) \
@ -227,7 +228,7 @@ union user_desc_init
/* Return the address of the dtv for the current thread. */ /* Return the address of the dtv for the current thread. */
# define THREAD_DTV() \ # define THREAD_DTV() \
({ struct pthread *__pd; \ ({ struct pthread *__pd; \
THREAD_GETMEM (__pd, header.data.dtvp); }) THREAD_GETMEM (__pd, dtv); })
/* Return the thread descriptor for the current thread. /* Return the thread descriptor for the current thread.
@ -239,7 +240,7 @@ union user_desc_init
# define THREAD_SELF \ # define THREAD_SELF \
({ struct pthread *__self; \ ({ struct pthread *__self; \
asm ("movl %%gs:%c1,%0" : "=r" (__self) \ asm ("movl %%gs:%c1,%0" : "=r" (__self) \
: "i" (offsetof (struct pthread, header.data.self))); \ : "i" (offsetof (struct pthread, self))); \
__self;}) __self;})

View File

@ -42,7 +42,7 @@ create_thread (struct pthread *pd, STACK_VARIABLES_PARMS)
PREPARE_CREATE; PREPARE_CREATE;
#endif #endif
assert (pd->header.data.tcb != NULL); assert (pd->tcb != NULL);
if (__builtin_expect (THREAD_GETMEM (THREAD_SELF, report_events), 0)) if (__builtin_expect (THREAD_GETMEM (THREAD_SELF, report_events), 0))
@ -70,8 +70,12 @@ create_thread (struct pthread *pd, STACK_VARIABLES_PARMS)
/* Failed. */ /* Failed. */
return errno; return errno;
#ifdef TLS_MULTIPLE_THREADS_IN_TCB
/* We now have for sure more than one thread. */ /* 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 /* Now fill in the information about the new thread in
the newly created thread's data structure. We cannot let 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 #ifdef NEED_DL_SYSINFO
assert (THREAD_GETMEM (THREAD_SELF, header.data.sysinfo) assert (THREAD_GETMEM (THREAD_SELF, sysinfo) == pd->sysinfo);
== pd->header.data.sysinfo);
#endif #endif
/* We rely heavily on various flags the CLONE function understands: /* We rely heavily on various flags the CLONE function understands:
@ -139,8 +142,10 @@ create_thread (struct pthread *pd, STACK_VARIABLES_PARMS)
/* Failed. */ /* Failed. */
return errno; return errno;
#ifdef TLS_MULTIPLE_THREADS_IN_TCB
/* We now have for sure more than one thread. */ /* 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; return 0;
} }

View File

@ -46,9 +46,10 @@ typedef struct
#ifdef NEED_DL_SYSINFO #ifdef NEED_DL_SYSINFO
uintptr_t sysinfo; uintptr_t sysinfo;
#endif #endif
list_t list;
} tcbhead_t; } tcbhead_t;
# define TLS_MULTIPLE_THREADS_IN_TCB 1
#else /* __ASSEMBLER__ */ #else /* __ASSEMBLER__ */
# include <tcb-offsets.h> # include <tcb-offsets.h>
#endif #endif

View File

@ -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. This file is part of the GNU C Library.
Contributed by Jakub Jelinek <jakub@redhat.com>, 2002. Contributed by Jakub Jelinek <jakub@redhat.com>, 2002.
@ -78,8 +78,7 @@
# ifndef __ASSEMBLER__ # ifndef __ASSEMBLER__
# define SINGLE_THREAD_P \ # define SINGLE_THREAD_P \
__builtin_expect (THREAD_GETMEM (THREAD_SELF, \ __builtin_expect (THREAD_GETMEM (THREAD_SELF, multiple_threads) == 0, 1)
header.data.multiple_threads) == 0, 1)
# else # else
# define SINGLE_THREAD_P cmpl $0, %gs:MULTIPLE_THREADS_OFFSET # define SINGLE_THREAD_P cmpl $0, %gs:MULTIPLE_THREADS_OFFSET
# endif # endif

View File

@ -117,8 +117,7 @@
# ifndef __ASSEMBLER__ # ifndef __ASSEMBLER__
# define SINGLE_THREAD_P \ # define SINGLE_THREAD_P \
__builtin_expect (THREAD_GETMEM (THREAD_SELF, \ __builtin_expect (THREAD_GETMEM (THREAD_SELF, multiple_threads) == 0, 1)
header.data.multiple_threads) == 0, 1)
# else # else
# define SINGLE_THREAD_P \ # define SINGLE_THREAD_P \
stc gbr,r0; \ stc gbr,r0; \

View File

@ -84,12 +84,12 @@ typedef struct
/* Install the dtv pointer. The pointer passed is to the element with /* Install the dtv pointer. The pointer passed is to the element with
index -1 which contain the length. */ index -1 which contain the length. */
# define INSTALL_DTV(descr, dtvp) \ # define INSTALL_DTV(descr, dtvp) \
((tcbhead_t *) (descr))->dtv = dtvp + 1 ((tcbhead_t *) (descr))->dtv = (dtvp) + 1
/* Install new dtv for current thread. */ /* Install new dtv for current thread. */
# define INSTALL_NEW_DTV(dtv) \ # define INSTALL_NEW_DTV(dtvp) \
({ struct pthread *__pd; \ ({ struct pthread *__pd; \
THREAD_SETMEM (__pd, header.data.dtvp, dtv); }) THREAD_SETMEM (__pd, dtv, (dtvp)); })
/* Return dtv of given thread descriptor. */ /* Return dtv of given thread descriptor. */
# define GET_DTV(descr) \ # define GET_DTV(descr) \
@ -133,7 +133,7 @@ typedef struct
/* Return the address of the dtv for the current thread. */ /* Return the address of the dtv for the current thread. */
# define THREAD_DTV() \ # define THREAD_DTV() \
({ struct pthread *__pd; \ ({ struct pthread *__pd; \
THREAD_GETMEM (__pd, header.data.dtvp); }) THREAD_GETMEM (__pd, dtv); })
/* Return the thread descriptor for the current thread. /* Return the thread descriptor for the current thread.
@ -145,7 +145,7 @@ typedef struct
# define THREAD_SELF \ # define THREAD_SELF \
({ struct pthread *__self; \ ({ struct pthread *__self; \
asm ("movq %%fs:%c1,%0" : "=r" (__self) \ asm ("movq %%fs:%c1,%0" : "=r" (__self) \
: "i" (offsetof (struct pthread, header.data.self))); \ : "i" (offsetof (struct pthread, self))); \
__self;}) __self;})