1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-07-28 00:21:52 +03:00
2003-04-22  Jakub Jelinek  <jakub@redhat.com>

	* include/link.h (NO_TLS_OFFSET): Define to 0 if not defined.
	* elf/dl-close.c (_dl_close): Use NO_TLS_OFFSET.
	* elf/dl-object.c (_dl_new_object): Initialize l_tls_offset to
	NO_TLS_OFFSET.
	* elf/rtld.c (_dl_start_final, _dl_start): Likewise.
	* elf/dl-reloc.c (CHECK_STATIC_TLS): Use NO_TLS_OFFSET.
	* sysdeps/generic/dl-tls.c (_dl_allocate_tls_init): Likewise.
	* sysdeps/powerpc/dl-tls.h (TLS_TPREL_VALUE): Don't subtract
	TLS_TCB_SIZE.
This commit is contained in:
Ulrich Drepper
2003-04-25 09:12:43 +00:00
parent 29bfc9453e
commit 299601a1ef
33 changed files with 225 additions and 113 deletions

View File

@ -1,3 +1,15 @@
2003-04-22 Jakub Jelinek <jakub@redhat.com>
* include/link.h (NO_TLS_OFFSET): Define to 0 if not defined.
* elf/dl-close.c (_dl_close): Use NO_TLS_OFFSET.
* elf/dl-object.c (_dl_new_object): Initialize l_tls_offset to
NO_TLS_OFFSET.
* elf/rtld.c (_dl_start_final, _dl_start): Likewise.
* elf/dl-reloc.c (CHECK_STATIC_TLS): Use NO_TLS_OFFSET.
* sysdeps/generic/dl-tls.c (_dl_allocate_tls_init): Likewise.
* sysdeps/powerpc/dl-tls.h (TLS_TPREL_VALUE): Don't subtract
TLS_TCB_SIZE.
2003-04-24 Ulrich Drepper <drepper@redhat.com> 2003-04-24 Ulrich Drepper <drepper@redhat.com>
* nss/getent.c: Implement alternative host database lookup via * nss/getent.c: Implement alternative host database lookup via

View File

