From 8454830b083e01a66c3a273fca0d7b46a7e4d0dc Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Sun, 15 Dec 2002 20:06:34 +0000 Subject: Update. * init.c (pthread_functions): New variable. (__pthread_initialize_minimal): Pass pointer to pthread_functions (or NULL) to __libc_pthread_init. * forward.c: Rewrite to use __libc:pthread_functions array to get function addresses. * sysdeps/unix/sysv/linux/fork.h: Remove __libc_pthread_init prototype. * sysdeps/unix/sysv/linux/libc_pthread_init.c (__libc_pthread_init): Take new parameter. Copy content of variable pointed to by it to __libc_pthread_init. * pthreadP.h (struct pthread_functions): New type. (__libc_pthread_init): Declare. * pthread_attr_destroy.c: Add namespace protected alias. * pthread_attr_getdetachstate.c: Likewise. * pthread_attr_getinheritsched.c: Likewise. * pthread_attr_getschedparam.c: Likewise. * pthread_attr_getschedpolicy.c: Likewise. * pthread_attr_getscope.c: Likewise. * pthread_attr_setdetachstate.c: Likewise. * pthread_attr_setinheritsched.c: Likewise. * pthread_attr_setschedparam.c: Likewise. * pthread_attr_setschedpolicy.c: Likewise. * pthread_attr_setscope.c: Likewise. * pthread_cond_broadcast.c: Likewise. * pthread_cond_destroy.c: Likewise. * pthread_cond_init.c: Likewise. * pthread_cond_signal.c: Likewise. * pthread_cond_wait.c: Likewise. * pthread_condattr_destroy.c: Likewise. * pthread_condattr_init.c: Likewise. * pthread_equal.c: Likewise. * pthread_exit.c: Likewise. * pthread_getschedparam.c: Likewise. * pthread_self.c: Likewise. * pthread_setcancelstate.c: Likewise. * pthread_setschedparam.c: Likewise. * pthread_mutex_destroy.c: Likewise. * pthread_mutex_init.c: Likewise. * pthreadP.h: Add prototypes for the aliases. --- nptl/ChangeLog | 42 ++++++++++++ nptl/forward.c | 36 +++------- nptl/init.c | 43 +++++++++++- nptl/pthreadP.h | 85 ++++++++++++++++++++++++ nptl/sysdeps/unix/sysv/linux/fork.h | 4 -- nptl/sysdeps/unix/sysv/linux/libc_pthread_init.c | 13 +++- 6 files changed, 190 insertions(+), 33 deletions(-) (limited to 'nptl') diff --git a/nptl/ChangeLog b/nptl/ChangeLog index 7dc9523530..1ed889e19d 100644 --- a/nptl/ChangeLog +++ b/nptl/ChangeLog @@ -1,5 +1,47 @@ 2002-12-15 Ulrich Drepper + * init.c (pthread_functions): New variable. + (__pthread_initialize_minimal): Pass pointer to pthread_functions + (or NULL) to __libc_pthread_init. + * forward.c: Rewrite to use __libc:pthread_functions array to get + function addresses. + * sysdeps/unix/sysv/linux/fork.h: Remove __libc_pthread_init + prototype. + * sysdeps/unix/sysv/linux/libc_pthread_init.c (__libc_pthread_init): + Take new parameter. Copy content of variable pointed to by it + to __libc_pthread_init. + + * pthreadP.h (struct pthread_functions): New type. + (__libc_pthread_init): Declare. + + * pthread_attr_destroy.c: Add namespace protected alias. + * pthread_attr_getdetachstate.c: Likewise. + * pthread_attr_getinheritsched.c: Likewise. + * pthread_attr_getschedparam.c: Likewise. + * pthread_attr_getschedpolicy.c: Likewise. + * pthread_attr_getscope.c: Likewise. + * pthread_attr_setdetachstate.c: Likewise. + * pthread_attr_setinheritsched.c: Likewise. + * pthread_attr_setschedparam.c: Likewise. + * pthread_attr_setschedpolicy.c: Likewise. + * pthread_attr_setscope.c: Likewise. + * pthread_cond_broadcast.c: Likewise. + * pthread_cond_destroy.c: Likewise. + * pthread_cond_init.c: Likewise. + * pthread_cond_signal.c: Likewise. + * pthread_cond_wait.c: Likewise. + * pthread_condattr_destroy.c: Likewise. + * pthread_condattr_init.c: Likewise. + * pthread_equal.c: Likewise. + * pthread_exit.c: Likewise. + * pthread_getschedparam.c: Likewise. + * pthread_self.c: Likewise. + * pthread_setcancelstate.c: Likewise. + * pthread_setschedparam.c: Likewise. + * pthread_mutex_destroy.c: Likewise. + * pthread_mutex_init.c: Likewise. + * pthreadP.h: Add prototypes for the aliases. + * sysdeps/unix/sysv/linux/i386/createthread.c (create_thread): Set multiple_threads member in correct TCB to 1. diff --git a/nptl/forward.c b/nptl/forward.c index 6c278c0690..e178136737 100644 --- a/nptl/forward.c +++ b/nptl/forward.c @@ -18,51 +18,33 @@ 02111-1307 USA. */ #include -#include +#include #include #include #include -#if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_3_2) -static void *libpthread_handle; - - -static void -test_loaded (void) -{ - /* While we are getting the result set the handle to (void *) -1 to - avoid recursive calls. */ - atomic_compare_and_exchange_acq (&libpthread_handle, (void *) -1l, NULL); - - void *h = __libc_dlopen_mode ("libpthread.so.0", RTLD_LAZY | RTLD_NOLOAD); +/* Pointers to the libc functions. */ +struct pthread_functions __libc_pthread_functions attribute_hidden; - libpthread_handle = h ?: (void *) -1l; -} - -#define FORWARD3(name, rettype, decl, params, defaction, version) \ +#if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_3_2) +# define FORWARD3(name, rettype, decl, params, defaction, version) \ rettype \ __noexport_##name decl \ { \ - if (libpthread_handle == NULL) \ - test_loaded (); \ - \ - if (libpthread_handle == (void *) -1l) \ + if (__libc_pthread_functions.ptr_##name == NULL) \ defaction; \ \ - static __typeof (name) *p; \ - p = __libc_dlsym (libpthread_handle, #name); \ - \ - return p params; \ + return __libc_pthread_functions.ptr_##name params; \ } \ compat_symbol (libc, __noexport_##name, name, version) -#define FORWARD2(name, decl, params, defretval, version) \ +# define FORWARD2(name, decl, params, defretval, version) \ FORWARD3 (name, int, decl, params, return defretval, version) -#define FORWARD(name, decl, params, defretval) \ +# define FORWARD(name, decl, params, defretval) \ FORWARD2 (name, decl, params, defretval, GLIBC_2_0) diff --git a/nptl/init.c b/nptl/init.c index 66976ff615..1ec12f436f 100644 --- a/nptl/init.c +++ b/nptl/init.c @@ -52,6 +52,46 @@ extern void __libc_setup_tls (size_t tcbsize, size_t tcbalign); #endif +#ifdef SHARED +static struct pthread_functions pthread_functions = + { + .ptr_pthread_attr_destroy = __pthread_attr_destroy, + .ptr_pthread_attr_init = __pthread_attr_init_2_1, + .ptr_pthread_attr_getdetachstate = __pthread_attr_getdetachstate, + .ptr_pthread_attr_setdetachstate = __pthread_attr_setdetachstate, + .ptr_pthread_attr_getinheritsched = __pthread_attr_getinheritsched, + .ptr_pthread_attr_setinheritsched = __pthread_attr_setinheritsched, + .ptr_pthread_attr_getschedparam = __pthread_attr_getschedparam, + .ptr_pthread_attr_setschedparam = __pthread_attr_setschedparam, + .ptr_pthread_attr_getschedpolicy = __pthread_attr_getschedpolicy, + .ptr_pthread_attr_setschedpolicy = __pthread_attr_setschedpolicy, + .ptr_pthread_attr_getscope = __pthread_attr_getscope, + .ptr_pthread_attr_setscope = __pthread_attr_setscope, + .ptr_pthread_condattr_destroy = __pthread_condattr_destroy, + .ptr_pthread_condattr_init = __pthread_condattr_init, + .ptr_pthread_cond_broadcast = __pthread_cond_broadcast, + .ptr_pthread_cond_destroy = __pthread_cond_destroy, + .ptr_pthread_cond_init = __pthread_cond_init, + .ptr_pthread_cond_signal = __pthread_cond_signal, + .ptr_pthread_cond_wait = __pthread_cond_wait, + .ptr_pthread_equal = __pthread_equal, + .ptr_pthread_exit = __pthread_exit, + .ptr_pthread_getschedparam = __pthread_getschedparam, + .ptr_pthread_setschedparam = __pthread_setschedparam, + .ptr_pthread_mutex_destroy = INTUSE(__pthread_mutex_destroy), + .ptr_pthread_mutex_init = INTUSE(__pthread_mutex_init), + .ptr_pthread_mutex_lock = INTUSE(__pthread_mutex_lock), + .ptr_pthread_mutex_unlock = INTUSE(__pthread_mutex_unlock), + .ptr_pthread_self = __pthread_self, + .ptr_pthread_setcancelstate = __pthread_setcancelstate, + .ptr_pthread_setcanceltype = __pthread_setcanceltype + }; +# define ptr_pthread_functions &pthread_functions +#else +# define ptr_pthread_functions NULL +#endif + + /* For asynchronous cancellation we use a signal. This is the handler. */ static void sigcancel_handler (int sig __attribute ((unused))) @@ -167,5 +207,6 @@ __pthread_initialize_minimal (void) __static_tls_size = roundup (__static_tls_size, __static_tls_align); /* Register the fork generation counter with the libc. */ - __libc_pthread_init (&__fork_generation, __reclaim_stacks); + __libc_pthread_init (&__fork_generation, __reclaim_stacks, + ptr_pthread_functions); } diff --git a/nptl/pthreadP.h b/nptl/pthreadP.h index 94f169c564..e759e83062 100644 --- a/nptl/pthreadP.h +++ b/nptl/pthreadP.h @@ -67,6 +67,50 @@ extern int __pthread_debug attribute_hidden; #define DEBUGGING_P __builtin_expect (__pthread_debug, 0) +/* Data type shared with libc. The libc uses it to pass on calls to + the thread functions. */ +struct pthread_functions +{ + int (*ptr_pthread_attr_destroy) (pthread_attr_t *); + int (*ptr_pthread_attr_init) (pthread_attr_t *); + int (*ptr_pthread_attr_getdetachstate) (const pthread_attr_t *, int *); + int (*ptr_pthread_attr_setdetachstate) (pthread_attr_t *, int); + int (*ptr_pthread_attr_getinheritsched) (const pthread_attr_t *, int *); + int (*ptr_pthread_attr_setinheritsched) (pthread_attr_t *, int); + int (*ptr_pthread_attr_getschedparam) (const pthread_attr_t *, + struct sched_param *); + int (*ptr_pthread_attr_setschedparam) (pthread_attr_t *, + const struct sched_param *); + int (*ptr_pthread_attr_getschedpolicy) (const pthread_attr_t *, int *); + int (*ptr_pthread_attr_setschedpolicy) (pthread_attr_t *, int); + int (*ptr_pthread_attr_getscope) (const pthread_attr_t *, int *); + int (*ptr_pthread_attr_setscope) (pthread_attr_t *, int); + int (*ptr_pthread_condattr_destroy) (pthread_condattr_t *); + int (*ptr_pthread_condattr_init) (pthread_condattr_t *); + int (*ptr_pthread_cond_broadcast) (pthread_cond_t *); + int (*ptr_pthread_cond_destroy) (pthread_cond_t *); + int (*ptr_pthread_cond_init) (pthread_cond_t *, const pthread_condattr_t *); + int (*ptr_pthread_cond_signal) (pthread_cond_t *); + int (*ptr_pthread_cond_wait) (pthread_cond_t *, pthread_mutex_t *); + int (*ptr_pthread_equal) (pthread_t, pthread_t); + void (*ptr_pthread_exit) (void *); + int (*ptr_pthread_getschedparam) (pthread_t, int *, struct sched_param *); + int (*ptr_pthread_setschedparam) (pthread_t, int, + const struct sched_param *); + int (*ptr_pthread_mutex_destroy) (pthread_mutex_t *); + int (*ptr_pthread_mutex_init) (pthread_mutex_t *, + const pthread_mutexattr_t *); + int (*ptr_pthread_mutex_lock) (pthread_mutex_t *); + int (*ptr_pthread_mutex_unlock) (pthread_mutex_t *); + pthread_t (*ptr_pthread_self) (void); + int (*ptr_pthread_setcancelstate) (int, int *); + int (*ptr_pthread_setcanceltype) (int, int *); +}; + +/* Variable in libc.so. */ +extern struct pthread_functions __libc_pthread_functions attribute_hidden; + + /* Cancellation test. */ #define CANCELLATION_P(self) \ do { \ @@ -170,11 +214,24 @@ extern void __nptl_death_event (void); hidden_proto (__nptl_create_event) hidden_proto (__nptl_death_event) +/* Register the generation counter in the libpthread with the libc. */ +extern void __libc_pthread_init (unsigned long int *ptr, + void (*reclaim) (void), + const struct pthread_functions *functions); + /* Namespace save aliases. */ +extern int __pthread_getschedparam (pthread_t thread_id, int *policy, + struct sched_param *param); +extern int __pthread_setschedparam (pthread_t thread_id, int policy, + const struct sched_param *param); +extern int __pthread_setcancelstate (int state, int *oldstate); extern int __pthread_mutex_init (pthread_mutex_t *__mutex, __const pthread_mutexattr_t *__mutexattr); +extern int __pthread_mutex_init_internal (pthread_mutex_t *__mutex, + __const pthread_mutexattr_t *__mutexattr); extern int __pthread_mutex_destroy (pthread_mutex_t *__mutex); +extern int __pthread_mutex_destroy_internal (pthread_mutex_t *__mutex); extern int __pthread_mutex_trylock (pthread_mutex_t *_mutex); extern int __pthread_mutex_lock (pthread_mutex_t *__mutex); extern int __pthread_mutex_lock_internal (pthread_mutex_t *__mutex); @@ -183,6 +240,23 @@ extern int __pthread_mutex_unlock_internal (pthread_mutex_t *__mutex); extern int __pthread_mutexattr_init (pthread_mutexattr_t *attr); extern int __pthread_mutexattr_destroy (pthread_mutexattr_t *attr); extern int __pthread_mutexattr_settype (pthread_mutexattr_t *attr, int kind); +extern int __pthread_attr_destroy (pthread_attr_t *attr); +extern int __pthread_attr_getdetachstate (const pthread_attr_t *attr, + int *detachstate); +extern int __pthread_attr_setdetachstate (pthread_attr_t *attr, + int detachstate); +extern int __pthread_attr_getinheritsched (const pthread_attr_t *attr, + int *inherit); +extern int __pthread_attr_setinheritsched (pthread_attr_t *attr, int inherit); +extern int __pthread_attr_getschedparam (const pthread_attr_t *attr, + struct sched_param *param); +extern int __pthread_attr_setschedparam (pthread_attr_t *attr, + const struct sched_param *param); +extern int __pthread_attr_getschedpolicy (const pthread_attr_t *attr, + int *policy); +extern int __pthread_attr_setschedpolicy (pthread_attr_t *attr, int policy); +extern int __pthread_attr_getscope (const pthread_attr_t *attr, int *scope); +extern int __pthread_attr_setscope (pthread_attr_t *attr, int scope); extern int __pthread_attr_getstackaddr (__const pthread_attr_t *__restrict __attr, void **__restrict __stackaddr); extern int __pthread_attr_setstackaddr (pthread_attr_t *__attr, @@ -206,6 +280,14 @@ extern int __pthread_rwlock_tryrdlock (pthread_rwlock_t *__rwlock); extern int __pthread_rwlock_wrlock (pthread_rwlock_t *__rwlock); extern int __pthread_rwlock_trywrlock (pthread_rwlock_t *__rwlock); extern int __pthread_rwlock_unlock (pthread_rwlock_t *__rwlock); +extern int __pthread_cond_broadcast (pthread_cond_t *cond); +extern int __pthread_cond_destroy (pthread_cond_t *cond); +extern int __pthread_cond_init (pthread_cond_t *cond, + const pthread_condattr_t *cond_attr); +extern int __pthread_cond_signal (pthread_cond_t *cond); +extern int __pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex); +extern int __pthread_condattr_destroy (pthread_condattr_t *attr); +extern int __pthread_condattr_init (pthread_condattr_t *attr); extern int __pthread_key_create (pthread_key_t *key, void (*destr) (void *)); extern void *__pthread_getspecific (pthread_key_t key); extern int __pthread_setspecific (pthread_key_t key, const void *value); @@ -215,7 +297,10 @@ extern int __pthread_once_internal (pthread_once_t *once_control, void (*init_routine) (void)); extern int __pthread_atfork (void (*prepare) (void), void (*parent) (void), void (*child) (void)); +extern pthread_t __pthread_self (void); +extern int __pthread_equal (pthread_t thread1, pthread_t thread2); extern int __pthread_kill (pthread_t threadid, int signo); +extern void __pthread_exit (void *value); extern int __pthread_setcanceltype (int type, int *oldtype); extern int __pthread_enable_asynccancel (void) attribute_hidden; extern void __pthread_disable_asynccancel (int oldtype) diff --git a/nptl/sysdeps/unix/sysv/linux/fork.h b/nptl/sysdeps/unix/sysv/linux/fork.h index f2899225b8..906cf7fcc0 100644 --- a/nptl/sysdeps/unix/sysv/linux/fork.h +++ b/nptl/sysdeps/unix/sysv/linux/fork.h @@ -54,7 +54,3 @@ extern int __register_atfork (void (*__prepare) (void), void (*__parent) (void), void (*__child) (void), void *dso_handle); - -/* Register the generation counter in the libpthread with the libc. */ -extern void __libc_pthread_init (unsigned long int *__ptr, - void (*reclaim) (void)); diff --git a/nptl/sysdeps/unix/sysv/linux/libc_pthread_init.c b/nptl/sysdeps/unix/sysv/linux/libc_pthread_init.c index bf0551a7e4..7d91528aaf 100644 --- a/nptl/sysdeps/unix/sysv/linux/libc_pthread_init.c +++ b/nptl/sysdeps/unix/sysv/linux/libc_pthread_init.c @@ -21,6 +21,8 @@ #include #include "fork.h" #include +#include +#include #include @@ -28,9 +30,10 @@ static struct fork_handler pthread_child_handler; void -__libc_pthread_init (ptr, reclaim) +__libc_pthread_init (ptr, reclaim, functions) unsigned long int *ptr; void (*reclaim) (void); + const struct pthread_functions *functions; { /* Remember the pointer to the generation counter in libpthread. */ __fork_generation_pointer = ptr; @@ -41,6 +44,14 @@ __libc_pthread_init (ptr, reclaim) /* The fork handler needed by libpthread. */ list_add_tail (&pthread_child_handler.list, &__fork_child_list); +#ifdef SHARED + /* We copy the content of the variable pointed to by the FUNCTIONS + parameter to one in libc.so since this means access to the array + can be done with one memory access instead of two. */ + memcpy (&__libc_pthread_functions, functions, + sizeof (__libc_pthread_functions)); +#endif + /* We have a macro which is used in asm code describing data layout. Make sure it does not get out of date. */ if (offsetof (struct pthread, header.data.multiple_threads) -- cgit 1.4.1