about summary refs log tree commit diff
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)