aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--nptl/ChangeLog42
-rw-r--r--nptl/forward.c36
-rw-r--r--nptl/init.c43
-rw-r--r--nptl/pthreadP.h85
-rw-r--r--nptl/sysdeps/unix/sysv/linux/fork.h4
-rw-r--r--nptl/sysdeps/unix/sysv/linux/libc_pthread_init.c13
6 files changed, 190 insertions, 33 deletions
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 <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.
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 <dlfcn.h>
-#include <pthread.h>
+#include <pthreadP.h>
#include <stdlib.h>
#include <shlib-compat.h>
#include <atomic.h>
-#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 <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)