From cd30b01ee9cdefd2e6f81b1c25ee6897243706fc Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Thu, 7 Feb 2002 08:44:37 +0000 Subject: Update. 2002-02-07 Ulrich Drepper * sysdeps/generic/dl-tls.c (_dl_determine_tlsoffset): Account for alignment of the TCB and store total size and alignment of static TLS block in _dl_tls_static_size and _dl_tls_static_align. tls_index is a typedef. * sysdeps/generic/ldsodefs.h: Declare _dl_tls_static_size and _dl_tls_static_align. * sysdeps/i386/dl-tls.h: tls_index is a typedef. * elf/dl-support.c: Define _dl_tls_static_size and _dl_tls_static_align. --- ChangeLog | 12 ++++++++ elf/dl-support.c | 5 +++ linuxthreads/ChangeLog | 11 +++++++ linuxthreads/descr.h | 67 +++++++++++++++++++++++++++++++++++++++++ linuxthreads/internals.h | 65 --------------------------------------- linuxthreads/sysdeps/i386/tls.h | 13 +++++--- sysdeps/generic/dl-tls.c | 25 +++++++++++++-- sysdeps/generic/ldsodefs.h | 5 +++ sysdeps/i386/dl-tls.h | 8 ++--- 9 files changed, 136 insertions(+), 75 deletions(-) diff --git a/ChangeLog b/ChangeLog index 82c1059..9de0606 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2002-02-07 Ulrich Drepper + + * sysdeps/generic/dl-tls.c (_dl_determine_tlsoffset): Account for + alignment of the TCB and store total size and alignment of static + TLS block in _dl_tls_static_size and _dl_tls_static_align. + tls_index is a typedef. + * sysdeps/generic/ldsodefs.h: Declare _dl_tls_static_size and + _dl_tls_static_align. + * sysdeps/i386/dl-tls.h: tls_index is a typedef. + * elf/dl-support.c: Define _dl_tls_static_size and + _dl_tls_static_align. + 2002-02-06 Ulrich Drepper * configure.in: Add --without-tls option. diff --git a/elf/dl-support.c b/elf/dl-support.c index 4eaa675..914b43f 100644 --- a/elf/dl-support.c +++ b/elf/dl-support.c @@ -147,6 +147,11 @@ struct link_map *_dl_initimage_list; size_t _dl_tls_max_dtv_idx; /* Flag signalling whether there are gaps in the module ID allocation. */ bool _dl_tls_dtv_gaps; + +/* Size of the static TLS block. */ +size_t _dl_tls_static_size; +/* Alignment requirement of the static TLS block. */ +size_t _dl_tls_static_align; #endif diff --git a/linuxthreads/ChangeLog b/linuxthreads/ChangeLog index a4ab63c..49f1aa7 100644 --- a/linuxthreads/ChangeLog +++ b/linuxthreads/ChangeLog @@ -1,3 +1,14 @@ +2002-02-07 Ulrich Drepper + + * internals.h: Move declarations/definitions of + __pthread_initial_thread_bos, __pthread_initial_thread, + __pthread_manager_thread_bos, __pthread_manager_thread_tos, + __pthread_manager_thread, __pthread_nonstandard_stacks, STACK_SIZE, + CURRENT_STACK_FRAME, __pthread_find_self, and thread_self... + * descr.h: ...here. + * sysdeps/i386/tls.h: Add TLS definitions also for !FLOATING_STACKS. + Define THREAD_GETMEM accordingly. + 2002-02-06 Ulrich Drepper * sysdeps/i386/tls.h: Include for size_t. diff --git a/linuxthreads/descr.h b/linuxthreads/descr.h index 4cfad89..a2cddb1 100644 --- a/linuxthreads/descr.h +++ b/linuxthreads/descr.h @@ -165,4 +165,71 @@ struct _pthread_descr_struct { 32 bytes might give better cache utilization. */ + + +/* Limit between the stack of the initial thread (above) and the + stacks of other threads (below). Aligned on a STACK_SIZE boundary. + Initially 0, meaning that the current thread is (by definition) + the initial thread. */ + +extern char *__pthread_initial_thread_bos; + +/* Descriptor of the initial thread */ + +extern struct _pthread_descr_struct __pthread_initial_thread; + +/* Limits of the thread manager stack. */ + +extern char *__pthread_manager_thread_bos; +extern char *__pthread_manager_thread_tos; + +/* Descriptor of the manager thread */ + +extern struct _pthread_descr_struct __pthread_manager_thread; + +/* Indicate whether at least one thread has a user-defined stack (if 1), + or all threads have stacks supplied by LinuxThreads (if 0). */ + +extern int __pthread_nonstandard_stacks; + +/* The max size of the thread stack segments. If the default + THREAD_SELF implementation is used, this must be a power of two and + a multiple of PAGE_SIZE. */ +#ifndef STACK_SIZE +#define STACK_SIZE (2 * 1024 * 1024) +#endif + +/* Get some notion of the current stack. Need not be exactly the top + of the stack, just something somewhere in the current frame. */ +#ifndef CURRENT_STACK_FRAME +#define CURRENT_STACK_FRAME ({ char __csf; &__csf; }) +#endif + +/* Recover thread descriptor for the current thread */ + +extern pthread_descr __pthread_find_self (void) __attribute__ ((const)); + +static inline pthread_descr thread_self (void) __attribute__ ((const)); +static inline pthread_descr thread_self (void) +{ +#ifdef THREAD_SELF + return THREAD_SELF; +#else + char *sp = CURRENT_STACK_FRAME; + if (sp >= __pthread_initial_thread_bos) + return &__pthread_initial_thread; + else if (sp >= __pthread_manager_thread_bos + && sp < __pthread_manager_thread_tos) + return &__pthread_manager_thread; + else if (__pthread_nonstandard_stacks) + return __pthread_find_self(); + else +#ifdef _STACK_GROWS_DOWN + return (pthread_descr)(((unsigned long)sp | (STACK_SIZE-1))+1) - 1; +#else + return (pthread_descr)((unsigned long)sp &~ (STACK_SIZE-1)); +#endif +#endif +} + #endif /* descr.h */ diff --git a/linuxthreads/internals.h b/linuxthreads/internals.h index e1768b4..056e36d 100644 --- a/linuxthreads/internals.h +++ b/linuxthreads/internals.h @@ -110,30 +110,10 @@ extern int __pthread_sig_debug; extern struct pthread_handle_struct __pthread_handles[PTHREAD_THREADS_MAX]; -/* Descriptor of the initial thread */ - -extern struct _pthread_descr_struct __pthread_initial_thread; - -/* Descriptor of the manager thread */ - -extern struct _pthread_descr_struct __pthread_manager_thread; - /* Descriptor of the main thread */ extern pthread_descr __pthread_main_thread; -/* Limit between the stack of the initial thread (above) and the - stacks of other threads (below). Aligned on a STACK_SIZE boundary. - Initially 0, meaning that the current thread is (by definition) - the initial thread. */ - -extern char *__pthread_initial_thread_bos; - -/* Indicate whether at least one thread has a user-defined stack (if 1), - or all threads have stacks supplied by LinuxThreads (if 0). */ - -extern int __pthread_nonstandard_stacks; - /* File descriptor for sending requests to the thread manager. Initially -1, meaning that __pthread_initialize_manager must be called. */ @@ -143,11 +123,6 @@ extern int __pthread_manager_request; extern int __pthread_manager_reader; -/* Limits of the thread manager stack. */ - -extern char *__pthread_manager_thread_bos; -extern char *__pthread_manager_thread_tos; - #ifdef FLOATING_STACKS /* Maximum stack size. */ extern size_t __pthread_max_stacksize; @@ -202,13 +177,6 @@ static inline int nonexisting_handle(pthread_handle h, pthread_t id) #define PAGE_SIZE (sysconf (_SC_PAGE_SIZE)) #endif -/* The max size of the thread stack segments. If the default - THREAD_SELF implementation is used, this must be a power of two and - a multiple of PAGE_SIZE. */ -#ifndef STACK_SIZE -#define STACK_SIZE (2 * 1024 * 1024) -#endif - /* The initial size of the thread stack. Must be a multiple of PAGE_SIZE. */ #ifndef INITIAL_STACK_SIZE #define INITIAL_STACK_SIZE (4 * PAGE_SIZE) @@ -227,39 +195,6 @@ static inline int nonexisting_handle(pthread_handle h, pthread_t id) #define THREAD_STACK_START_ADDRESS __pthread_initial_thread_bos #endif -/* Get some notion of the current stack. Need not be exactly the top - of the stack, just something somewhere in the current frame. */ -#ifndef CURRENT_STACK_FRAME -#define CURRENT_STACK_FRAME ({ char __csf; &__csf; }) -#endif - -/* Recover thread descriptor for the current thread */ - -extern pthread_descr __pthread_find_self (void) __attribute__ ((const)); - -static inline pthread_descr thread_self (void) __attribute__ ((const)); -static inline pthread_descr thread_self (void) -{ -#ifdef THREAD_SELF - return THREAD_SELF; -#else - char *sp = CURRENT_STACK_FRAME; - if (sp >= __pthread_initial_thread_bos) - return &__pthread_initial_thread; - else if (sp >= __pthread_manager_thread_bos - && sp < __pthread_manager_thread_tos) - return &__pthread_manager_thread; - else if (__pthread_nonstandard_stacks) - return __pthread_find_self(); - else -#ifdef _STACK_GROWS_DOWN - return (pthread_descr)(((unsigned long)sp | (STACK_SIZE-1))+1) - 1; -#else - return (pthread_descr)((unsigned long)sp &~ (STACK_SIZE-1)); -#endif -#endif -} - /* If MEMORY_BARRIER isn't defined in pt-machine.h, assume the architecture doesn't need a memory barrier instruction (e.g. Intel x86). Some architectures distinguish between full, read and write barriers. */ diff --git a/linuxthreads/sysdeps/i386/tls.h b/linuxthreads/sysdeps/i386/tls.h index 870832c..ed5e634 100644 --- a/linuxthreads/sysdeps/i386/tls.h +++ b/linuxthreads/sysdeps/i386/tls.h @@ -42,7 +42,7 @@ typedef struct /* We can support TLS only if the floating-stack support is available. */ -#if FLOATING_STACKS && defined HAVE_TLS_SUPPORT +#ifdef HAVE_TLS_SUPPORT /* Get system call information. */ # include @@ -94,11 +94,16 @@ typedef struct /* Return the address of the dtv for the current thread. */ -# define THREAD_DTV() \ +# if FLOATING_STACKS +# define THREAD_DTV() \ ({ struct _pthread_descr_struct *__descr; \ THREAD_GETMEM (__descr, p_header.data.dtvp); }) +# else +# define THREAD_DTV() \ + ({ struct _pthread_descr_struct *__descr = thread_self (); \ + THREAD_GETMEM (__descr, p_header.data.dtvp); }) +# endif - -#endif +#endif /* HAVE_TLS_SUPPORT */ #endif /* tls.h */ diff --git a/sysdeps/generic/dl-tls.c b/sysdeps/generic/dl-tls.c index 729adf0..1b16bd5 100644 --- a/sysdeps/generic/dl-tls.c +++ b/sysdeps/generic/dl-tls.c @@ -103,7 +103,21 @@ _dl_determine_tlsoffset (struct link_map *firstp) /* The thread descriptor (pointed to by the thread pointer) has its own alignment requirement. Adjust the static TLS size - appropriately. */ + and TLS offsets appropriately. */ + if (offset % TLS_TCB_ALIGN != 0) + { + size_t add = TLS_TCB_ALIGN - offset % TLS_TCB_ALIGN; + + /* XXX If the offset stored is negative we must subtract here. */ + offset += add; + + runp = firstp; + do + runp->l_tls_offset += add; + while ((runp = runp->l_tls_nextimage) != firstp); + } + + GL(dl_tls_static_size) = offset + TLS_TCB_SIZE; # elif TLS_DTV_AT_TP struct link_map *lastp; @@ -121,10 +135,17 @@ _dl_determine_tlsoffset (struct link_map *firstp) offset = roundup (offset + lastp->l_tls_blocksize, runp->l_tls_align); runp->l_tls_offset = offset; + + lastp = runp; } + + GL(dl_tls_static_size) = offset + lastp->l_tls_blocksize; # else # error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined" # endif + + /* The alignment requirement for the static TLS block. */ + GL(dl_tls_static_align) = MAX (TLS_TCB_ALIGN, max_align); } @@ -136,7 +157,7 @@ _dl_determine_tlsoffset (struct link_map *firstp) it. Users of the IA-64 form have to provide adequate definitions of the following macros. */ # ifndef GET_ADDR_ARGS -# define GET_ADDR_ARGS struct tls_index *ti +# define GET_ADDR_ARGS tls_index *ti # endif # ifndef GET_ADDR_MODULE # define GET_ADDR_MODULE ti->ti_module diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h index 9913820..f049878 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h @@ -298,6 +298,11 @@ struct rtld_global EXTERN size_t _dl_tls_max_dtv_idx; /* Flag signalling whether there are gaps in the module ID allocation. */ EXTERN bool _dl_tls_dtv_gaps; + + /* Size of the static TLS block. */ + EXTERN size_t _dl_tls_static_size; + /* Alignment requirement of the static TLS block. */ + EXTERN size_t _dl_tls_static_align; #endif /* Name of the shared object to be profiled (if any). */ diff --git a/sysdeps/i386/dl-tls.h b/sysdeps/i386/dl-tls.h index 5398609..7fe4be8 100644 --- a/sysdeps/i386/dl-tls.h +++ b/sysdeps/i386/dl-tls.h @@ -19,15 +19,15 @@ #ifdef USE_TLS /* Type used for the representation of TLS information in the GOT. */ -struct tls_index +typedef struct { unsigned long int ti_module; unsigned long int ti_offset; -}; +} tls_index; /* This is the prototype for the GNU version. */ -extern void *___tls_get_addr (struct tls_index *ti) +extern void *___tls_get_addr (tls_index *ti) __attribute__ ((__regparm__ (1))); /* The special thing about the x86 TLS ABI is that we have two @@ -37,7 +37,7 @@ extern void *___tls_get_addr (struct tls_index *ti) an additional underscore at the beginning. The Sun version uses the normal calling convention. */ void * -__tls_get_addr (struct tls_index *ti) +__tls_get_addr (tls_index *ti) { return ___tls_get_addr (ti); } -- cgit v1.1