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.
This commit is contained in:
parent
8361400815
commit
8454830b08
@ -1,5 +1,47 @@
|
||||
2002-12-15 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* 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.
|
||||
|
||||
|
@ -18,51 +18,33 @@
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <pthread.h>
|
||||
#include <pthreadP.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <shlib-compat.h>
|
||||
#include <atomic.h>
|
||||
|
||||
|
||||
/* Pointers to the libc functions. */
|
||||
struct pthread_functions __libc_pthread_functions attribute_hidden;
|
||||
|
||||
|
||||
#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);
|
||||
|
||||
libpthread_handle = h ?: (void *) -1l;
|
||||
}
|
||||
|
||||
|
||||
#define FORWARD3(name, rettype, decl, params, defaction, version) \
|
||||
# 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)
|
||||
|
||||
|
||||
|
43
nptl/init.c
43
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);
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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));
|
||||
|
@ -21,6 +21,8 @@
|
||||
#include <list.h>
|
||||
#include "fork.h"
|
||||
#include <tls.h>
|
||||
#include <string.h>
|
||||
#include <pthreadP.h>
|
||||
#include <bits/libc-lock.h>
|
||||
|
||||
|
||||
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user