@ -365,7 +365,7 @@ _dl_close (void *_map)
/* All dynamically loaded modules with TLS are unloaded. */ /* All dynamically loaded modules with TLS are unloaded. */
GL(dl_tls_max_dtv_idx) = GL(dl_tls_static_nelem); GL(dl_tls_max_dtv_idx) = GL(dl_tls_static_nelem);
if (imap->l_tls_offset != 0) if (imap->l_tls_offset != NO_TLS_OFFSET)
{ {
/* Collect a contiguous chunk built from the objects in /* Collect a contiguous chunk built from the objects in
this search list, going in either direction. When the this search list, going in either direction. When the

View File

@ -53,6 +53,10 @@ _dl_new_object (char *realname, const char *libname, int type,
new->l_name = realname; new->l_name = realname;
new->l_type = type; new->l_type = type;
new->l_loader = loader; new->l_loader = loader;
#if defined USE_TLS && NO_TLS_OFFSET != 0
new->l_tls_offset = NO_TLS_OFFSET;
#endif
/* new->l_global = 0; We use calloc therefore not necessary. */ /* new->l_global = 0; We use calloc therefore not necessary. */
/* Use the 'l_scope_mem' array by default for the the 'l_scope' /* Use the 'l_scope_mem' array by default for the the 'l_scope'

View File

@ -209,7 +209,7 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
intended to produce. */ intended to produce. */
#define CHECK_STATIC_TLS(map, sym_map) \ #define CHECK_STATIC_TLS(map, sym_map) \
do { \ do { \
if (__builtin_expect ((sym_map)->l_tls_offset == 0, 0)) \ if (__builtin_expect ((sym_map)->l_tls_offset == NO_TLS_OFFSET, 0)) \
_dl_allocate_static_tls (sym_map); \ _dl_allocate_static_tls (sym_map); \
} while (0) } while (0)

View File

@ -233,6 +233,9 @@ _dl_start_final (void *arg, struct dl_start_final_info *info)
GL(dl_rtld_map).l_tls_modid = 1; GL(dl_rtld_map).l_tls_modid = 1;
# else # else
assert (info->l.l_tls_modid == 0); assert (info->l.l_tls_modid == 0);
# if NO_TLS_OFFSET != 0
GL(dl_rtld_map).l_tls_offset = NO_TLS_OFFSET;
# endif
# endif # endif
#endif #endif
@ -316,6 +319,10 @@ _dl_start (void *arg)
bootstrap_map.l_ld = (void *) bootstrap_map.l_addr + elf_machine_dynamic (); bootstrap_map.l_ld = (void *) bootstrap_map.l_addr + elf_machine_dynamic ();
elf_get_dynamic_info (&bootstrap_map); elf_get_dynamic_info (&bootstrap_map);
#if defined USE_TLS && NO_TLS_OFFSET != 0
bootstrap_map.l_tls_offset = NO_TLS_OFFSET;
#endif
#if USE___THREAD #if USE___THREAD
/* Get the dynamic linker's own program header. First we need the ELF /* Get the dynamic linker's own program header. First we need the ELF
file header. The `_begin' symbol created by the linker script points file header. The `_begin' symbol created by the linker script points

View File

@ -268,6 +268,9 @@ struct link_map
size_t l_tls_blocksize; size_t l_tls_blocksize;
/* Alignment requirement of the TLS block. */ /* Alignment requirement of the TLS block. */
size_t l_tls_align; size_t l_tls_align;
# ifndef NO_TLS_OFFSET
# define NO_TLS_OFFSET 0
# endif
/* For objects present at startup time: offset in the static TLS block. */ /* For objects present at startup time: offset in the static TLS block. */
ptrdiff_t l_tls_offset; ptrdiff_t l_tls_offset;
/* Index of the module in the dtv array. */ /* Index of the module in the dtv array. */

View File

@ -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> 2003-04-22 Roland McGrath <roland@redhat.com>
* Makeconfig (shared-thread-library): Reverse link order to work * Makeconfig (shared-thread-library): Reverse link order to work

View File

@ -120,17 +120,14 @@ struct _pthread_descr_struct
union dtv *dtvp; union dtv *dtvp;
pthread_descr self; /* Pointer to this structure */ pthread_descr self; /* Pointer to this structure */
int multiple_threads; 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; uintptr_t sysinfo;
#endif # endif
} data; } data;
void *__padding[16]; void *__padding[16];
} p_header; } p_header;
# define p_multiple_threads p_header.data.multiple_threads
#elif TLS_MULTIPLE_THREADS_IN_TCB
int p_multiple_threads;
#endif #endif
pthread_descr p_nextlive, p_prevlive; pthread_descr p_nextlive, p_prevlive;
/* Double chaining of active threads */ /* Double chaining of active threads */
pthread_descr p_nextwaiting; /* Next element in the queue holding the thr */ pthread_descr p_nextwaiting; /* Next element in the queue holding the thr */
@ -189,7 +186,22 @@ struct _pthread_descr_struct
#endif #endif
size_t p_alloca_cutoff; /* Maximum size which should be allocated size_t p_alloca_cutoff; /* Maximum size which should be allocated
using alloca() instead of malloc(). */ 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 } __attribute__ ((aligned(32))); /* We need to align the structure so that
doubles are aligned properly. This is 8 doubles are aligned properly. This is 8
bytes on MIPS and 16 bytes on MIPS64. bytes on MIPS and 16 bytes on MIPS64.

View File

@ -591,8 +591,8 @@ static int pthread_handle_create(pthread_t *thread, const pthread_attr_t *attr,
if (new_thread == NULL) if (new_thread == NULL)
return EAGAIN; return EAGAIN;
# if TLS_DTV_AT_TP # if TLS_DTV_AT_TP
/* pthread_descr is right below TP. */ /* pthread_descr is below TP. */
--new_thread; new_thread = (pthread_descr) ((char *) new_thread - TLS_PRE_TCB_SIZE);
# endif # endif
#else #else
/* Prevent warnings. */ /* Prevent warnings. */
@ -612,7 +612,7 @@ static int pthread_handle_create(pthread_t *thread, const pthread_attr_t *attr,
{ {
#ifdef USE_TLS #ifdef USE_TLS
# if TLS_DTV_AT_TP # if TLS_DTV_AT_TP
++new_thread; new_thread = (pthread_descr) ((char *) new_thread + TLS_PRE_TCB_SIZE);
# endif # endif
_dl_deallocate_tls (new_thread, true); _dl_deallocate_tls (new_thread, true);
#endif #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; new_thread->p_header.data.self = new_thread;
#endif #endif
#if TLS_MULTIPLE_THREADS_IN_TCB || !defined USE_TLS || !TLS_DTV_AT_TP #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 #endif
new_thread->p_tid = new_thread_id; new_thread->p_tid = new_thread_id;
new_thread->p_lock = &(__pthread_handles[sseg].h_lock); 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 #ifdef USE_TLS
# if TLS_DTV_AT_TP # if TLS_DTV_AT_TP
++new_thread; new_thread = (pthread_descr) ((char *) new_thread + TLS_PRE_TCB_SIZE);
# endif # endif
_dl_deallocate_tls (new_thread, true); _dl_deallocate_tls (new_thread, true);
#endif #endif
@ -896,7 +896,7 @@ static void pthread_free(pthread_descr th)
#ifdef USE_TLS #ifdef USE_TLS
# if TLS_DTV_AT_TP # if TLS_DTV_AT_TP
++th; th = (pthread_descr) ((char *) th + TLS_PRE_TCB_SIZE);
# endif # endif
_dl_deallocate_tls (th, true); _dl_deallocate_tls (th, true);
#endif #endif

View File

@ -571,7 +571,7 @@ int __pthread_initialize_manager(void)
__pthread_multiple_threads = 1; __pthread_multiple_threads = 1;
#if TLS_MULTIPLE_THREADS_IN_TCB || !defined USE_TLS || !TLS_DTV_AT_TP #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 #endif
*__libc_multiple_threads_ptr = 1; *__libc_multiple_threads_ptr = 1;
@ -612,7 +612,7 @@ int __pthread_initialize_manager(void)
# elif TLS_DTV_AT_TP # elif TLS_DTV_AT_TP
/* pthread_descr is located right below tcbhead_t which _dl_allocate_tls /* pthread_descr is located right below tcbhead_t which _dl_allocate_tls
returns. */ returns. */
mgr = (pthread_descr) tcbp - 1; mgr = (pthread_descr) ((char *) tcbp - TLS_PRE_TCB_SIZE);
# endif # endif
__pthread_handles[1].h_descr = manager_thread = mgr; __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 #if !defined USE_TLS || !TLS_DTV_AT_TP
mgr->p_header.data.tcb = tcbp; mgr->p_header.data.tcb = tcbp;
mgr->p_header.data.self = mgr; mgr->p_header.data.self = mgr;
mgr->p_header.data.multiple_threads = 1; p_multiple_threads (mgr) = 1;
#elif TLS_MULTIPLE_THREADS_IN_TCB #elif TLS_MULTIPLE_THREADS_IN_TCB
mgr->p_multiple_threads = 1; p_multiple_threads (mgr) = 1;
#endif #endif
mgr->p_lock = &__pthread_handles[1].h_lock; mgr->p_lock = &__pthread_handles[1].h_lock;
# ifndef HAVE___THREAD # ifndef HAVE___THREAD

View File

@ -3,7 +3,7 @@
-- --
#ifdef USE_TLS #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 #else
MULTIPLE_THREADS_OFFSET offsetof (tcbhead_t, multiple_threads) MULTIPLE_THREADS_OFFSET offsetof (tcbhead_t, multiple_threads)
#endif #endif

View File

@ -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

View File

@ -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

View File

@ -32,8 +32,6 @@ typedef union dtv
void *pointer; void *pointer;
} dtv_t; } dtv_t;
#else /* __ASSEMBLER__ */
# include <tcb-offsets.h>
#endif /* __ASSEMBLER__ */ #endif /* __ASSEMBLER__ */
#ifdef HAVE_TLS_SUPPORT #ifdef HAVE_TLS_SUPPORT
@ -52,27 +50,29 @@ typedef struct
} tcbhead_t; } tcbhead_t;
/* This is the size of the initial TCB. */ /* 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. */ /* 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. */ /* This is the size of the TCB. */
# define TLS_TCB_SIZE sizeof (tcbhead_t) # define TLS_TCB_SIZE 0
/* Alignment requirements for the TCB. */ /* 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. */ /* 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 /* 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 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 assume that the pthread_descr is allocated immediately ahead of the
TCB. This implies that the pthread_descr address is TCB. This implies that the pthread_descr address is
TP-(TLS_PRE_TCB_SIZE + TLS_TCB_SIZE + 0x7000). */ TP - (TLS_PRE_TCB_SIZE + 0x7000). */
# define TLS_TCB_OFFSET 0x7000 #define TLS_TCB_OFFSET 0x7000
/* The DTV is allocated at the TP; the TCB is placed elsewhere. */ /* The DTV is allocated at the TP; the TCB is placed elsewhere. */
/* This is not really true for powerpc64. We are following alpha /* 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 /* 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(TCBP, DTVP) \ # define INSTALL_DTV(TCBP, DTVP) \
(((tcbhead_t *) (TCBP))->dtv = (DTVP) + 1) (((tcbhead_t *) (TCBP))[-1].dtv = (DTVP) + 1)
/* Install new dtv for current thread. */ /* Install new dtv for current thread. */
# define INSTALL_NEW_DTV(DTV) (THREAD_DTV() = (DTV)) # define INSTALL_NEW_DTV(DTV) (THREAD_DTV() = (DTV))
/* Return dtv of given thread descriptor. */ /* 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 global register variable is declared in pt-machine.h with
the wrong type, but the compiler doesn't like us declaring another. */ 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 special attention since 'errno' is not yet available and if the
operation can cause a failure 'errno' must not be touched. */ operation can cause a failure 'errno' must not be touched. */
# define TLS_INIT_TP(TCBP, SECONDCALL) \ # 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. */ /* Return the address of the dtv for the current thread. */
# define THREAD_DTV() \ # 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. */ /* Return the thread descriptor for the current thread. */
# undef THREAD_SELF # undef THREAD_SELF
# define THREAD_SELF \ # define THREAD_SELF \
((pthread_descr) (__thread_register \ ((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 # undef INIT_THREAD_SELF
# define INIT_THREAD_SELF(DESCR, NR) \ # define INIT_THREAD_SELF(DESCR, NR) \
(__thread_register = ((void *) (DESCR) \ (__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. /* Make sure we have the p_multiple_threads member in the thread structure.
See below. */ See below. */
@ -124,6 +124,10 @@ typedef struct
/* Get the thread descriptor definition. */ /* Get the thread descriptor definition. */
# include <linuxthreads/descr.h> # 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__ */ # endif /* __ASSEMBLER__ */
#elif !defined __ASSEMBLER__ && !defined __powerpc64__ #elif !defined __ASSEMBLER__ && !defined __powerpc64__

View File

@ -3,7 +3,7 @@
-- --
#ifdef USE_TLS #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) TLS_PRE_TCB_SIZE sizeof (struct _pthread_descr_struct)
#else #else
MULTIPLE_THREADS_OFFSET offsetof (tcbhead_t, multiple_threads) MULTIPLE_THREADS_OFFSET offsetof (tcbhead_t, multiple_threads)

View File

@ -101,7 +101,7 @@ __syscall_error_##args: \
# ifndef __ASSEMBLER__ # ifndef __ASSEMBLER__
# define SINGLE_THREAD_P \ # 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 # else
# define SINGLE_THREAD_P \ # define SINGLE_THREAD_P \
adds r14 = MULTIPLE_THREADS_OFFSET, r13 ;; ld4 r14 = [r14] ;; cmp4.ne p6, p7 = 0, r14 adds r14 = MULTIPLE_THREADS_OFFSET, r13 ;; ld4 r14 = [r14] ;; cmp4.ne p6, p7 = 0, r14

View File

@ -21,6 +21,8 @@
#include <tls.h> #include <tls.h>
#ifndef __ASSEMBLER__ #ifndef __ASSEMBLER__
# include <linuxthreads/internals.h> # include <linuxthreads/internals.h>
#else
# include <tcb-offsets.h>
#endif #endif
#if !defined NOT_IN_libc || defined IS_IN_libpthread #if !defined NOT_IN_libc || defined IS_IN_libpthread
@ -85,7 +87,7 @@
# ifndef __ASSEMBLER__ # ifndef __ASSEMBLER__
# define SINGLE_THREAD_P \ # 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 # else
# define SINGLE_THREAD_P \ # define SINGLE_THREAD_P \
lwz 10,MULTIPLE_THREADS_OFFSET(2); \ lwz 10,MULTIPLE_THREADS_OFFSET(2); \

View File

@ -121,7 +121,7 @@
# ifndef __ASSEMBLER__ # ifndef __ASSEMBLER__
# if defined FLOATING_STACKS && USE___THREAD && defined PIC # if defined FLOATING_STACKS && USE___THREAD && defined PIC
# define SINGLE_THREAD_P \ # 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 # else
extern int __local_multiple_threads attribute_hidden; extern int __local_multiple_threads attribute_hidden;
# define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1) # define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1)

View File

@ -1,3 +1,41 @@
2003-04-22 Jakub Jelinek <jakub@redhat.com>
* descr.h (p_multiple_threads): Define.
(struct pthread) [TLS_MULTIPLE_THREADS_IN_TCB]: Move
multiple_threads to last int in the structure.
* allocatestack.c (TLS_TPADJ): Add TLS_PRE_TCB_SIZE instead of
sizeof (struct pthread).
(allocate_stack): Subtract TLS_PRE_TCB_SIZE bytes instead of
1 struct pthread. Use p_multiple_threads macro.
* sysdeps/pthread/createthread.c (create_thread): Use
p_multiple_threads macro if TLS_DTV_AT_TP.
* sysdeps/powerpc/tls.h (TLS_INIT_TCB_SIZE, TLS_TCB_SIZE): Define
to 0.
(TLS_INIT_TCB_ALIGN, TLS_TCB_ALIGN): Define to alignment of
struct pthread.
(TLS_PRE_TCB_SIZE): Increase to cover tcbhead_t preceeded by pad
to 32-bit bytes.
(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/tcb-offsets.sym (MULTIPLE_THREADS): Use
p_multiple_threads macro.
* sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h
(SINGLE_THREAD_P): Likewise.
* sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h
(SINGLE_THREAD_P): Likewise.
* sysdeps/unix/sysv/linux/powerpc/createthread.c (TLS_VALUE): Don't
add TLS_TCB_SIZE unnecessarily.
* 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/sh/tcb-offsets.sym (MULTIPLE_THREADS): Likewise.
* sysdeps/unix/sysv/linux/sh/sysdep-cancel.h (SINGLE_THREAD_P):
Likewise.
2003-04-22 Roland McGrath <roland@redhat.com> 2003-04-22 Roland McGrath <roland@redhat.com>
* Makeconfig (shared-thread-library): Reverse link order to work * Makeconfig (shared-thread-library): Reverse link order to work

View File

@ -81,7 +81,7 @@
#if TLS_TCB_AT_TP #if TLS_TCB_AT_TP
# define TLS_TPADJ(pd) (pd) # define TLS_TPADJ(pd) (pd)
#elif TLS_DTV_AT_TP #elif TLS_DTV_AT_TP
# define TLS_TPADJ(pd) ((pd) + 1) # define TLS_TPADJ(pd) ((struct pthread *)((char *) (pd) + TLS_PRE_TCB_SIZE))
#endif #endif
/* Cache handling for not-yet free stacks. */ /* Cache handling for not-yet free stacks. */
@ -296,8 +296,9 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp,
pd = (struct pthread *) ((uintptr_t) attr->stackaddr pd = (struct pthread *) ((uintptr_t) attr->stackaddr
- TLS_TCB_SIZE - adj); - TLS_TCB_SIZE - adj);
#elif TLS_DTV_AT_TP #elif TLS_DTV_AT_TP
pd = (struct pthread *) ((uintptr_t) attr->stackaddr pd = (struct pthread *) (((uintptr_t) attr->stackaddr
- __static_tls_size - adj) - 1; - __static_tls_size - adj)
- TLS_PRE_TCB_SIZE);
#endif #endif
/* The user provided stack memory needs to be cleared. */ /* The user provided stack memory needs to be cleared. */
@ -321,7 +322,7 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp,
#ifdef TLS_MULTIPLE_THREADS_IN_TCB #ifdef TLS_MULTIPLE_THREADS_IN_TCB
/* This is at least the second thread. */ /* This is at least the second thread. */
pd->header.multiple_threads = 1; p_multiple_threads (pd) = 1;
#else #else
__pthread_multiple_threads = *__libc_multiple_threads_ptr = 1; __pthread_multiple_threads = *__libc_multiple_threads_ptr = 1;
#endif #endif
@ -426,9 +427,10 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp,
#if TLS_TCB_AT_TP #if TLS_TCB_AT_TP
pd = (struct pthread *) ((char *) mem + size - coloring) - 1; pd = (struct pthread *) ((char *) mem + size - coloring) - 1;
#elif TLS_DTV_AT_TP #elif TLS_DTV_AT_TP
pd = (struct pthread *) (((uintptr_t) mem + size - coloring pd = (struct pthread *) ((((uintptr_t) mem + size - coloring
- __static_tls_size) - __static_tls_size)
& ~__static_tls_align_m1) - 1; & ~__static_tls_align_m1)
- TLS_PRE_TCB_SIZE);
#endif #endif
/* Remember the stack-related values. */ /* Remember the stack-related values. */
@ -447,7 +449,7 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp,
#ifdef TLS_MULTIPLE_THREADS_IN_TCB #ifdef TLS_MULTIPLE_THREADS_IN_TCB
/* This is at least the second thread. */ /* This is at least the second thread. */
pd->header.multiple_threads = 1; p_multiple_threads (pd) = 1;
#else #else
__pthread_multiple_threads = *__libc_multiple_threads_ptr = 1; __pthread_multiple_threads = *__libc_multiple_threads_ptr = 1;
#endif #endif

View File

@ -99,11 +99,7 @@ struct pthread
#if !TLS_DTV_AT_TP #if !TLS_DTV_AT_TP
/* This overlaps the TCB as used for TLS without threads (see tls.h). */ /* This overlaps the TCB as used for TLS without threads (see tls.h). */
tcbhead_t header; tcbhead_t header;
#elif TLS_MULTIPLE_THREADS_IN_TCB # define p_multiple_threads(descr) (descr)->header.multiple_threads
struct
{
int multiple_threads;
} header;
#endif #endif
/* This extra padding has no special purpose, and this structure layout /* This extra padding has no special purpose, and this structure layout
@ -232,6 +228,21 @@ struct pthread
size_t stackblock_size; size_t stackblock_size;
/* Size of the included guard area. */ /* Size of the included guard area. */
size_t guardsize; size_t guardsize;
#if TLS_DTV_AT_TP && TLS_MULTIPLE_THREADS_IN_TCB
/* Must come last. */
int __multiple_threads;
# define p_multiple_threads(descr) \
((union \
{ \
struct pthread s; \
struct \
{ \
char dummy[sizeof (struct pthread) - sizeof (int)]; \
int multiple_threads; \
} m; \
} *)(descr)->m.multiple_threads)
#endif
} __attribute ((aligned (TCB_ALIGNMENT))); } __attribute ((aligned (TCB_ALIGNMENT)));

View File

@ -1,4 +1,4 @@
#include <sysdep.h> #include <sysdep.h>
#include <tls.h> #include <tls.h>
MULTIPLE_THREADS_OFFSET offsetof (struct pthread, header.multiple_threads) - sizeof (struct pthread) MULTIPLE_THREADS_OFFSET -sizeof(int)

View File

@ -1,13 +1,4 @@
#include <sysdep.h> #include <sysdep.h>
#include <tls.h> #include <tls.h>
-- MULTIPLE_THREADS_OFFSET ((void *) &p_multiple_threads ((struct pthread) ((void *) 0 - TLS_TCB_OFFSET - TLS_PRE_TCB_SIZE)) - (void *) 0)
-- 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->mem - (void *) 0)
#if TLS_MULTIPLE_THREADS_IN_TCB
MULTIPLE_THREADS_OFFSET thread_offsetof (header.multiple_threads)
#endif

View File

@ -69,22 +69,19 @@ typedef struct
} tcbhead_t; } tcbhead_t;
/* This is the size of the initial TCB. */ /* 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. */ /* Alignment requirements for the initial TCB. */
# define TLS_INIT_TCB_ALIGN __alignof__ (tcbhead_t) # define TLS_INIT_TCB_ALIGN __alignof__ (struct pthread)
/* This is the size of the TCB. */ /* This is the size of the TCB. */
# define TLS_TCB_SIZE sizeof (tcbhead_t) # define TLS_TCB_SIZE 0
/* Alignment requirements for the TCB. */ /* Alignment requirements for the TCB. */
# define TLS_TCB_ALIGN __alignof__ (tcbhead_t) # define TLS_TCB_ALIGN __alignof__ (struct pthread)
/* This is the size we need before TCB. */ /* This is the size we need before TCB. */
# define TLS_PRE_TCB_SIZE sizeof (struct pthread) # define TLS_PRE_TCB_SIZE (sizeof (struct pthread) + 32)
/* XXX if __alignof__ (struct pthread) > __alignof (tcbhead_t)
we could be in trouble. -- paulus */
# ifndef __powerpc64__ # ifndef __powerpc64__
/* Register r2 (tp) is reserved by the ABI as "thread pointer". */ /* Register r2 (tp) is reserved by the ABI as "thread pointer". */
@ -98,37 +95,37 @@ register void *__thread_register __asm__ ("r13");
/* The following assumes that TP (R2 or R13) points to the end of the /* The following assumes that TP (R2 or R13) points to the end of the
TCB + 0x7000 (per the ABI). This implies that TCB address is 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 struct is allocated immediately ahead of the assume that the pthread struct is allocated immediately ahead of the
TCB. This implies that the pthread_descr address is TCB. This implies that the pthread_descr address is
TP-(TLS_PRE_TCB_SIZE + TLS_TCB_SIZE + 0x7000). */ TP - (TLS_PRE_TCB_SIZE + 0x7000). */
# define TLS_TCB_OFFSET 0x7000 # define TLS_TCB_OFFSET 0x7000
/* 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(tcbp, dtvp) \ # define INSTALL_DTV(tcbp, dtvp) \
((tcbhead_t *) (tcbp))->dtv = dtvp + 1 ((tcbhead_t *) (tcbp))[-1].dtv = dtvp + 1
/* Install new dtv for current thread. */ /* Install new dtv for current thread. */
# define INSTALL_NEW_DTV(dtv) (THREAD_DTV() = (dtv)) # define INSTALL_NEW_DTV(dtv) (THREAD_DTV() = (dtv))
/* Return dtv of given thread descriptor. */ /* Return dtv of given thread descriptor. */
# define GET_DTV(tcbp) (((tcbhead_t *) (tcbp))->dtv) # define GET_DTV(tcbp) (((tcbhead_t *) (tcbp))[-1].dtv)
/* Code to initially initialize the thread pointer. This might need /* Code to initially initialize the thread pointer. This might need
special attention since 'errno' is not yet available and if the special attention since 'errno' is not yet available and if the
operation can cause a failure 'errno' must not be touched. */ operation can cause a failure 'errno' must not be touched. */
# define TLS_INIT_TP(tcbp, secondcall) \ # 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. */ /* Return the address of the dtv for the current thread. */
# define THREAD_DTV() \ # 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. */ /* Return the thread descriptor for the current thread. */
# define THREAD_SELF \ # define THREAD_SELF \
((struct pthread *) (__thread_register \ ((struct pthread *) (__thread_register \
- TLS_TCB_OFFSET - TLS_TCB_SIZE - TLS_PRE_TCB_SIZE)) - TLS_TCB_OFFSET - TLS_PRE_TCB_SIZE))
/* Read member of the thread descriptor directly. */ /* Read member of the thread descriptor directly. */
# define THREAD_GETMEM(descr, member) ((void)(descr), (THREAD_SELF)->member) # define THREAD_GETMEM(descr, member) ((void)(descr), (THREAD_SELF)->member)
@ -145,6 +142,10 @@ register void *__thread_register __asm__ ("r13");
# define THREAD_SETMEM_NC(descr, member, idx, value) \ # define THREAD_SETMEM_NC(descr, member, idx, value) \
((void)(descr), (THREAD_SELF)->member[idx] = (value)) ((void)(descr), (THREAD_SELF)->member[idx] = (value))
/* 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__ */ #endif /* __ASSEMBLER__ */
#endif /* tls.h */ #endif /* tls.h */

View File

@ -87,7 +87,11 @@ create_thread (struct pthread *pd, STACK_VARIABLES_PARMS)
thread might not yet have the flag set. No need to set thread might not yet have the flag set. No need to set
the global variable again if this is what we use. */ the global variable again if this is what we use. */
#ifdef TLS_MULTIPLE_THREADS_IN_TCB #ifdef TLS_MULTIPLE_THREADS_IN_TCB
# if TLS_DTV_AT_TP
p_multiple_threads (THREAD_SELF) = 1;
# else
THREAD_SETMEM (THREAD_SELF, header.multiple_threads, 1); THREAD_SETMEM (THREAD_SELF, header.multiple_threads, 1);
# endif
#endif #endif
/* Now fill in the information about the new thread in /* Now fill in the information about the new thread in
@ -159,7 +163,11 @@ create_thread (struct pthread *pd, STACK_VARIABLES_PARMS)
not yet have the flag set. No need to set the global variable not yet have the flag set. No need to set the global variable
again if this is what we use. */ again if this is what we use. */
#ifdef TLS_MULTIPLE_THREADS_IN_TCB #ifdef TLS_MULTIPLE_THREADS_IN_TCB
# if TLS_DTV_AT_TP
p_multiple_threads (THREAD_SELF) = 1;
# else
THREAD_SETMEM (THREAD_SELF, header.multiple_threads, 1); THREAD_SETMEM (THREAD_SELF, header.multiple_threads, 1);
# endif
#endif #endif
return 0; return 0;

View File

@ -1,5 +1,5 @@
#include <sysdep.h> #include <sysdep.h>
#include <tls.h> #include <tls.h>
MULTIPLE_THREADS_OFFSET offsetof (struct pthread, header.multiple_threads) MULTIPLE_THREADS_OFFSET ((char *) &p_multiple_threads ((struct pthread *)0) - (char *) 0)
TLS_PRE_TCB_SIZE sizeof (struct pthread) TLS_PRE_TCB_SIZE sizeof (struct pthread)

View File

@ -101,7 +101,7 @@ __syscall_error_##args: \
# ifndef __ASSEMBLER__ # ifndef __ASSEMBLER__
# define SINGLE_THREAD_P \ # define SINGLE_THREAD_P \
__builtin_expect (THREAD_GETMEM (THREAD_SELF, header.multiple_threads) == 0, 1) __builtin_expect (p_multiple_threads (THREAD_SELF) == 0, 1)
# else # else
# define SINGLE_THREAD_P \ # define SINGLE_THREAD_P \
adds r14 = MULTIPLE_THREADS_OFFSET, r13 ;; ld4 r14 = [r14] ;; cmp4.ne p6, p7 = 0, r14 adds r14 = MULTIPLE_THREADS_OFFSET, r13 ;; ld4 r14 = [r14] ;; cmp4.ne p6, p7 = 0, r14

View File

@ -19,7 +19,7 @@
/* Value passed to 'clone' for initialization of the thread register. */ /* Value passed to 'clone' for initialization of the thread register. */
#define TLS_VALUE ((void *) (pd) \ #define TLS_VALUE ((void *) (pd) \
+ TLS_TCB_OFFSET + TLS_TCB_SIZE + TLS_PRE_TCB_SIZE) + TLS_TCB_OFFSET + TLS_PRE_TCB_SIZE)
/* Get the real implementation. */ /* Get the real implementation. */
#include <nptl/sysdeps/pthread/createthread.c> #include <nptl/sysdeps/pthread/createthread.c>

View File

@ -86,8 +86,7 @@
# ifndef __ASSEMBLER__ # ifndef __ASSEMBLER__
# define SINGLE_THREAD_P \ # define SINGLE_THREAD_P \
__builtin_expect (THREAD_GETMEM (THREAD_SELF, \ __builtin_expect (p_multiple_threads (THREAD_SELF) == 0, 1)
header.multiple_threads) == 0, 1)
# else # else
# define SINGLE_THREAD_P \ # define SINGLE_THREAD_P \
lwz 10,MULTIPLE_THREADS_OFFSET(2); \ lwz 10,MULTIPLE_THREADS_OFFSET(2); \

View File

@ -86,8 +86,7 @@
# ifndef __ASSEMBLER__ # ifndef __ASSEMBLER__
# define SINGLE_THREAD_P \ # define SINGLE_THREAD_P \
__builtin_expect (THREAD_GETMEM (THREAD_SELF, \ __builtin_expect (p_multiple_threads (THREAD_SELF) == 0, 1)
header.multiple_threads) == 0, 1)
# else # else
# define SINGLE_THREAD_P \ # define SINGLE_THREAD_P \
lwz 10,MULTIPLE_THREADS_OFFSET(13); \ lwz 10,MULTIPLE_THREADS_OFFSET(13); \

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 (p_multiple_threads (THREAD_SELF) == 0, 1)
header.multiple_threads) == 0, 1)
# else # else
# define SINGLE_THREAD_P \ # define SINGLE_THREAD_P \
stc gbr,r0; \ stc gbr,r0; \

View File

@ -359,7 +359,7 @@ _dl_allocate_tls_init (void *result)
/* Unused entry. */ /* Unused entry. */
continue; continue;
if (map->l_tls_offset == 0) if (map->l_tls_offset == NO_TLS_OFFSET)
{ {
/* For dynamically loaded modules we simply store /* For dynamically loaded modules we simply store
the value indicating deferred allocation. */ the value indicating deferred allocation. */

View File

@ -35,7 +35,7 @@ typedef struct
/* Compute the value for a @tprel reloc. */ /* Compute the value for a @tprel reloc. */
#define TLS_TPREL_VALUE(sym_map, sym, reloc) \ #define TLS_TPREL_VALUE(sym_map, sym, reloc) \
((sym_map)->l_tls_offset + (sym)->st_value + (reloc)->r_addend \ ((sym_map)->l_tls_offset + (sym)->st_value + (reloc)->r_addend \
- TLS_TCB_SIZE - TLS_TP_OFFSET) - TLS_TP_OFFSET)
/* Compute the value for a @dtprel reloc. */ /* Compute the value for a @dtprel reloc. */
#define TLS_DTPREL_VALUE(sym, reloc) \ #define TLS_DTPREL_VALUE(sym, reloc) \