From c2afe833521105e05298500ba5d4676d6c833242 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Fri, 2 Aug 2002 03:32:24 +0000 Subject: * sysdeps/pthread/bits/libc-tsd.h: Include . [USE_TLS && HAVE___THREAD]: Just include the sysdeps/generic file, which does the right thing when __thread support is available. * descr.h (struct _pthread_descr_struct) [USE_TLS && HAVE___THREAD]: Omit `p_libc_specific', `p_errnop', `p_errno', `p_h_errnop', `p_h_errno', `p_resp', and `p_res' members. * pthread.c (__pthread_initialize_minimal) [USE_TLS && HAVE___THREAD]: Don't initialize `p_errnop' and `p_h_errnop' members. (__pthread_reset_main_thread): Likewise. (__pthread_initialize_manager): Likewise. * manager.c (__pthread_manager, pthread_handle_create): Likewise. * pthread.c (pthread_initialize) [USE_TLS && HAVE___THREAD]: Don't initialize `p_resp' member. (__pthread_reset_main_thread): Likewise. * manager.c (pthread_handle_create): Likewise. * specific.c (libc_internal_tsd_set, libc_internal_tsd_get): Conditionalize these on [!(USE_TLS && HAVE___THREAD)]. * errno.c [USE_TLS && HAVE___THREAD] (__h_errno_location, __res_state): Don't define these at all. * sysdeps/i386/tls.h (INSTALL_DTV): Add parens around arguments! (INSTALL_NEW_DTV, GET_DTV): Likewise. * sysdeps/sh/tls.h (INSTALL_DTV, INSTALL_NEW_DTV, GET_DTV): Likewise. * weaks.c: Don't include here. 2002-08-01 Roland McGrath * sysdeps/i386/tls.h (TLS_DO_MODIFY_LDT): New macro, broken out of TLS_INIT_TP. (TLS_DO_SET_THREAD_AREA): New macro, uses thread_set_area syscall. (TLS_SETUP_GS_SEGMENT): New macro, try one or the other or both. (TLS_INIT_TP): Use that. --- linuxthreads/ChangeLog | 36 ++++++++++++++++++++ linuxthreads/descr.h | 14 ++++---- linuxthreads/errno.c | 2 +- linuxthreads/manager.c | 4 +++ linuxthreads/pthread.c | 49 ++++++++++++++++++---------- linuxthreads/specific.c | 4 +++ linuxthreads/sysdeps/pthread/bits/libc-tsd.h | 14 ++++++-- linuxthreads/sysdeps/sh/tls.h | 8 ++--- linuxthreads/weaks.c | 3 +- 9 files changed, 101 insertions(+), 33 deletions(-) (limited to 'linuxthreads') diff --git a/linuxthreads/ChangeLog b/linuxthreads/ChangeLog index 2baa1e4..30917d3 100644 --- a/linuxthreads/ChangeLog +++ b/linuxthreads/ChangeLog @@ -1,3 +1,39 @@ +2002-07-30 Roland McGrath + + * sysdeps/pthread/bits/libc-tsd.h: Include . + [USE_TLS && HAVE___THREAD]: Just include the sysdeps/generic file, + which does the right thing when __thread support is available. + * descr.h (struct _pthread_descr_struct) [USE_TLS && HAVE___THREAD]: + Omit `p_libc_specific', `p_errnop', `p_errno', `p_h_errnop', + `p_h_errno', `p_resp', and `p_res' members. + * pthread.c (__pthread_initialize_minimal) [USE_TLS && HAVE___THREAD]: + Don't initialize `p_errnop' and `p_h_errnop' members. + (__pthread_reset_main_thread): Likewise. + (__pthread_initialize_manager): Likewise. + * manager.c (__pthread_manager, pthread_handle_create): Likewise. + * pthread.c (pthread_initialize) [USE_TLS && HAVE___THREAD]: + Don't initialize `p_resp' member. + (__pthread_reset_main_thread): Likewise. + * manager.c (pthread_handle_create): Likewise. + * specific.c (libc_internal_tsd_set, libc_internal_tsd_get): + Conditionalize these on [!(USE_TLS && HAVE___THREAD)]. + * errno.c [USE_TLS && HAVE___THREAD] + (__h_errno_location, __res_state): Don't define these at all. + + * sysdeps/i386/tls.h (INSTALL_DTV): Add parens around arguments! + (INSTALL_NEW_DTV, GET_DTV): Likewise. + * sysdeps/sh/tls.h (INSTALL_DTV, INSTALL_NEW_DTV, GET_DTV): Likewise. + + * weaks.c: Don't include here. + +2002-08-01 Roland McGrath + + * sysdeps/i386/tls.h (TLS_DO_MODIFY_LDT): New macro, broken out of + TLS_INIT_TP. + (TLS_DO_SET_THREAD_AREA): New macro, uses thread_set_area syscall. + (TLS_SETUP_GS_SEGMENT): New macro, try one or the other or both. + (TLS_INIT_TP): Use that. + 2002-08-02 Jakub Jelinek * sysdeps/i386/useldt.h (DO_MODIFY_LDT): Move from INIT_THREAD_SELF. diff --git a/linuxthreads/descr.h b/linuxthreads/descr.h index d0c31da..cc64cbc 100644 --- a/linuxthreads/descr.h +++ b/linuxthreads/descr.h @@ -130,15 +130,19 @@ struct _pthread_descr_struct { char p_cancelstate; /* cancellation state */ char p_canceltype; /* cancellation type (deferred/async) */ char p_canceled; /* cancellation request pending */ - int * p_errnop; /* pointer to used errno variable */ - int p_errno; /* error returned by last system call */ - int * p_h_errnop; /* pointer to used h_errno variable */ - int p_h_errno; /* error returned by last netdb function */ char * p_in_sighandler; /* stack address of sighandler, or NULL */ char p_sigwaiting; /* true if a sigwait() is in progress */ struct pthread_start_args p_start_args; /* arguments for thread creation */ void ** p_specific[PTHREAD_KEY_1STLEVEL_SIZE]; /* thread-specific data */ +#if !(USE_TLS && HAVE___THREAD) void * p_libc_specific[_LIBC_TSD_KEY_N]; /* thread-specific data for libc */ + int * p_errnop; /* pointer to used errno variable */ + int p_errno; /* error returned by last system call */ + int * p_h_errnop; /* pointer to used h_errno variable */ + int p_h_errno; /* error returned by last netdb function */ + struct __res_state *p_resp; /* Pointer to resolver state */ + struct __res_state p_res; /* per-thread resolver state */ +#endif int p_userstack; /* nonzero if the user provided the stack */ void *p_guardaddr; /* address of guard area or NULL */ size_t p_guardsize; /* size of guard area */ @@ -154,8 +158,6 @@ struct _pthread_descr_struct { pthread_readlock_info *p_readlock_list; /* List of readlock info structs */ pthread_readlock_info *p_readlock_free; /* Free list of structs */ int p_untracked_readlock_count; /* Readlocks not tracked by list */ - struct __res_state *p_resp; /* Pointer to resolver state */ - struct __res_state p_res; /* per-thread resolver state */ int p_inheritsched; /* copied from the thread attribute */ #if HP_TIMING_AVAIL hp_timing_t p_cpuclock_offset; /* Initial CPU clock for thread. */ diff --git a/linuxthreads/errno.c b/linuxthreads/errno.c index c74e4c4..57b1ebb 100644 --- a/linuxthreads/errno.c +++ b/linuxthreads/errno.c @@ -28,7 +28,6 @@ int * __errno_location() pthread_descr self = thread_self(); return THREAD_GETMEM (self, p_errnop); } -#endif int * __h_errno_location() { @@ -42,3 +41,4 @@ struct __res_state * __res_state() pthread_descr self = thread_self(); return THREAD_GETMEM (self, p_resp); } +#endif diff --git a/linuxthreads/manager.c b/linuxthreads/manager.c index 1b84fb7..11588fb 100644 --- a/linuxthreads/manager.c +++ b/linuxthreads/manager.c @@ -138,9 +138,11 @@ __pthread_manager(void *arg) #ifdef INIT_THREAD_SELF INIT_THREAD_SELF(self, 1); #endif +#if !(USE_TLS && HAVE___THREAD) /* Set the error variable. */ self->p_errnop = &self->p_errno; self->p_h_errnop = &self->p_h_errno; +#endif /* Block all signals except __pthread_sig_cancel and SIGTRAP */ sigfillset(&manager_mask); sigdelset(&manager_mask, __pthread_sig_cancel); /* for thread termination */ @@ -640,9 +642,11 @@ static int pthread_handle_create(pthread_t *thread, const pthread_attr_t *attr, new_thread->p_lock = &(__pthread_handles[sseg].h_lock); new_thread->p_cancelstate = PTHREAD_CANCEL_ENABLE; new_thread->p_canceltype = PTHREAD_CANCEL_DEFERRED; +#if !(USE_TLS && HAVE___THREAD) new_thread->p_errnop = &new_thread->p_errno; new_thread->p_h_errnop = &new_thread->p_h_errno; new_thread->p_resp = &new_thread->p_res; +#endif new_thread->p_guardaddr = guardaddr; new_thread->p_guardsize = guardsize; new_thread->p_header.data.self = new_thread; diff --git a/linuxthreads/pthread.c b/linuxthreads/pthread.c index 8bca63e..3c978a5 100644 --- a/linuxthreads/pthread.c +++ b/linuxthreads/pthread.c @@ -33,27 +33,28 @@ #include #include -/* We need the global/static resolver state here. */ -#include -#undef _res - -extern struct __res_state _res; - /* Sanity check. */ #if __ASSUME_REALTIME_SIGNALS && !defined __SIGRTMIN # error "This must not happen; new kernel assumed but old headers" #endif -/* These variables are used by the setup code. */ -extern int _errno; -extern int _h_errno; - #ifdef USE_TLS /* We need only a few variables. */ static pthread_descr manager_thread; #else + +/* These variables are used by the setup code. */ +extern int _errno; +extern int _h_errno; + +/* We need the global/static resolver state here. */ +#include +#undef _res + +extern struct __res_state _res; + /* Descriptor of the initial thread */ struct _pthread_descr_struct __pthread_initial_thread = { @@ -83,16 +84,18 @@ struct _pthread_descr_struct __pthread_initial_thread = { 0, /* char p_cancelstate */ 0, /* char p_canceltype */ 0, /* char p_canceled */ - &_errno, /* int *p_errnop */ - 0, /* int p_errno */ - &_h_errno, /* int *p_h_errnop */ - 0, /* int p_h_errno */ NULL, /* char * p_in_sighandler */ 0, /* char p_sigwaiting */ PTHREAD_START_ARGS_INITIALIZER(NULL), /* struct pthread_start_args p_start_args */ {NULL}, /* void ** p_specific[PTHREAD_KEY_1STLEVEL_SIZE] */ {NULL}, /* void * p_libc_specific[_LIBC_TSD_KEY_N] */ + &_errno, /* int *p_errnop */ + 0, /* int p_errno */ + &_h_errno, /* int *p_h_errnop */ + 0, /* int p_h_errno */ + &_res, /* struct __res_state *p_resp */ + {}, /* struct __res_state p_res */ 1, /* int p_userstack */ NULL, /* void * p_guardaddr */ 0, /* size_t p_guardsize */ @@ -141,16 +144,18 @@ struct _pthread_descr_struct __pthread_manager_thread = { 0, /* char p_cancelstate */ 0, /* char p_canceltype */ 0, /* char p_canceled */ - &__pthread_manager_thread.p_errno, /* int *p_errnop */ - 0, /* int p_errno */ - NULL, /* int *p_h_errnop */ - 0, /* int p_h_errno */ NULL, /* char * p_in_sighandler */ 0, /* char p_sigwaiting */ PTHREAD_START_ARGS_INITIALIZER(__pthread_manager), /* struct pthread_start_args p_start_args */ {NULL}, /* void ** p_specific[PTHREAD_KEY_1STLEVEL_SIZE] */ {NULL}, /* void * p_libc_specific[_LIBC_TSD_KEY_N] */ + &__pthread_manager_thread.p_errno, /* int *p_errnop */ + 0, /* int p_errno */ + NULL, /* int *p_h_errnop */ + 0, /* int p_h_errno */ + NULL, /* struct __res_state *p_resp */ + {}, /* struct __res_state p_res */ 0, /* int p_userstack */ NULL, /* void * p_guardaddr */ 0, /* size_t p_guardsize */ @@ -423,8 +428,10 @@ __pthread_initialize_minimal(void) self->p_nextlive = self->p_prevlive = self; self->p_tid = PTHREAD_THREADS_MAX; self->p_lock = &__pthread_handles[0].h_lock; +# ifndef HAVE___THREAD self->p_errnop = &_errno; self->p_h_errnop = &_h_errno; +# endif /* self->p_start_args need not be initialized, it's all zero. */ self->p_userstack = 1; # if __LT_SPINLOCK_INIT != 0 @@ -521,8 +528,10 @@ static void pthread_initialize(void) #ifdef USE_TLS /* Update the descriptor for the initial thread. */ THREAD_SETMEM (((pthread_descr) NULL), p_pid, __getpid()); +# ifndef HAVE___THREAD /* Likewise for the resolver state _res. */ THREAD_SETMEM (((pthread_descr) NULL), p_resp, &_res); +# endif #else /* Update the descriptor for the initial thread. */ __pthread_initial_thread.p_pid = __getpid(); @@ -615,7 +624,9 @@ int __pthread_initialize_manager(void) /* Initialize the descriptor. */ tcb->p_header.data.self = tcb; tcb->p_lock = &__pthread_handles[1].h_lock; +# ifndef HAVE___THREAD tcb->p_errnop = &tcb->p_errno; +# endif tcb->p_start_args = (struct pthread_start_args) PTHREAD_START_ARGS_INITIALIZER(__pthread_manager); tcb->p_nr = 1; # if __LT_SPINLOCK_INIT != 0 @@ -1048,10 +1059,12 @@ void __pthread_reset_main_thread(void) __pthread_main_thread = self; THREAD_SETMEM(self, p_nextlive, self); THREAD_SETMEM(self, p_prevlive, self); +#if !(USE_TLS && HAVE___THREAD) /* Now this thread modifies the global variables. */ THREAD_SETMEM(self, p_errnop, &_errno); THREAD_SETMEM(self, p_h_errnop, &_h_errno); THREAD_SETMEM(self, p_resp, &_res); +#endif if (getrlimit (RLIMIT_STACK, &limit) == 0 && limit.rlim_cur != limit.rlim_max) { diff --git a/linuxthreads/specific.c b/linuxthreads/specific.c index 2dbf205..caa6736 100644 --- a/linuxthreads/specific.c +++ b/linuxthreads/specific.c @@ -204,6 +204,8 @@ void __pthread_destroy_specifics() __pthread_unlock(THREAD_GETMEM(self, p_lock)); } +#if !(USE_TLS && HAVE___THREAD) + /* Thread-specific data for libc. */ static int @@ -226,3 +228,5 @@ libc_internal_tsd_get(enum __libc_tsd_key_t key) } void * (*__libc_internal_tsd_get)(enum __libc_tsd_key_t key) = libc_internal_tsd_get; + +#endif diff --git a/linuxthreads/sysdeps/pthread/bits/libc-tsd.h b/linuxthreads/sysdeps/pthread/bits/libc-tsd.h index 7a532ea..79808a5 100644 --- a/linuxthreads/sysdeps/pthread/bits/libc-tsd.h +++ b/linuxthreads/sysdeps/pthread/bits/libc-tsd.h @@ -1,5 +1,5 @@ /* libc-internal interface for thread-specific data. LinuxThreads version. - Copyright (C) 1997, 1998, 1999, 2001 Free Software Foundation, Inc. + Copyright (C) 1997,98,99,2001,02 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -20,13 +20,21 @@ #ifndef _BITS_LIBC_TSD_H #define _BITS_LIBC_TSD_H 1 - /* Fast thread-specific data internal to libc. */ enum __libc_tsd_key_t { _LIBC_TSD_KEY_MALLOC = 0, _LIBC_TSD_KEY_DL_ERROR, _LIBC_TSD_KEY_RPC_VARS, _LIBC_TSD_KEY_N }; +#include + +#if USE_TLS && HAVE___THREAD + +/* When __thread works, the generic definition is what we want. */ +# include + +#else + extern void *(*__libc_internal_tsd_get) (enum __libc_tsd_key_t) __THROW; extern int (*__libc_internal_tsd_set) (enum __libc_tsd_key_t, __const void *) __THROW; @@ -41,4 +49,6 @@ extern int (*__libc_internal_tsd_set) (enum __libc_tsd_key_t, ? __libc_internal_tsd_set (_LIBC_TSD_KEY_##KEY, (VALUE)) \ : ((__libc_tsd_##KEY##_data = (VALUE)), 0)) +#endif + #endif /* bits/libc-tsd.h */ diff --git a/linuxthreads/sysdeps/sh/tls.h b/linuxthreads/sysdeps/sh/tls.h index e8cf504..7dc4040 100644 --- a/linuxthreads/sysdeps/sh/tls.h +++ b/linuxthreads/sysdeps/sh/tls.h @@ -73,16 +73,16 @@ 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) \ ({ struct _pthread_descr_struct *__descr; \ - THREAD_SETMEM (__descr, p_header.data.dtvp, dtv); }) + THREAD_SETMEM (__descr, p_header.data.dtvp, (dtv)); }) /* Return dtv of given thread descriptor. */ # define GET_DTV(descr) \ - (((tcbhead_t *) descr)->dtv) + (((tcbhead_t *) (descr))->dtv) /* Code to initially initialize the thread pointer. This might need special attention since 'errno' is not yet available and if the @@ -94,7 +94,7 @@ typedef struct tcbhead_t *head = _descr; \ \ head->tcb = _descr; \ - /* For now the thread descriptor is at the same address. */ \ + /* For now the thread descriptor is at the same address. */ \ head->self = _descr; \ \ asm ("ldc %0,gbr" : : "r" (_descr)); \ diff --git a/linuxthreads/weaks.c b/linuxthreads/weaks.c index 036e004..3bbf546 100644 --- a/linuxthreads/weaks.c +++ b/linuxthreads/weaks.c @@ -1,5 +1,5 @@ /* The weak pthread functions for Linux. - Copyright (C) 1996,1997,1998,1999,2000,2001 Free Software Foundation, Inc. + Copyright (C) 1996,97,98,99,2000,01,02 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -17,7 +17,6 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include #include #include #include -- cgit v1.1