mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-22 13:00:06 +00:00
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
Block a user