about summary refs log tree commit diff
path: root/linuxthreads
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2002-12-18 01:38:17 +0000
committerUlrich Drepper <drepper@redhat.com>2002-12-18 01:38:17 +0000
commit82f81a9086320d12eb2fc45766203954b90461a2 (patch)
treeb2c668e5ee6bc1e9c4176cee394ac7f37b382617 /linuxthreads
parentf077a4a9f027b938bd091583e3ec34725cba428c (diff)
downloadglibc-82f81a9086320d12eb2fc45766203954b90461a2.tar.gz
glibc-82f81a9086320d12eb2fc45766203954b90461a2.tar.xz
glibc-82f81a9086320d12eb2fc45766203954b90461a2.zip
Update.
	* sysdeps/unix/sysv/linux/alpha/syscalls.list (msgrcv, msgsnd):
	Make cancelable.
	* sysdeps/unix/sysv/linux/hppa/syscalls.list (msgrcv, msgsnd):
	Likewise.
	* sysdeps/unix/sysv/linux/ia64/syscalls.list (msgrcv, msgsnd):
	Likewise.
	* sysdeps/unix/sysv/linux/s390/s390-64/syscalls.list (msgrcv, msgsnd):
	Likewise.
	* sysdeps/unix/sysv/linux/x86_64/syscalls.list (msgrcv, msgsnd):
	Likewise.
	* sysdeps/unix/sysv/linux/ia64/sigsuspend.c (__sigsuspend): Likewise.
Diffstat (limited to 'linuxthreads')
-rw-r--r--linuxthreads/ChangeLog119
-rw-r--r--linuxthreads/Makefile26
-rw-r--r--linuxthreads/Versions3
-rw-r--r--linuxthreads/attr.c37
-rw-r--r--linuxthreads/cancel.c43
-rw-r--r--linuxthreads/condvar.c23
-rw-r--r--linuxthreads/descr.h1
-rw-r--r--linuxthreads/forward.c146
-rw-r--r--linuxthreads/internals.h126
-rw-r--r--linuxthreads/join.c3
-rw-r--r--linuxthreads/libc-cancellation.c75
-rw-r--r--linuxthreads/libc_pthread_init.c53
-rw-r--r--linuxthreads/lockfile.c30
-rw-r--r--linuxthreads/manager.c1
-rw-r--r--linuxthreads/mutex.c5
-rw-r--r--linuxthreads/pt-allocrtsig.c50
-rw-r--r--linuxthreads/pt-system.c32
-rw-r--r--linuxthreads/pthread.c188
-rw-r--r--linuxthreads/sysdeps/pthread/bits/libc-lock.h33
-rw-r--r--linuxthreads/sysdeps/pthread/flockfile.c33
-rw-r--r--linuxthreads/sysdeps/pthread/ftrylockfile.c33
-rw-r--r--linuxthreads/sysdeps/pthread/funlockfile.c33
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/allocrtsig.c85
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/i386/sysdep-cancel.h124
-rw-r--r--linuxthreads/sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h118
-rw-r--r--linuxthreads/sysdeps/x86_64/pt-machine.h31
-rw-r--r--linuxthreads/tst-cancel-wrappers.sh96
-rw-r--r--linuxthreads/weaks.c97
-rw-r--r--linuxthreads/wrapsyscall.c233
29 files changed, 1348 insertions, 529 deletions
diff --git a/linuxthreads/ChangeLog b/linuxthreads/ChangeLog
index 179e247f2e..a84d4bd383 100644
--- a/linuxthreads/ChangeLog
+++ b/linuxthreads/ChangeLog
@@ -1,3 +1,122 @@
+2002-12-18  Jakub Jelinek  <jakub@redhat.com>
+
+	* internals.h (__pthread_thread_self): New prototype.
+	(struct pthread_functions): Add ptr_pthread_thread_self field.
+	* pthread.c (pthread_functions): Initialize ptr_pthread_thread_self.
+	(__pthread_thread_self): New function.
+	* libc-cancellation.c (__pthread_thread_self): Add weak_extern.
+	(__libc_enable_asynccancel, __libc_disable_asynccancel): Don't
+	use thread_self() directly if not FLOATING_STACKS.
+
+2002-12-18  Jakub Jelinek  <jakub@redhat.com>
+
+	* sysdeps/x86_64/pt-machine.h: Guard most of the header
+	with #ifndef __ASSEMBLER__.
+	* pthread.c (pthread_functions): Use SHLIB_COMPAT around
+	pthread_attr_init_2_0 use.
+
+2002-12-17  Jakub Jelinek  <jakub@redhat.com>
+
+	* wrapsyscall.c: Removed.
+	* weaks.c: Removed.
+	* Makefile (distribute): Add tst-cancel-wrappers.sh.
+	(routines): Remove weaks.  Add forward,
+	libc_pthread_init, libc-cancellation.
+	(shared-only-routines): Remove weaks.  Add forward.
+	(libpthread-routines): Remove wrapsyscall.
+	Add ptw-write, ptw-read, ptw-close, ptw-fcntl, ptw-accept,
+	ptw-connect, ptw-recv, ptw-recvfrom, ptw-recvmsg, ptw-send,
+	ptw-sendmsg, ptw-sendto, ptw-fsync, ptw-lseek, ptw-lseek64,
+	ptw-llseek, ptw-msync, ptw-nanosleep, ptw-open, ptw-open64,
+	ptw-pause, ptw-pread, ptw-pread64, ptw-pwrite, ptw-pwrite64,
+	ptw-tcdrain, ptw-wait, ptw-waitpid, pt-system, pt-allocrtsig.
+	(libpthread-shared-only-routines): Add pt-allocrtsig.
+	(tests): Depend on $(objpfx)tst-cancel-wrappers.out.
+	($(objpfx)tst-cancel-wrappers.out): New rule.
+	* sysdeps/pthread/bits/libc-lock.h: Include linuxthreads/internals.h
+	if in libc.
+	(__libc_maybe_call): In libpthread.* don't check for existance
+	of the function.
+	(__libc_maybe_call2): Define.
+	(__libc_lock_init, __libc_lock_fini, __libc_lock_lock,
+	__libc_lock_trylock, __libc_lock_unlock): Use it.
+	* sysdeps/pthread/flockfile.c: New file.
+	* sysdeps/pthread/ftrylockfile.c: New file.
+	* sysdeps/pthread/funlockfile.c: New file.
+	* sysdeps/unix/sysv/linux/i386/sysdep-cancel.h: New file.
+	* sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h: New file.
+	* sysdeps/unix/sysv/linux/allocrtsig.c: New file.
+	* libc-cancellation.c: New file.
+	* forward.c: New file.
+	* libc_pthread_init.c: New file.
+	* pt-system.c: New file.
+	* pthread.c: Remove locale.h.
+	(__pthread_manager_thread): Initialize multiple_threads.
+	(__pthread_multiple_threads): Declare.
+	(pthread_functions): New variable.
+	(__pthread_initialize_minimal): Remove __uselocale call.
+	Call __libc_pthread_init.
+	(__pthread_initialize_manager): Initialize __pthread_multiple_threads,
+	initial thread's multiple_threads and __libc_multiple_threads.
+	Check MULTIPLE_THREADS_OFFSET value. Initialize manager thread's
+	multiple_threads.
+	(pthread_setschedparam, pthread_getschedparam): Rename to __
+	prefixed variants.  Add strong_alias.
+	(current_rtmin, current_rtmax, __libc_current_sigrtmin,
+	__libc_current_sigrtmax, __libc_allocate_rtsig): Remove.
+	(init_rtsigs): Use __libc_current_sigrtmin_private.
+	(pthread_initialize): Only call init_rtsigs if
+	!__ASSUME_REALTIME_SIGNALS.
+	(__pthread_require_wrappers, __pthread_require_lockfile): Remove.
+	* internals.h (__pthread_attr_destroy, __pthread_attr_setdetachstate,
+	__pthread_attr_getdetachstate, __pthread_attr_setschedparam,
+	__pthread_attr_getschedparam, __pthread_attr_setschedpolicy,
+	__pthread_attr_getschedpolicy, __pthread_attr_setinheritsched,
+	__pthread_attr_getinheritsched, __pthread_attr_setscope,
+	__pthread_attr_getscope, __pthread_cond_init,
+	__pthread_cond_destroy, __pthread_cond_wait,
+	__pthread_cond_signal, __pthread_cond_broadcast,
+	__pthread_condattr_init, __pthread_condattr_destroy,
+	__pthread_equal, __pthread_getschedparam,
+	__pthread_setschedparam, __pthread_setcancelstate,
+	__pthread_setcanceltype, __pthread_enable_asynccancel,
+	__libc_enable_asynccancel, __libc_pthread_init): New prototype.
+	(__pthread_mutex_init, __pthread_mutex_destroy,
+	__pthread_mutex_lock, __pthread_mutex_unlock,
+	__pthread_mutex_trylock): Likewise.
+	Add hidden_proto.
+	(struct pthread_functions): New type.
+	(__libc_pthread_functions): New variable.
+	(LIBC_CANCEL_ASYNC, LIBC_CANCEL_RESET): Define.
+	* descr.h (struct _pthread_descr_struct): Add
+	p_header.data.multiple_threads field.
+	* manager.c (pthread_handle_create): Initialize multiple_threads.
+	* cancel.c (__pthread_enable_asynccancel,
+	__pthread_disable_asynccancel): New functions.
+	(__pthread_provide_wrappers): Remove.
+	(pthread_setcancelstate, pthread_setcanceltype): Rename to __
+	prefixed variants.  Add strong_alias.
+	* condvar.c (pthread_cond_init, pthread_cond_destroy,
+	pthread_cond_wait, pthread_cond_signal, pthread_cond_broadcast,
+	pthread_condattr_init, pthread_condattr_destroy): Likewise.
+	* join.c (pthread_exit): Likewise.
+	* attr.c (pthread_attr_destroy, pthread_attr_setdetachstate,
+	pthread_attr_getdetachstate, pthread_attr_setschedparam,
+	pthread_attr_getschedparam, pthread_attr_setschedpolicy,
+	pthread_attr_getschedpolicy, pthread_attr_setinheritsched,
+	pthread_attr_getinheritsched, pthread_attr_setscope,
+	pthread_attr_getscope): Likewise.
+	* mutex.c (__pthread_mutex_init, __pthread_mutex_destroy,
+	__pthread_mutex_lock, __pthread_mutex_unlock,
+	__pthread_mutex_trylock): Add hidden_def.
+	* Versions (libc): Add __libc_pthread_init,
+	__libc_current_sigrtmin_private, __libc_current_sigrtmax_private,
+	__libc_allocate_rtsig_private @@GLIBC_PRIVATE.
+	* lockfile.c: Remove some USE_IN_LIBIO guards.
+	(__pthread_provide_lockfile): Remove.
+	* pt-allocrtsig.c: New file.
+	* tst-cancel-wrappers.sh: New test.
+
 2002-12-15  Ulrich Drepper  <drepper@redhat.com>
 
 	* Versions [libpthread: GLIBC_2.3.2]: Remove creat, poll, pselect,
diff --git a/linuxthreads/Makefile b/linuxthreads/Makefile
index fca0137571..7c993ac0fd 100644
--- a/linuxthreads/Makefile
+++ b/linuxthreads/Makefile
@@ -26,20 +26,29 @@ linuxthreads-version := $(shell sed -n 's/^.*$(subdir)-\([0-9.]*\).*$$/\1/p' \
 
 headers := pthread.h semaphore.h
 distribute := internals.h queue.h restart.h spinlock.h smp.h tst-signal.sh \
-	      libc-tsd.c
+	      tst-cancel-wrappers.sh libc-tsd.c
 
-routines := weaks no-tsd
-shared-only-routines = weaks
+routines := forward no-tsd libc-cancellation libc_pthread_init
+shared-only-routines = forward
 
 extra-libs := libpthread
 extra-libs-others := $(extra-libs)
 
 libpthread-routines := attr cancel condvar join manager mutex ptfork \
 		       ptlongjmp pthread signals specific errno lockfile \
-		       semaphore spinlock wrapsyscall rwlock pt-machine \
+		       semaphore spinlock rwlock pt-machine \
 		       oldsemaphore events getcpuclockid pspinlock barrier \
 		       ptclock_gettime ptclock_settime sighandler \
-		       pthandles libc-tls-loc
+		       pthandles libc-tls-loc pt-allocrtsig \
+		       ptw-write ptw-read ptw-close ptw-fcntl ptw-accept \
+		       ptw-connect ptw-recv ptw-recvfrom ptw-recvmsg \
+		       ptw-send ptw-sendmsg ptw-sendto ptw-fsync ptw-lseek \
+		       ptw-lseek64 ptw-llseek ptw-msync ptw-nanosleep \
+		       ptw-open ptw-open64 ptw-pause ptw-pread ptw-pread64 \
+		       ptw-pwrite ptw-pwrite64 ptw-tcdrain ptw-wait \
+		       ptw-waitpid pt-system
+
+libpthread-shared-only-routines = pt-allocrtsig
 
 nodelete-yes = -Wl,--enable-new-dtags,-z,nodelete
 initfirst-yes = -Wl,--enable-new-dtags,-z,initfirst
@@ -194,8 +203,13 @@ endif
 
 ifeq (no,$(cross-compiling))
 ifeq (yes,$(build-shared))
-tests: $(objpfx)tst-signal.out
+tests: $(objpfx)tst-signal.out $(objpfx)tst-cancel-wrappers.out
 $(objpfx)tst-signal.out: tst-signal.sh $(objpfx)tst-signal
 	$(SHELL) -e $< $(common-objpfx) > $@
+$(objpfx)tst-cancel-wrappers.out: tst-cancel-wrappers.sh
+	$(SHELL) $< $(common-objpfx)/libc_pic.a \
+		    $(common-objpfx)/libc.a \
+		    $(objpfx)/libpthread_pic.a \
+		    $(objpfx)/libpthread.a > $@
 endif
 endif
diff --git a/linuxthreads/Versions b/linuxthreads/Versions
index 78b1a937cf..fea2e368d8 100644
--- a/linuxthreads/Versions
+++ b/linuxthreads/Versions
@@ -22,6 +22,9 @@ libc {
     __libc_internal_tsd_address; __libc_alloca_cutoff;
     __libc_dl_error_tsd;
 
+    __libc_pthread_init; __libc_current_sigrtmin_private;
+    __libc_current_sigrtmax_private; __libc_allocate_rtsig_private;
+
     __libc_creat; __libc_poll; __libc_pselect; __libc_select;
     __libc_sigpause; __libc_sigsuspend; __libc_sigwait; __libc_sigwaitinfo;
     __libc_waitid; __libc___xpg_sigpause;
diff --git a/linuxthreads/attr.c b/linuxthreads/attr.c
index 8b7e8ce81c..58a7b69f94 100644
--- a/linuxthreads/attr.c
+++ b/linuxthreads/attr.c
@@ -56,12 +56,13 @@ compat_symbol (libpthread, __pthread_attr_init_2_0, pthread_attr_init,
 	       GLIBC_2_0);
 #endif
 
-int pthread_attr_destroy(pthread_attr_t *attr)
+int __pthread_attr_destroy(pthread_attr_t *attr)
 {
   return 0;
 }
+strong_alias (__pthread_attr_destroy, pthread_attr_destroy);
 
-int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate)
+int __pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate)
 {
   if (detachstate < PTHREAD_CREATE_JOINABLE ||
       detachstate > PTHREAD_CREATE_DETACHED)
@@ -69,15 +70,17 @@ int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate)
   attr->__detachstate = detachstate;
   return 0;
 }
+strong_alias (__pthread_attr_setdetachstate, pthread_attr_setdetachstate);
 
-int pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate)
+int __pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate)
 {
   *detachstate = attr->__detachstate;
   return 0;
 }
+strong_alias (__pthread_attr_getdetachstate, pthread_attr_getdetachstate);
 
-int pthread_attr_setschedparam(pthread_attr_t *attr,
-                               const struct sched_param *param)
+int __pthread_attr_setschedparam(pthread_attr_t *attr,
+                                 const struct sched_param *param)
 {
   int max_prio = __sched_get_priority_max(attr->__schedpolicy);
   int min_prio = __sched_get_priority_min(attr->__schedpolicy);
@@ -87,43 +90,49 @@ int pthread_attr_setschedparam(pthread_attr_t *attr,
   memcpy (&attr->__schedparam, param, sizeof (struct sched_param));
   return 0;
 }
+strong_alias (__pthread_attr_setschedparam, pthread_attr_setschedparam);
 
-int pthread_attr_getschedparam(const pthread_attr_t *attr,
-                               struct sched_param *param)
+int __pthread_attr_getschedparam(const pthread_attr_t *attr,
+                                 struct sched_param *param)
 {
   memcpy (param, &attr->__schedparam, sizeof (struct sched_param));
   return 0;
 }
+strong_alias (__pthread_attr_getschedparam, pthread_attr_getschedparam);
 
-int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy)
+int __pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy)
 {
   if (policy != SCHED_OTHER && policy != SCHED_FIFO && policy != SCHED_RR)
     return EINVAL;
   attr->__schedpolicy = policy;
   return 0;
 }
+strong_alias (__pthread_attr_setschedpolicy, pthread_attr_setschedpolicy);
 
-int pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *policy)
+int __pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *policy)
 {
   *policy = attr->__schedpolicy;
   return 0;
 }
+strong_alias (__pthread_attr_getschedpolicy, pthread_attr_getschedpolicy);
 
-int pthread_attr_setinheritsched(pthread_attr_t *attr, int inherit)
+int __pthread_attr_setinheritsched(pthread_attr_t *attr, int inherit)
 {
   if (inherit != PTHREAD_INHERIT_SCHED && inherit != PTHREAD_EXPLICIT_SCHED)
     return EINVAL;
   attr->__inheritsched = inherit;
   return 0;
 }
+strong_alias (__pthread_attr_setinheritsched, pthread_attr_setinheritsched);
 
-int pthread_attr_getinheritsched(const pthread_attr_t *attr, int *inherit)
+int __pthread_attr_getinheritsched(const pthread_attr_t *attr, int *inherit)
 {
   *inherit = attr->__inheritsched;
   return 0;
 }
+strong_alias (__pthread_attr_getinheritsched, pthread_attr_getinheritsched);
 
-int pthread_attr_setscope(pthread_attr_t *attr, int scope)
+int __pthread_attr_setscope(pthread_attr_t *attr, int scope)
 {
   switch (scope) {
   case PTHREAD_SCOPE_SYSTEM:
@@ -135,12 +144,14 @@ int pthread_attr_setscope(pthread_attr_t *attr, int scope)
     return EINVAL;
   }
 }
+strong_alias (__pthread_attr_setscope, pthread_attr_setscope);
 
-int pthread_attr_getscope(const pthread_attr_t *attr, int *scope)
+int __pthread_attr_getscope(const pthread_attr_t *attr, int *scope)
 {
   *scope = attr->__scope;
   return 0;
 }
+strong_alias (__pthread_attr_getscope, pthread_attr_getscope);
 
 int __pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize)
 {
diff --git a/linuxthreads/cancel.c b/linuxthreads/cancel.c
index 47c0bfee04..838f55d8b2 100644
--- a/linuxthreads/cancel.c
+++ b/linuxthreads/cancel.c
@@ -30,7 +30,7 @@
 #endif
 
 
-int pthread_setcancelstate(int state, int * oldstate)
+int __pthread_setcancelstate(int state, int * oldstate)
 {
   pthread_descr self = thread_self();
   if (state < PTHREAD_CANCEL_ENABLE || state > PTHREAD_CANCEL_DISABLE)
@@ -43,8 +43,9 @@ int pthread_setcancelstate(int state, int * oldstate)
     __pthread_do_exit(PTHREAD_CANCELED, CURRENT_STACK_FRAME);
   return 0;
 }
+strong_alias (__pthread_setcancelstate, pthread_setcancelstate);
 
-int pthread_setcanceltype(int type, int * oldtype)
+int __pthread_setcanceltype(int type, int * oldtype)
 {
   pthread_descr self = thread_self();
   if (type < PTHREAD_CANCEL_DEFERRED || type > PTHREAD_CANCEL_ASYNCHRONOUS)
@@ -57,6 +58,33 @@ int pthread_setcanceltype(int type, int * oldtype)
     __pthread_do_exit(PTHREAD_CANCELED, CURRENT_STACK_FRAME);
   return 0;
 }
+strong_alias (__pthread_setcanceltype, pthread_setcanceltype);
+
+
+/* The next two functions are similar to pthread_setcanceltype() but
+   more specialized for the use in the cancelable functions like write().
+   They do not need to check parameters etc.  */
+int
+attribute_hidden
+__pthread_enable_asynccancel (void)
+{
+  pthread_descr self = thread_self();
+  int oldtype = THREAD_GETMEM(self, p_canceltype);
+  THREAD_SETMEM(self, p_canceltype, PTHREAD_CANCEL_ASYNCHRONOUS);
+  if (__builtin_expect (THREAD_GETMEM(self, p_canceled), 0) &&
+      THREAD_GETMEM(self, p_cancelstate) == PTHREAD_CANCEL_ENABLE)
+    __pthread_do_exit(PTHREAD_CANCELED, CURRENT_STACK_FRAME);
+  return oldtype;
+}
+
+void
+internal_function attribute_hidden
+__pthread_disable_asynccancel (int oldtype)
+{
+  pthread_descr self = thread_self();
+  THREAD_SETMEM(self, p_canceltype, oldtype);
+}
+
 
 int pthread_cancel(pthread_t thread)
 {
@@ -210,14 +238,3 @@ void __pthread_perform_cleanup(char *currentframe)
     __rpc_thread_destroy ();
 #endif
 }
-
-#ifndef SHARED
-/* We need a hook to force the cancelation wrappers and file locking
-   to be linked in when static libpthread is used.  */
-extern const int __pthread_provide_wrappers;
-static const int *const __pthread_require_wrappers =
-  &__pthread_provide_wrappers;
-extern const int __pthread_provide_lockfile;
-static const int *const __pthread_require_lockfile =
-  &__pthread_provide_lockfile;
-#endif
diff --git a/linuxthreads/condvar.c b/linuxthreads/condvar.c
index fd0db50fa2..a40ae49fab 100644
--- a/linuxthreads/condvar.c
+++ b/linuxthreads/condvar.c
@@ -25,19 +25,21 @@
 #include "queue.h"
 #include "restart.h"
 
-int pthread_cond_init(pthread_cond_t *cond,
-                      const pthread_condattr_t *cond_attr)
+int __pthread_cond_init(pthread_cond_t *cond,
+                        const pthread_condattr_t *cond_attr)
 {
   __pthread_init_lock(&cond->__c_lock);
   cond->__c_waiting = NULL;
   return 0;
 }
+strong_alias (__pthread_cond_init, pthread_cond_init)
 
-int pthread_cond_destroy(pthread_cond_t *cond)
+int __pthread_cond_destroy(pthread_cond_t *cond)
 {
   if (cond->__c_waiting != NULL) return EBUSY;
   return 0;
 }
+strong_alias (__pthread_cond_destroy, pthread_cond_destroy)
 
 /* Function called by pthread_cancel to remove the thread from
    waiting on a condition variable queue. */
@@ -55,7 +57,7 @@ static int cond_extricate_func(void *obj, pthread_descr th)
   return did_remove;
 }
 
-int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
+int __pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
 {
   volatile pthread_descr self = thread_self();
   pthread_extricate_if extr;
@@ -132,6 +134,7 @@ int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
   pthread_mutex_lock(mutex);
   return 0;
 }
+strong_alias (__pthread_cond_wait, pthread_cond_wait)
 
 static int
 pthread_cond_timedwait_relative(pthread_cond_t *cond,
@@ -234,7 +237,7 @@ int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
   return pthread_cond_timedwait_relative(cond, mutex, abstime);
 }
 
-int pthread_cond_signal(pthread_cond_t *cond)
+int __pthread_cond_signal(pthread_cond_t *cond)
 {
   pthread_descr th;
 
@@ -248,8 +251,9 @@ int pthread_cond_signal(pthread_cond_t *cond)
   }
   return 0;
 }
+strong_alias (__pthread_cond_signal, pthread_cond_signal)
 
-int pthread_cond_broadcast(pthread_cond_t *cond)
+int __pthread_cond_broadcast(pthread_cond_t *cond)
 {
   pthread_descr tosignal, th;
 
@@ -266,16 +270,19 @@ int pthread_cond_broadcast(pthread_cond_t *cond)
   }
   return 0;
 }
+strong_alias (__pthread_cond_broadcast, pthread_cond_broadcast)
 
-int pthread_condattr_init(pthread_condattr_t *attr)
+int __pthread_condattr_init(pthread_condattr_t *attr)
 {
   return 0;
 }
+strong_alias (__pthread_condattr_init, pthread_condattr_init)
 
-int pthread_condattr_destroy(pthread_condattr_t *attr)
+int __pthread_condattr_destroy(pthread_condattr_t *attr)
 {
   return 0;
 }
+strong_alias (__pthread_condattr_destroy, pthread_condattr_destroy)
 
 int pthread_condattr_getpshared (const pthread_condattr_t *attr, int *pshared)
 {
diff --git a/linuxthreads/descr.h b/linuxthreads/descr.h
index 1e14823d83..94ad893979 100644
--- a/linuxthreads/descr.h
+++ b/linuxthreads/descr.h
@@ -106,6 +106,7 @@ struct _pthread_descr_struct {
 				   the address of this thread descriptor.  */
       union dtv *dtvp;
       pthread_descr self;	/* Pointer to this structure */
+      int multiple_threads;
     } data;
     void *__padding[16];
   } p_header;
diff --git a/linuxthreads/forward.c b/linuxthreads/forward.c
new file mode 100644
index 0000000000..499930ab26
--- /dev/null
+++ b/linuxthreads/forward.c
@@ -0,0 +1,146 @@
+/* Copyright (C) 2002 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <dlfcn.h>
+#include "internals.h"
+#include <stdlib.h>
+
+#include <shlib-compat.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)
+# define FORWARD4(name, export, rettype, decl, params, defaction, version) \
+rettype									      \
+__noexport_##name decl							      \
+{									      \
+  if (__libc_pthread_functions.ptr_##name == NULL)			      \
+    defaction;								      \
+									      \
+  return __libc_pthread_functions.ptr_##name params;			      \
+}									      \
+compat_symbol (libc, __noexport_##name, export, version)
+
+# define FORWARD3(name, rettype, decl, params, defaction, version) \
+  FORWARD4 (name, name, rettype, decl, params, defaction, version)
+
+# define FORWARD2(name, decl, params, defretval, version) \
+  FORWARD3 (name, int, decl, params, return defretval, version)
+
+# define FORWARD(name, decl, params, defretval) \
+  FORWARD2 (name, decl, params, defretval, GLIBC_2_0)
+
+
+FORWARD (pthread_attr_destroy, (pthread_attr_t *attr), (attr), 0);
+
+#if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_1)
+FORWARD4 (pthread_attr_init_2_0, pthread_attr_init, int,
+	  (pthread_attr_t *attr), (attr), 0, GLIBC_2_0);
+#endif
+
+FORWARD4 (pthread_attr_init_2_1, pthread_attr_init, int,
+	  (pthread_attr_t *attr), (attr), 0, GLIBC_2_1);
+
+FORWARD (pthread_attr_getdetachstate,
+	 (const pthread_attr_t *attr, int *detachstate), (attr, detachstate),
+	 0);
+FORWARD (pthread_attr_setdetachstate, (pthread_attr_t *attr, int detachstate),
+	 (attr, detachstate), 0);
+
+FORWARD (pthread_attr_getinheritsched,
+	 (const pthread_attr_t *attr, int *inherit), (attr, inherit), 0);
+FORWARD (pthread_attr_setinheritsched, (pthread_attr_t *attr, int inherit),
+	 (attr, inherit), 0);
+
+FORWARD (pthread_attr_getschedparam,
+	 (const pthread_attr_t *attr, struct sched_param *param),
+	 (attr, param), 0);
+FORWARD (pthread_attr_setschedparam,
+	 (pthread_attr_t *attr, const struct sched_param *param),
+	 (attr, param), 0);
+
+FORWARD (pthread_attr_getschedpolicy,
+	 (const pthread_attr_t *attr, int *policy), (attr, policy), 0);
+FORWARD (pthread_attr_setschedpolicy, (pthread_attr_t *attr, int policy),
+	 (attr, policy), 0);
+
+FORWARD (pthread_attr_getscope,
+	 (const pthread_attr_t *attr, int *scope), (attr, scope), 0);
+FORWARD (pthread_attr_setscope, (pthread_attr_t *attr, int scope),
+	 (attr, scope), 0);
+
+
+FORWARD (pthread_condattr_destroy, (pthread_condattr_t *attr), (attr), 0);
+FORWARD (pthread_condattr_init, (pthread_condattr_t *attr), (attr), 0);
+
+
+FORWARD (pthread_cond_broadcast, (pthread_cond_t *cond), (cond), 0);
+
+FORWARD (pthread_cond_destroy, (pthread_cond_t *cond), (cond), 0);
+
+FORWARD (pthread_cond_init,
+	 (pthread_cond_t *cond, const pthread_condattr_t *cond_attr),
+	 (cond, cond_attr), 0);
+
+FORWARD (pthread_cond_signal, (pthread_cond_t *cond), (cond), 0);
+
+FORWARD (pthread_cond_wait, (pthread_cond_t *cond, pthread_mutex_t *mutex),
+	 (cond, mutex), 0);
+
+
+FORWARD (pthread_equal, (pthread_t thread1, pthread_t thread2),
+	 (thread1, thread2), 1);
+
+
+FORWARD3 (pthread_exit, void, (void *retval), (retval), exit (EXIT_SUCCESS),
+	  GLIBC_2_0);
+
+
+FORWARD (pthread_getschedparam,
+	 (pthread_t target_thread, int *policy, struct sched_param *param),
+	 (target_thread, policy, param), 0);
+FORWARD (pthread_setschedparam,
+	 (pthread_t target_thread, int policy,
+	  const struct sched_param *param), (target_thread, policy, param), 0);
+
+
+FORWARD (pthread_mutex_destroy, (pthread_mutex_t *mutex), (mutex), 0);
+
+FORWARD (pthread_mutex_init,
+	 (pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr),
+	 (mutex, mutexattr), 0);
+
+FORWARD (pthread_mutex_lock, (pthread_mutex_t *mutex), (mutex), 0);
+
+FORWARD (pthread_mutex_unlock, (pthread_mutex_t *mutex), (mutex), 0);
+
+
+FORWARD3 (pthread_self, pthread_t, (void), (), return 0, GLIBC_2_0);
+
+
+FORWARD (pthread_setcancelstate, (int state, int *oldstate), (state, oldstate),
+	 0);
+
+FORWARD (pthread_setcanceltype, (int type, int *oldtype), (type, oldtype), 0);
+
+
+#endif
diff --git a/linuxthreads/internals.h b/linuxthreads/internals.h
index 58a60fffc2..3e10304c2f 100644
--- a/linuxthreads/internals.h
+++ b/linuxthreads/internals.h
@@ -245,6 +245,9 @@ static inline int nonexisting_handle(pthread_handle h, pthread_t id)
 #define SPIN_SLEEP_DURATION 2000001
 #endif
 
+/* Defined and used in libc.so.  */
+extern int __libc_multiple_threads attribute_hidden;
+
 /* Debugging */
 
 #ifdef DEBUG
@@ -294,6 +297,24 @@ extern int __pthread_attr_setstack (pthread_attr_t *__attr, void *__stackaddr,
 				    size_t __stacksize);
 extern int __pthread_attr_getstack (const pthread_attr_t *__attr, void **__stackaddr,
 				    size_t *__stacksize);
+extern int __pthread_attr_destroy (pthread_attr_t *attr);
+extern int __pthread_attr_setdetachstate (pthread_attr_t *attr,
+					  int detachstate);
+extern int __pthread_attr_getdetachstate (const pthread_attr_t *attr,
+					  int *detachstate);
+extern int __pthread_attr_setschedparam (pthread_attr_t *attr,
+					 const struct sched_param *param);
+extern int __pthread_attr_getschedparam (const pthread_attr_t *attr,
+					 struct sched_param *param);
+extern int __pthread_attr_setschedpolicy (pthread_attr_t *attr, int policy);
+extern int __pthread_attr_getschedpolicy (const pthread_attr_t *attr,
+					  int *policy);
+extern int __pthread_attr_setinheritsched (pthread_attr_t *attr, int inherit);
+extern int __pthread_attr_getinheritsched (const pthread_attr_t *attr,
+					   int *inherit);
+extern int __pthread_attr_setscope (pthread_attr_t *attr, int scope);
+extern int __pthread_attr_getscope (const pthread_attr_t *attr, int *scope);
+
 extern int __pthread_getconcurrency (void);
 extern int __pthread_setconcurrency (int __level);
 extern int __pthread_mutex_timedlock (pthread_mutex_t *__mutex,
@@ -305,6 +326,37 @@ extern int __pthread_mutexattr_setpshared (pthread_mutexattr_t *__attr,
 extern int __pthread_mutexattr_gettype (const pthread_mutexattr_t *__attr,
 					int *__kind);
 extern void __pthread_kill_other_threads_np (void);
+extern int __pthread_mutex_init (pthread_mutex_t *__mutex,
+				 __const pthread_mutexattr_t *__mutex_attr);
+extern int __pthread_mutex_destroy (pthread_mutex_t *__mutex);
+extern int __pthread_mutex_lock (pthread_mutex_t *__mutex);
+extern int __pthread_mutex_trylock (pthread_mutex_t *__mutex);
+extern int __pthread_mutex_unlock (pthread_mutex_t *__mutex);
+#if defined NOT_IN_libc && defined IS_IN_libpthread
+hidden_proto (__pthread_mutex_init)
+hidden_proto (__pthread_mutex_destroy)
+hidden_proto (__pthread_mutex_lock)
+hidden_proto (__pthread_mutex_trylock)
+hidden_proto (__pthread_mutex_unlock)
+#endif
+extern int __pthread_cond_init (pthread_cond_t *cond,
+				const pthread_condattr_t *cond_attr);
+extern int __pthread_cond_destroy (pthread_cond_t *cond);
+extern int __pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex);
+extern int __pthread_cond_signal (pthread_cond_t *cond);
+extern int __pthread_cond_broadcast (pthread_cond_t *cond);
+extern int __pthread_condattr_init (pthread_condattr_t *attr);
+extern int __pthread_condattr_destroy (pthread_condattr_t *attr);
+extern pthread_t __pthread_self (void);
+extern pthread_descr __pthread_thread_self (void);
+extern int __pthread_equal (pthread_t thread1, pthread_t thread2);
+extern void __pthread_exit (void *retval);
+extern int __pthread_getschedparam (pthread_t thread, int *policy,
+				    struct sched_param *param);
+extern int __pthread_setschedparam (pthread_t thread, int policy,
+				    const struct sched_param *param);
+extern int __pthread_setcancelstate (int state, int * oldstate);
+extern int __pthread_setcanceltype (int type, int * oldtype);
 
 extern void __pthread_restart_old(pthread_descr th);
 extern void __pthread_suspend_old(pthread_descr self);
@@ -339,7 +391,6 @@ extern int __pthread_spin_destroy (pthread_spinlock_t *__lock);
 extern int __pthread_clock_gettime (hp_timing_t freq, struct timespec *tp);
 extern void __pthread_clock_settime (hp_timing_t offset);
 
-
 /* Global pointers to old or new suspend functions */
 
 extern void (*__pthread_restart)(pthread_descr);
@@ -386,4 +437,77 @@ extern void __pthread_sighandler_rt(int signo, struct siginfo *si,
 				    struct ucontext *uc);
 extern void __pthread_null_sighandler(int sig);
 
+/* Cancellation.  */
+extern int __pthread_enable_asynccancel (void) attribute_hidden;
+extern void __pthread_disable_asynccancel (int oldtype)
+  internal_function attribute_hidden;
+
+/* The two functions are in libc.so and not exported.  */
+extern int __libc_enable_asynccancel (void) attribute_hidden;
+extern void __libc_disable_asynccancel (int oldtype)
+  internal_function attribute_hidden;
+
+#if !defined NOT_IN_libc
+# define LIBC_CANCEL_ASYNC() \
+  __libc_enable_asynccancel ()
+# define LIBC_CANCEL_RESET(oldtype) \
+  __libc_disable_asynccancel (oldtype)
+#elif defined NOT_IN_libc && defined IS_IN_libpthread
+# define LIBC_CANCEL_ASYNC() \
+  __pthread_enable_asynccancel ()
+# define LIBC_CANCEL_RESET(oldtype) \
+  __pthread_disable_asynccancel (oldtype)
+#else
+# define LIBC_CANCEL_ASYNC()    0 /* Just a dummy value.  */
+# define LIBC_CANCEL_RESET(val) ((void)(val)) /* Nothing, but evaluate it.  */
+#endif
+
+/* 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_2_0) (pthread_attr_t *);
+  int (*ptr_pthread_attr_init_2_1) (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_trylock) (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 *);
+  void (*ptr_pthread_do_exit) (void *retval, char *currentframe);
+  pthread_descr (*ptr_pthread_thread_self) (void);
+};
+
+/* Variable in libc.so.  */
+extern struct pthread_functions __libc_pthread_functions attribute_hidden;
+extern int * __libc_pthread_init (const struct pthread_functions *functions);
+
 #endif /* internals.h */
diff --git a/linuxthreads/join.c b/linuxthreads/join.c
index a6ed08c97a..3d204296fc 100644
--- a/linuxthreads/join.c
+++ b/linuxthreads/join.c
@@ -23,10 +23,11 @@
 #include "spinlock.h"
 #include "restart.h"
 
-void pthread_exit(void * retval)
+void __pthread_exit(void * retval)
 {
   __pthread_do_exit (retval, CURRENT_STACK_FRAME);
 }
+strong_alias (__pthread_exit, pthread_exit);
 
 void __pthread_do_exit(void *retval, char *currentframe)
 {
diff --git a/linuxthreads/libc-cancellation.c b/linuxthreads/libc-cancellation.c
new file mode 100644
index 0000000000..4d38d4222d
--- /dev/null
+++ b/linuxthreads/libc-cancellation.c
@@ -0,0 +1,75 @@
+/* Copyright (C) 2002 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Jakub Jelinek <jakub@redhat.com>, 2002.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <errno.h>
+#include <rpc/rpc.h>
+#include "pthread.h"
+#include "internals.h"
+#include "spinlock.h"
+#include "restart.h"
+#include <bits/libc-lock.h>
+
+#if !defined NOT_IN_libc
+
+# ifndef SHARED
+weak_extern (__pthread_do_exit)
+weak_extern (__pthread_thread_self)
+# endif
+
+int __libc_multiple_threads attribute_hidden;
+
+/* The next two functions are similar to pthread_setcanceltype() but
+   more specialized for the use in the cancelable functions like write().
+   They do not need to check parameters etc.  */
+int
+attribute_hidden
+__libc_enable_asynccancel (void)
+{
+#ifdef FLOATING_STACKS
+  pthread_descr self = thread_self();
+#else
+  pthread_descr self = __libc_maybe_call2 (pthread_thread_self, (), NULL);
+
+  if (self == NULL)
+    return PTHREAD_CANCEL_DEFERRED;
+#endif
+  int oldtype = THREAD_GETMEM(self, p_canceltype);
+  THREAD_SETMEM(self, p_canceltype, PTHREAD_CANCEL_ASYNCHRONOUS);
+  if (__builtin_expect (THREAD_GETMEM(self, p_canceled), 0) &&
+      THREAD_GETMEM(self, p_cancelstate) == PTHREAD_CANCEL_ENABLE)
+    __libc_maybe_call2 (pthread_do_exit,
+			(PTHREAD_CANCELED, CURRENT_STACK_FRAME), 0);
+  return oldtype;
+}
+
+void
+internal_function attribute_hidden
+__libc_disable_asynccancel (int oldtype)
+{
+#ifdef FLOATING_STACKS
+  pthread_descr self = thread_self();
+#else
+  pthread_descr self = __libc_maybe_call2 (pthread_thread_self, (), NULL);
+
+  if (self != NULL)
+#endif
+    THREAD_SETMEM(self, p_canceltype, oldtype);
+}
+
+#endif
diff --git a/linuxthreads/libc_pthread_init.c b/linuxthreads/libc_pthread_init.c
new file mode 100644
index 0000000000..901d333fbf
--- /dev/null
+++ b/linuxthreads/libc_pthread_init.c
@@ -0,0 +1,53 @@
+/* Copyright (C) 2002 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Jakub Jelinek <jakub@redhat.com>, 2002.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <string.h>
+#include <tls.h>
+#include <locale.h>
+#include "internals.h"
+#include <sysdep-cancel.h>
+
+int *
+__libc_pthread_init (functions)
+     const struct pthread_functions *functions;
+{
+#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
+
+#ifdef MULTIPLE_THREADS_OFFSET
+  /* 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_descr_struct, p_header.data.multiple_threads)
+      != MULTIPLE_THREADS_OFFSET)
+    abort ();
+#endif
+
+#if !(USE_TLS && HAVE___THREAD)
+  /* Initialize thread-locale current locale to point to the global one.
+     With __thread support, the variable's initializer takes care of this.  */
+  __uselocale (LC_GLOBAL_LOCALE);
+#endif
+
+  return &__libc_multiple_threads;
+}
diff --git a/linuxthreads/lockfile.c b/linuxthreads/lockfile.c
index 0e27324034..34055e4115 100644
--- a/linuxthreads/lockfile.c
+++ b/linuxthreads/lockfile.c
@@ -21,80 +21,51 @@
 #include <stdio.h>
 #include <pthread.h>
 #include "internals.h"
-
-#ifdef USE_IN_LIBIO
 #include "../libio/libioP.h"
-#endif
-
-#ifndef SHARED
-/* We need a hook to force this file to be linked in when static
-   libpthread is used.  */
-const int __pthread_provide_lockfile = 0;
-#endif
 
 void
 __flockfile (FILE *stream)
 {
-#ifdef USE_IN_LIBIO
   __pthread_mutex_lock (stream->_lock);
-#else
-#endif
 }
-#ifdef USE_IN_LIBIO
 #undef _IO_flockfile
 strong_alias (__flockfile, _IO_flockfile)
-#endif
 weak_alias (__flockfile, flockfile);
 
 
 void
 __funlockfile (FILE *stream)
 {
-#ifdef USE_IN_LIBIO
   __pthread_mutex_unlock (stream->_lock);
-#else
-#endif
 }
-#ifdef USE_IN_LIBIO
 #undef _IO_funlockfile
 strong_alias (__funlockfile, _IO_funlockfile)
-#endif
 weak_alias (__funlockfile, funlockfile);
 
 
 int
 __ftrylockfile (FILE *stream)
 {
-#ifdef USE_IN_LIBIO
   return __pthread_mutex_trylock (stream->_lock);
-#else
-#endif
 }
-#ifdef USE_IN_LIBIO
 strong_alias (__ftrylockfile, _IO_ftrylockfile)
-#endif
 weak_alias (__ftrylockfile, ftrylockfile);
 
 void
 __flockfilelist(void)
 {
-#ifdef USE_IN_LIBIO
   _IO_list_lock();
-#endif
 }
 
 void
 __funlockfilelist(void)
 {
-#ifdef USE_IN_LIBIO
   _IO_list_unlock();
-#endif
 }
 
 void
 __fresetlockfiles (void)
 {
-#ifdef USE_IN_LIBIO
   _IO_ITER i;
 
   pthread_mutexattr_t attr;
@@ -108,5 +79,4 @@ __fresetlockfiles (void)
   __pthread_mutexattr_destroy (&attr);
 
   _IO_list_resetlock();
-#endif
 }
diff --git a/linuxthreads/manager.c b/linuxthreads/manager.c
index 1d21760cf9..3268ea8a41 100644
--- a/linuxthreads/manager.c
+++ b/linuxthreads/manager.c
@@ -633,6 +633,7 @@ static int pthread_handle_create(pthread_t *thread, const pthread_attr_t *attr,
      initialized to zero already have this value.  */
   new_thread->p_header.data.tcb = new_thread;
   new_thread->p_header.data.self = new_thread;
+  new_thread->p_header.data.multiple_threads = 1;
   new_thread->p_tid = new_thread_id;
   new_thread->p_lock = &(__pthread_handles[sseg].h_lock);
   new_thread->p_cancelstate = PTHREAD_CANCEL_ENABLE;
diff --git a/linuxthreads/mutex.c b/linuxthreads/mutex.c
index 3c97ea7d66..d5f7a335cc 100644
--- a/linuxthreads/mutex.c
+++ b/linuxthreads/mutex.c
@@ -36,6 +36,7 @@ int __pthread_mutex_init(pthread_mutex_t * mutex,
   return 0;
 }
 strong_alias (__pthread_mutex_init, pthread_mutex_init)
+hidden_def (__pthread_mutex_init)
 
 int __pthread_mutex_destroy(pthread_mutex_t * mutex)
 {
@@ -55,6 +56,7 @@ int __pthread_mutex_destroy(pthread_mutex_t * mutex)
   }
 }
 strong_alias (__pthread_mutex_destroy, pthread_mutex_destroy)
+hidden_def (__pthread_mutex_destroy)
 
 int __pthread_mutex_trylock(pthread_mutex_t * mutex)
 {
@@ -91,6 +93,7 @@ int __pthread_mutex_trylock(pthread_mutex_t * mutex)
   }
 }
 strong_alias (__pthread_mutex_trylock, pthread_mutex_trylock)
+hidden_def (__pthread_mutex_trylock)
 
 int __pthread_mutex_lock(pthread_mutex_t * mutex)
 {
@@ -124,6 +127,7 @@ int __pthread_mutex_lock(pthread_mutex_t * mutex)
   }
 }
 strong_alias (__pthread_mutex_lock, pthread_mutex_lock)
+hidden_def (__pthread_mutex_lock)
 
 int __pthread_mutex_timedlock (pthread_mutex_t *mutex,
 			       const struct timespec *abstime)
@@ -199,6 +203,7 @@ int __pthread_mutex_unlock(pthread_mutex_t * mutex)
   }
 }
 strong_alias (__pthread_mutex_unlock, pthread_mutex_unlock)
+hidden_def (__pthread_mutex_unlock)
 
 int __pthread_mutexattr_init(pthread_mutexattr_t *attr)
 {
diff --git a/linuxthreads/pt-allocrtsig.c b/linuxthreads/pt-allocrtsig.c
new file mode 100644
index 0000000000..3598dbb49f
--- /dev/null
+++ b/linuxthreads/pt-allocrtsig.c
@@ -0,0 +1,50 @@
+/* Copyright (C) 2002 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <signal.h>
+
+
+/* These are defined in libc.  We want to have only one definition
+   so we "forward" the calls.  */
+extern int __libc_current_sigrtmin_private (void);
+extern int __libc_current_sigrtmax_private (void);
+extern int __libc_allocate_rtsig_private (int high);
+
+
+/* We reserve __SIGRTMIN for use as the cancelation signal.  This
+   signal is used internally.  */
+int
+__libc_current_sigrtmin (void)
+{
+  return __libc_current_sigrtmin_private ();
+}
+
+
+int
+__libc_current_sigrtmax (void)
+{
+  return __libc_current_sigrtmax_private ();
+}
+
+
+int
+__libc_allocate_rtsig (int high)
+{
+  return __libc_allocate_rtsig_private (high);
+}
diff --git a/linuxthreads/pt-system.c b/linuxthreads/pt-system.c
new file mode 100644
index 0000000000..bc5098adc0
--- /dev/null
+++ b/linuxthreads/pt-system.c
@@ -0,0 +1,32 @@
+/* Copyright (C) 2002 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Jakub Jelinek <jakub@redhat.com>, 2002.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <errno.h>
+#include <stdlib.h>
+#include <sysdep-cancel.h>
+
+
+int
+system (const char *line)
+{
+  int oldtype = LIBC_CANCEL_ASYNC ();
+  int result = __libc_system (line);
+  LIBC_CANCEL_RESET (oldtype);
+  return result;
+}
diff --git a/linuxthreads/pthread.c b/linuxthreads/pthread.c
index 8216985972..7fc5ef6ff4 100644
--- a/linuxthreads/pthread.c
+++ b/linuxthreads/pthread.c
@@ -33,12 +33,11 @@
 #include "smp.h"
 #include <ldsodefs.h>
 #include <tls.h>
-#include <locale.h>		/* for __uselocale */
 #include <version.h>
 
 /* Sanity check.  */
-#if __ASSUME_REALTIME_SIGNALS && !defined __SIGRTMIN
-# error "This must not happen; new kernel assumed but old headers"
+#if !defined __SIGRTMIN || (__SIGRTMAX - __SIGRTMIN) < 3
+# error "This must not happen"
 #endif
 
 #if !(USE_TLS && HAVE___THREAD)
@@ -86,6 +85,7 @@ struct _pthread_descr_struct __pthread_initial_thread = {
 #define manager_thread (&__pthread_manager_thread)
 struct _pthread_descr_struct __pthread_manager_thread = {
   .p_header.data.self = &__pthread_manager_thread,
+  .p_header.data.multiple_threads = 1,
   .p_lock = &__pthread_handles[1].h_lock,
   .p_start_args = PTHREAD_START_ARGS_INITIALIZER(__pthread_manager),
 #if !(USE_TLS && HAVE___THREAD)
@@ -116,6 +116,8 @@ char *__pthread_initial_thread_bos;
 
 int __pthread_manager_request = -1;
 
+int __pthread_multiple_threads attribute_hidden;
+
 /* Other end of the pipe for sending requests to the thread manager. */
 
 int __pthread_manager_reader;
@@ -177,109 +179,38 @@ static void pthread_handle_sigdebug(int sig);
    platform does not support any real-time signals we will define the
    values to some unreasonable value which will signal failing of all
    the functions below.  */
-#ifndef __SIGRTMIN
-static int current_rtmin = -1;
-static int current_rtmax = -1;
-int __pthread_sig_restart = SIGUSR1;
-int __pthread_sig_cancel = SIGUSR2;
-int __pthread_sig_debug;
-#else
-static int current_rtmin;
-static int current_rtmax;
-
-#if __SIGRTMAX - __SIGRTMIN >= 3
 int __pthread_sig_restart = __SIGRTMIN;
 int __pthread_sig_cancel = __SIGRTMIN + 1;
 int __pthread_sig_debug = __SIGRTMIN + 2;
-#else
-int __pthread_sig_restart = SIGUSR1;
-int __pthread_sig_cancel = SIGUSR2;
-int __pthread_sig_debug;
-#endif
 
-static int rtsigs_initialized;
+extern int __libc_current_sigrtmin_private (void);
 
 #if !__ASSUME_REALTIME_SIGNALS
-# include "testrtsig.h"
-#endif
+static int rtsigs_initialized;
 
 static void
 init_rtsigs (void)
 {
-#if !__ASSUME_REALTIME_SIGNALS
-  if (__builtin_expect (!kernel_has_rtsig (), 0))
+  if (rtsigs_initialized)
+    return;
+
+  if (__builtin_expect (__libc_current_sigrtmin_private () == -1))
     {
-      current_rtmin = -1;
-      current_rtmax = -1;
-# if __SIGRTMAX - __SIGRTMIN >= 3
       __pthread_sig_restart = SIGUSR1;
       __pthread_sig_cancel = SIGUSR2;
       __pthread_sig_debug = 0;
-# endif
     }
   else
-#endif	/* __ASSUME_REALTIME_SIGNALS */
     {
-#if __SIGRTMAX - __SIGRTMIN >= 3
-      current_rtmin = __SIGRTMIN + 3;
-# if !__ASSUME_REALTIME_SIGNALS
       __pthread_restart = __pthread_restart_new;
       __pthread_suspend = __pthread_wait_for_restart_signal;
       __pthread_timedsuspend = __pthread_timedsuspend_new;
-# endif /* __ASSUME_REALTIME_SIGNALS */
-#else
-      current_rtmin = __SIGRTMIN;
-#endif
-
-      current_rtmax = __SIGRTMAX;
     }
 
   rtsigs_initialized = 1;
 }
 #endif
 
-/* Return number of available real-time signal with highest priority.  */
-int
-__libc_current_sigrtmin (void)
-{
-#ifdef __SIGRTMIN
-  if (__builtin_expect (!rtsigs_initialized, 0))
-    init_rtsigs ();
-#endif
-  return current_rtmin;
-}
-
-/* Return number of available real-time signal with lowest priority.  */
-int
-__libc_current_sigrtmax (void)
-{
-#ifdef __SIGRTMIN
-  if (__builtin_expect (!rtsigs_initialized, 0))
-    init_rtsigs ();
-#endif
-  return current_rtmax;
-}
-
-/* Allocate real-time signal with highest/lowest available
-   priority.  Please note that we don't use a lock since we assume
-   this function to be called at program start.  */
-int
-__libc_allocate_rtsig (int high)
-{
-#ifndef __SIGRTMIN
-  return -1;
-#else
-  if (__builtin_expect (!rtsigs_initialized, 0))
-    init_rtsigs ();
-  if (__builtin_expect (current_rtmin == -1, 0)
-      || __builtin_expect (current_rtmin > current_rtmax, 0))
-    /* We don't have anymore signal available.  */
-    return -1;
-
-  return high ? current_rtmin++ : current_rtmax--;
-#endif
-}
-
 
 /* Initialize the pthread library.
    Initialization is split in two functions:
@@ -299,6 +230,52 @@ extern void *__dso_handle __attribute__ ((weak));
 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,
+#if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_1)
+    .ptr_pthread_attr_init_2_0 = __pthread_attr_init_2_0,
+#endif
+    .ptr_pthread_attr_init_2_1 = __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 = __pthread_mutex_destroy,
+    .ptr_pthread_mutex_init = __pthread_mutex_init,
+    .ptr_pthread_mutex_lock = __pthread_mutex_lock,
+    .ptr_pthread_mutex_trylock = __pthread_mutex_trylock,
+    .ptr_pthread_mutex_unlock = __pthread_mutex_unlock,
+    .ptr_pthread_self = __pthread_self,
+    .ptr_pthread_setcancelstate = __pthread_setcancelstate,
+    .ptr_pthread_setcanceltype = __pthread_setcanceltype,
+    .ptr_pthread_do_exit = __pthread_do_exit,
+    .ptr_pthread_thread_self = __pthread_thread_self
+  };
+# define ptr_pthread_functions &pthread_functions
+#else
+# define ptr_pthread_functions NULL
+#endif
+
+static int *__libc_multiple_threads_ptr;
 
 /* Do some minimal initialization which has to be done during the
    startup of the C library.  */
@@ -413,11 +390,7 @@ cannot allocate TLS data structures for initial thread\n";
 # endif
 #endif
 
-#if !(USE_TLS && HAVE___THREAD)
-  /* Initialize thread-locale current locale to point to the global one.
-     With __thread support, the variable's initializer takes care of this.  */
-  __uselocale (LC_GLOBAL_LOCALE);
-#endif
+  __libc_multiple_threads_ptr = __libc_pthread_init (ptr_pthread_functions);
 }
 
 
@@ -520,7 +493,7 @@ static void pthread_initialize(void)
   /* Likewise for the resolver state _res.  */
   __pthread_initial_thread.p_resp = &_res;
 #endif
-#ifdef __SIGRTMIN
+#if !__ASSUME_REALTIME_SIGNALS
   /* Initialize real-time signals. */
   init_rtsigs ();
 #endif
@@ -577,6 +550,15 @@ int __pthread_initialize_manager(void)
   int report_events;
   pthread_descr tcb;
 
+  __pthread_multiple_threads = 1;
+  __pthread_main_thread->p_header.data.multiple_threads = 1;
+  * __libc_multiple_threads_ptr = 1;
+#ifdef MULTIPLE_THREADS_OFFSET
+  if (offsetof(struct _pthread_descr_struct, p_header.data.multiple_threads)
+      != MULTIPLE_THREADS_OFFSET)
+    abort ();
+#endif
+
 #ifndef HAVE_Z_NODELETE
   if (__builtin_expect (&__dso_handle != NULL, 1))
     __cxa_atexit ((void (*) (void *)) pthread_atexit_retcode, NULL,
@@ -613,6 +595,7 @@ int __pthread_initialize_manager(void)
   /* Initialize the descriptor.  */
   tcb->p_header.data.tcb = tcb;
   tcb->p_header.data.self = tcb;
+  tcb->p_header.data.multiple_threads = 1;
   tcb->p_lock = &__pthread_handles[1].h_lock;
 # ifndef HAVE___THREAD
   tcb->p_errnop = &tcb->p_errno;
@@ -797,16 +780,23 @@ compat_symbol (libpthread, __pthread_create_2_0, pthread_create, GLIBC_2_0);
 
 /* Simple operations on thread identifiers */
 
-pthread_t pthread_self(void)
+pthread_descr __pthread_thread_self(void)
+{
+  return thread_self();
+}
+
+pthread_t __pthread_self(void)
 {
   pthread_descr self = thread_self();
   return THREAD_GETMEM(self, p_tid);
 }
+strong_alias (__pthread_self, pthread_self);
 
-int pthread_equal(pthread_t thread1, pthread_t thread2)
+int __pthread_equal(pthread_t thread1, pthread_t thread2)
 {
   return thread1 == thread2;
 }
+strong_alias (__pthread_equal, pthread_equal);
 
 /* Helper function for thread_self in the case of user-provided stacks */
 
@@ -849,8 +839,8 @@ static pthread_descr thread_self_stack(void)
 
 /* Thread scheduling */
 
-int pthread_setschedparam(pthread_t thread, int policy,
-                          const struct sched_param *param)
+int __pthread_setschedparam(pthread_t thread, int policy,
+                            const struct sched_param *param)
 {
   pthread_handle handle = thread_handle(thread);
   pthread_descr th;
@@ -872,9 +862,10 @@ int pthread_setschedparam(pthread_t thread, int policy,
     __pthread_manager_adjust_prio(th->p_priority);
   return 0;
 }
+strong_alias (__pthread_setschedparam, pthread_setschedparam);
 
-int pthread_getschedparam(pthread_t thread, int *policy,
-                          struct sched_param *param)
+int __pthread_getschedparam(pthread_t thread, int *policy,
+                            struct sched_param *param)
 {
   pthread_handle handle = thread_handle(thread);
   int pid, pol;
@@ -892,6 +883,7 @@ int pthread_getschedparam(pthread_t thread, int *policy,
   *policy = pol;
   return 0;
 }
+strong_alias (__pthread_getschedparam, pthread_getschedparam);
 
 int __pthread_yield (void)
 {
@@ -1319,15 +1311,3 @@ void __pthread_message(const char * fmt, ...)
 }
 
 #endif
-
-
-#ifndef SHARED
-/* We need a hook to force the cancelation wrappers and file locking
-   to be linked in when static libpthread is used.  */
-extern const int __pthread_provide_wrappers;
-static const int *const __pthread_require_wrappers =
-  &__pthread_provide_wrappers;
-extern const int __pthread_provide_lockfile;
-static const int *const __pthread_require_lockfile =
-  &__pthread_provide_lockfile;
-#endif
diff --git a/linuxthreads/sysdeps/pthread/bits/libc-lock.h b/linuxthreads/sysdeps/pthread/bits/libc-lock.h
index ceb08b6238..217b0be253 100644
--- a/linuxthreads/sysdeps/pthread/bits/libc-lock.h
+++ b/linuxthreads/sysdeps/pthread/bits/libc-lock.h
@@ -23,6 +23,10 @@
 
 #include <pthread.h>
 
+#if defined _LIBC && !defined NOT_IN_libc
+#include <linuxthreads/internals.h>
+#endif
+
 /* Mutex type.  */
 #if defined(_LIBC) || defined(_IO_MTSAFE_IO)
 typedef pthread_mutex_t __libc_lock_t;
@@ -90,19 +94,30 @@ typedef pthread_key_t __libc_key_t;
 #define _RTLD_LOCK_RECURSIVE_INITIALIZER \
   {PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP}
 
-#ifdef __PIC__
-# define __libc_maybe_call(FUNC, ARGS, ELSE) \
+#if defined _LIBC && defined IS_IN_libpthread
+# define __libc_maybe_call(FUNC, ARGS, ELSE) FUNC ARGS
+#else
+# ifdef __PIC__
+#  define __libc_maybe_call(FUNC, ARGS, ELSE) \
   (__extension__ ({ __typeof (FUNC) *_fn = (FUNC); \
                     _fn != NULL ? (*_fn) ARGS : ELSE; }))
-#else
-# define __libc_maybe_call(FUNC, ARGS, ELSE) \
+# else
+#  define __libc_maybe_call(FUNC, ARGS, ELSE) \
   (FUNC != NULL ? FUNC ARGS : ELSE)
+# endif
+#endif
+#if defined _LIBC && !defined NOT_IN_libc && defined __PIC__
+# define __libc_maybe_call2(FUNC, ARGS, ELSE) \
+  ({__libc_pthread_functions.ptr_##FUNC != NULL \
+    ? __libc_pthread_functions.ptr_##FUNC ARGS : ELSE; })
+#else
+# define __libc_maybe_call2(FUNC, ARGS, ELSE) __libc_maybe_call (__##FUNC, ARGS, ELSE)
 #endif
 
 /* Initialize the named lock variable, leaving it in a consistent, unlocked
    state.  */
 #define __libc_lock_init(NAME) \
-  (__libc_maybe_call (__pthread_mutex_init, (&(NAME), NULL), 0))
+  (__libc_maybe_call2 (pthread_mutex_init, (&(NAME), NULL), 0))
 #define __libc_rwlock_init(NAME) \
   (__libc_maybe_call (__pthread_rwlock_init, (&(NAME), NULL), 0));
 
@@ -125,7 +140,7 @@ typedef pthread_key_t __libc_key_t;
    used again until __libc_lock_init is called again on it.  This must be
    called on a lock variable before the containing storage is reused.  */
 #define __libc_lock_fini(NAME) \
-  (__libc_maybe_call (__pthread_mutex_destroy, (&(NAME)), 0));
+  (__libc_maybe_call2 (pthread_mutex_destroy, (&(NAME)), 0));
 #define __libc_rwlock_fini(NAME) \
   (__libc_maybe_call (__pthread_rwlock_destroy, (&(NAME)), 0));
 
@@ -135,7 +150,7 @@ typedef pthread_key_t __libc_key_t;
 
 /* Lock the named lock variable.  */
 #define __libc_lock_lock(NAME) \
-  (__libc_maybe_call (__pthread_mutex_lock, (&(NAME)), 0));
+  (__libc_maybe_call2 (pthread_mutex_lock, (&(NAME)), 0));
 #define __libc_rwlock_rdlock(NAME) \
   (__libc_maybe_call (__pthread_rwlock_rdlock, (&(NAME)), 0));
 #define __libc_rwlock_wrlock(NAME) \
@@ -147,7 +162,7 @@ typedef pthread_key_t __libc_key_t;
 
 /* Try to lock the named lock variable.  */
 #define __libc_lock_trylock(NAME) \
-  (__libc_maybe_call (__pthread_mutex_trylock, (&(NAME)), 0))
+  (__libc_maybe_call2 (pthread_mutex_trylock, (&(NAME)), 0))
 #define __libc_rwlock_tryrdlock(NAME) \
   (__libc_maybe_call (__pthread_rwlock_tryrdlock, (&(NAME)), 0))
 #define __libc_rwlock_trywrlock(NAME) \
@@ -160,7 +175,7 @@ typedef pthread_key_t __libc_key_t;
 
 /* Unlock the named lock variable.  */
 #define __libc_lock_unlock(NAME) \
-  (__libc_maybe_call (__pthread_mutex_unlock, (&(NAME)), 0));
+  (__libc_maybe_call2 (pthread_mutex_unlock, (&(NAME)), 0));
 #define __libc_rwlock_unlock(NAME) \
   (__libc_maybe_call (__pthread_rwlock_unlock, (&(NAME)), 0));
 
diff --git a/linuxthreads/sysdeps/pthread/flockfile.c b/linuxthreads/sysdeps/pthread/flockfile.c
new file mode 100644
index 0000000000..a90215cc1f
--- /dev/null
+++ b/linuxthreads/sysdeps/pthread/flockfile.c
@@ -0,0 +1,33 @@
+/* Copyright (C) 2002 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <pthread.h>
+#include <stdio.h>
+#include <libio.h>
+#include <bits/stdio-lock.h>
+
+
+void
+__flockfile (stream)
+     FILE *stream;
+{
+  _IO_lock_lock (*stream->_lock);
+}
+strong_alias (__flockfile, _IO_flockfile)
+strong_alias (__flockfile, flockfile)
diff --git a/linuxthreads/sysdeps/pthread/ftrylockfile.c b/linuxthreads/sysdeps/pthread/ftrylockfile.c
new file mode 100644
index 0000000000..21c1ea01ed
--- /dev/null
+++ b/linuxthreads/sysdeps/pthread/ftrylockfile.c
@@ -0,0 +1,33 @@
+/* Copyright (C) 2002 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <errno.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <bits/stdio-lock.h>
+
+
+int
+__ftrylockfile (stream)
+     FILE *stream;
+{
+  return _IO_lock_trylock (*stream->_lock);
+}
+strong_alias (__ftrylockfile, _IO_ftrylockfile)
+weak_alias (__ftrylockfile, ftrylockfile)
diff --git a/linuxthreads/sysdeps/pthread/funlockfile.c b/linuxthreads/sysdeps/pthread/funlockfile.c
new file mode 100644
index 0000000000..f941fc9851
--- /dev/null
+++ b/linuxthreads/sysdeps/pthread/funlockfile.c
@@ -0,0 +1,33 @@
+/* Copyright (C) 2002 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <pthread.h>
+#include <stdio.h>
+#include <libio.h>
+#include <bits/stdio-lock.h>
+
+
+void
+__funlockfile (stream)
+     FILE *stream;
+{
+  _IO_lock_unlock (*stream->_lock);
+}
+strong_alias (__funlockfile, _IO_funlockfile)
+weak_alias (__funlockfile, funlockfile)
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/allocrtsig.c b/linuxthreads/sysdeps/unix/sysv/linux/allocrtsig.c
new file mode 100644
index 0000000000..a18753233a
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/allocrtsig.c
@@ -0,0 +1,85 @@
+/* Handle real-time signal allocation.
+   Copyright (C) 1997,98,99,2002 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <signal.h>
+
+/* Sanity check.  */
+#if !defined __SIGRTMIN || (__SIGRTMAX - __SIGRTMIN) < 3
+# error "This must not happen"
+#endif
+
+static int current_rtmin;
+static int current_rtmax;
+
+static int initialized;
+
+#include <testrtsig.h>
+
+static void
+init (void)
+{
+  if (!kernel_has_rtsig ())
+    {
+      current_rtmin = -1;
+      current_rtmax = -1;
+    }
+  else
+    {
+      current_rtmin = __SIGRTMIN + 3;
+      current_rtmax = __SIGRTMAX;
+    }
+  initialized = 1;
+}
+
+/* Return number of available real-time signal with highest priority.  */
+int
+__libc_current_sigrtmin (void)
+{
+  if (!initialized)
+    init ();
+  return current_rtmin;
+}
+strong_alias (__libc_current_sigrtmin, __libc_current_sigrtmin_private);
+
+/* Return number of available real-time signal with lowest priority.  */
+int
+__libc_current_sigrtmax (void)
+{
+  if (!initialized)
+    init ();
+  return current_rtmax;
+}
+strong_alias (__libc_current_sigrtmax, __libc_current_sigrtmax_private);
+
+/* Allocate real-time signal with highest/lowest available
+   priority.  Please note that we don't use a lock since we assume
+   this function to be called at program start.  */
+int
+__libc_allocate_rtsig (int high)
+{
+  if (!initialized)
+    init ();
+  if (current_rtmin == -1 || current_rtmin > current_rtmax)
+    /* We don't have anymore signal available.  */
+    return -1;
+
+  return high ? current_rtmin++ : current_rtmax--;
+}
+strong_alias (__libc_allocate_rtsig, __libc_allocate_rtsig_private);
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/i386/sysdep-cancel.h b/linuxthreads/sysdeps/unix/sysv/linux/i386/sysdep-cancel.h
new file mode 100644
index 0000000000..30be0b9c5f
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/i386/sysdep-cancel.h
@@ -0,0 +1,124 @@
+/* Copyright (C) 2002 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Jakub Jelinek <jakub@redhat.com>, 2002.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep.h>
+#include <tls.h>
+#include <pt-machine.h>
+#ifndef ASSEMBLER
+# include <linuxthreads/internals.h>
+#endif
+
+#if defined FLOATING_STACKS && USE___THREAD
+# define MULTIPLE_THREADS_OFFSET	12
+#endif
+
+#if !defined NOT_IN_libc || defined IS_IN_libpthread
+
+# undef PSEUDO
+# define PSEUDO(name, syscall_name, args)				      \
+  .text;								      \
+  ENTRY (name)								      \
+    SINGLE_THREAD_P;							      \
+    jne L(pseudo_cancel);						      \
+    DO_CALL (syscall_name, args);					      \
+    cmpl $-4095, %eax;							      \
+    jae SYSCALL_ERROR_LABEL;						      \
+    ret;								      \
+  L(pseudo_cancel):							      \
+    CENABLE								      \
+    SAVE_OLDTYPE_##args							      \
+    PUSHARGS_##args							      \
+    DOCARGS_##args							      \
+    movl $SYS_ify (syscall_name), %eax;					      \
+    int $0x80								      \
+    POPARGS_##args;							      \
+    POPCARGS_##args							      \
+    cmpl $-4095, %eax;							      \
+    jae SYSCALL_ERROR_LABEL;						      \
+  L(pseudo_end):
+
+# define SAVE_OLDTYPE_0	movl %eax, %edx;
+# define SAVE_OLDTYPE_1	SAVE_OLDTYPE_0
+# define SAVE_OLDTYPE_2	pushl %eax;
+# define SAVE_OLDTYPE_3	SAVE_OLDTYPE_2
+# define SAVE_OLDTYPE_4	SAVE_OLDTYPE_2
+# define SAVE_OLDTYPE_5	SAVE_OLDTYPE_2
+
+# define DOCARGS_0	DOARGS_0
+# define DOCARGS_1	DOARGS_1
+# define DOCARGS_2	_DOARGS_2 (12)
+# define DOCARGS_3	_DOARGS_3 (20)
+# define DOCARGS_4	_DOARGS_4 (28)
+# define DOCARGS_5	_DOARGS_5 (36)
+
+# ifdef IS_IN_libpthread
+#  define CENABLE	call __pthread_enable_asynccancel;
+#  define CDISABLE	call __pthread_disable_asynccancel
+# else
+#  define CENABLE	call __libc_enable_asynccancel;
+#  define CDISABLE	call __libc_disable_asynccancel
+# endif
+# define POPCARGS_0	pushl %eax; movl %ecx, %eax; CDISABLE; popl %eax;
+# define POPCARGS_1	POPCARGS_0
+# define POPCARGS_2	xchgl (%esp), %eax; CDISABLE; popl %eax;
+# define POPCARGS_3	POPCARGS_2
+# define POPCARGS_4	POPCARGS_2
+# define POPCARGS_5	POPCARGS_2
+
+#if !defined NOT_IN_libc
+# define __local_multiple_threads __libc_multiple_threads
+#else
+# define __local_multiple_threads __pthread_multiple_threads
+#endif
+
+# ifndef ASSEMBLER
+#  if defined MULTIPLE_THREADS_OFFSET && defined PIC
+#   define SINGLE_THREAD_P \
+  __builtin_expect (THREAD_GETMEM (THREAD_SELF,				      \
+				   p_header.data.multiple_threads) == 0, 1)
+#  else
+extern int __local_multiple_threads attribute_hidden;
+#   define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1)
+#  endif
+# else
+#  if !defined PIC
+#   define SINGLE_THREAD_P cmpl $0, __local_multiple_threads
+#  elif defined MULTIPLE_THREADS_OFFSET
+#   define SINGLE_THREAD_P cmpl $0, %gs:MULTIPLE_THREADS_OFFSET
+#  else
+#   if !defined HAVE_HIDDEN || !USE___THREAD
+#    define SINGLE_THREAD_P \
+  SETUP_PIC_REG (cx);				\
+  addl $_GLOBAL_OFFSET_TABLE_, %ecx;		\
+  cmpl $0, __local_multiple_threads@GOTOFF(%ecx)
+#   else
+#    define SINGLE_THREAD_P \
+  call __i686.get_pc_thunk.cx;			\
+  addl $_GLOBAL_OFFSET_TABLE_, %ecx;		\
+  cmpl $0, __local_multiple_threads@GOTOFF(%ecx)
+#   endif
+#  endif
+# endif
+
+#elif !defined ASSEMBLER
+
+/* This code should never be used but we define it anyhow.  */
+# define SINGLE_THREAD_P (1)
+
+#endif
diff --git a/linuxthreads/sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h b/linuxthreads/sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h
new file mode 100644
index 0000000000..1c7a95dcd8
--- /dev/null
+++ b/linuxthreads/sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h
@@ -0,0 +1,118 @@
+/* Copyright (C) 2002 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Jakub Jelinek <jakub@redhat.com>, 2002.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep.h>
+#include <tls.h>
+#include <pt-machine.h>
+#ifndef ASSEMBLER
+# include <linuxthreads/internals.h>
+#endif
+
+#if !defined NOT_IN_libc || defined IS_IN_libpthread
+
+# undef PSEUDO
+# define PSEUDO(name, syscall_name, args)				      \
+  .text;								      \
+  ENTRY (name)								      \
+    SINGLE_THREAD_P;							      \
+    jne L(pseudo_cancel);						      \
+    DO_CALL (syscall_name, args);					      \
+    cmpq $-4095, %rax;							      \
+    jae SYSCALL_ERROR_LABEL;						      \
+    ret;								      \
+  L(pseudo_cancel):							      \
+    SAVESTK_##args							      \
+    PUSHARGS_##args							      \
+    CENABLE								      \
+    POPARGS_##args							      \
+    movq %rax, OLDTYPE_##args;						      \
+    movq $SYS_ify (syscall_name), %rax;					      \
+    syscall;								      \
+    xchgq %rax, OLDTYPE_##args;						      \
+    CDISABLE								      \
+    movq OLDTYPE_##args, %rax;						      \
+    RESTSTK_##args							      \
+    cmpq $-4095, %rax;							      \
+    jae SYSCALL_ERROR_LABEL;						      \
+  L(pseudo_end):
+
+# define PUSHARGS_0	/* Nothing.  */
+# define PUSHARGS_1	PUSHARGS_0 movq %rdi, (%rsp);
+# define PUSHARGS_2	PUSHARGS_1 movq %rsi, 8(%rsp);
+# define PUSHARGS_3	PUSHARGS_2 movq %rdx, 16(%rsp);
+# define PUSHARGS_4	PUSHARGS_3 movq %rcx, 24(%rsp);
+# define PUSHARGS_5	PUSHARGS_4 movq %r8, 32(%rsp);
+# define PUSHARGS_6	PUSHARGS_5 movq %r9, 40(%rsp);
+
+# define POPARGS_0	/* Nothing.  */
+# define POPARGS_1	POPARGS_0 movq (%rsp), %rdi;
+# define POPARGS_2	POPARGS_1 movq 8(%rsp), %rsi;
+# define POPARGS_3	POPARGS_2 movq 16(%rsp), %rdx;
+# define POPARGS_4	POPARGS_3 movq 24(%rsp), %r10;
+# define POPARGS_5	POPARGS_4 movq 32(%rsp), %r8;
+# define POPARGS_6	POPARGS_5 movq 40(%rsp), %r9;
+
+# define SAVESTK_0	/* Nothing.  */
+# define SAVESTK_1	subq $16, %rsp;
+# define SAVESTK_2	SAVESTK_1;
+# define SAVESTK_3	subq $32, %rsp;
+# define SAVESTK_4	SAVESTK_3;
+# define SAVESTK_5	subq $48, %rsp;
+# define SAVESTK_6	subq $64, %rsp;
+
+# define RESTSTK_0	/* Nothing.  */
+# define RESTSTK_1	addq $16, %rsp;
+# define RESTSTK_2	RESTSTK_1;
+# define RESTSTK_3	addq $32, %rsp;
+# define RESTSTK_4	RESTSTK_3;
+# define RESTSTK_5	addq $48, %rsp;
+# define RESTSTK_6	addq $64, %rsp;
+
+# define OLDTYPE_0	%r9
+# define OLDTYPE_1	OLDTYPE_0
+# define OLDTYPE_2	OLDTYPE_0
+# define OLDTYPE_3	OLDTYPE_0
+# define OLDTYPE_4	OLDTYPE_0
+# define OLDTYPE_5	OLDTYPE_0
+# define OLDTYPE_6	48(%rsp)
+
+# ifdef IS_IN_libpthread
+#  define CENABLE	call __pthread_enable_asynccancel;
+#  define CDISABLE	call __pthread_disable_asynccancel;
+#  define __local_multiple_threads __pthread_multiple_threads
+# else
+#  define CENABLE	call __libc_enable_asynccancel;
+#  define CDISABLE	call __libc_disable_asynccancel;
+#  define __local_multiple_threads __libc_multiple_threads
+# endif
+
+# ifndef ASSEMBLER
+extern int __local_multiple_threads attribute_hidden;
+#   define SINGLE_THREAD_P \
+  __builtin_expect (__local_multiple_threads == 0, 1)
+# else
+#  define SINGLE_THREAD_P cmpl $0, __local_multiple_threads(%rip)
+# endif
+
+#elif !defined ASSEMBLER
+
+/* This code should never be used but we define it anyhow.  */
+# define SINGLE_THREAD_P (1)
+
+#endif
diff --git a/linuxthreads/sysdeps/x86_64/pt-machine.h b/linuxthreads/sysdeps/x86_64/pt-machine.h
index e0b68d315b..0a366c56eb 100644
--- a/linuxthreads/sysdeps/x86_64/pt-machine.h
+++ b/linuxthreads/sysdeps/x86_64/pt-machine.h
@@ -21,21 +21,22 @@
 #ifndef _PT_MACHINE_H
 #define _PT_MACHINE_H   1
 
-#include <stddef.h>	/* For offsetof.  */
-#include <stdlib.h>	/* For abort().  */
-#include <asm/prctl.h>
+#ifndef __ASSEMBLER__
+# include <stddef.h>	/* For offsetof.  */
+# include <stdlib.h>	/* For abort().  */
+# include <asm/prctl.h>
 
 
-#ifndef PT_EI
-# define PT_EI extern inline
-#endif
+# ifndef PT_EI
+#  define PT_EI extern inline
+# endif
 
 extern long int testandset (int *spinlock);
 extern int __compare_and_swap (long int *p, long int oldval, long int newval);
 
 /* Get some notion of the current stack.  Need not be exactly the top
    of the stack, just something somewhere in the current frame.  */
-#define CURRENT_STACK_FRAME  stack_pointer
+# define CURRENT_STACK_FRAME  stack_pointer
 register char * stack_pointer __asm__ ("%rsp");
 
 
@@ -56,7 +57,7 @@ testandset (int *spinlock)
 
 
 /* Compare-and-swap for semaphores.  */
-#define HAS_COMPARE_AND_SWAP
+# define HAS_COMPARE_AND_SWAP
 
 PT_EI int
 __compare_and_swap (long int *p, long int oldval, long int newval)
@@ -77,7 +78,7 @@ __compare_and_swap (long int *p, long int oldval, long int newval)
    assignments like
 	pthread_descr self = thread_self();
    do not get optimized away.  */
-#define THREAD_SELF \
+# define THREAD_SELF \
 ({									      \
   register pthread_descr __self;					      \
   __asm__ ("movq %%fs:%c1,%0" : "=r" (__self)				      \
@@ -90,14 +91,14 @@ __compare_and_swap (long int *p, long int oldval, long int newval)
 extern int __arch_prctl (int __code, unsigned long __addr);
 
 /* Initialize the thread-unique value.  */
-#define INIT_THREAD_SELF(descr, nr) \
+# define INIT_THREAD_SELF(descr, nr) \
 {									      \
   if (__arch_prctl (ARCH_SET_FS, (unsigned long)descr) != 0)		      \
     abort ();								      \
 }
 
 /* Read member of the thread descriptor directly.  */
-#define THREAD_GETMEM(descr, member) \
+# define THREAD_GETMEM(descr, member) \
 ({									      \
   __typeof__ (descr->member) __value;					      \
   if (sizeof (__value) == 1)						      \
@@ -127,7 +128,7 @@ extern int __arch_prctl (int __code, unsigned long __addr);
 })
 
 /* Same as THREAD_GETMEM, but the member offset can be non-constant.  */
-#define THREAD_GETMEM_NC(descr, member) \
+# define THREAD_GETMEM_NC(descr, member) \
 ({									      \
   __typeof__ (descr->member) __value;					      \
   if (sizeof (__value) == 1)						      \
@@ -157,7 +158,7 @@ extern int __arch_prctl (int __code, unsigned long __addr);
 })
 
 /* Set member of the thread descriptor directly.  */
-#define THREAD_SETMEM(descr, member, value) \
+# define THREAD_SETMEM(descr, member, value) \
 ({									      \
   __typeof__ (descr->member) __value = (value);				      \
   if (sizeof (__value) == 1)						      \
@@ -184,7 +185,7 @@ extern int __arch_prctl (int __code, unsigned long __addr);
 })
 
 /* Same as THREAD_SETMEM, but the member offset can be non-constant.  */
-#define THREAD_SETMEM_NC(descr, member, value) \
+# define THREAD_SETMEM_NC(descr, member, value) \
 ({									      \
   __typeof__ (descr->member) __value = (value);				      \
   if (sizeof (__value) == 1)						      \
@@ -210,6 +211,8 @@ extern int __arch_prctl (int __code, unsigned long __addr);
     }									      \
 })
 
+#endif /* !__ASSEMBLER__ */
+
 /* We want the OS to assign stack addresses.  */
 #define FLOATING_STACKS	1
 
diff --git a/linuxthreads/tst-cancel-wrappers.sh b/linuxthreads/tst-cancel-wrappers.sh
new file mode 100644
index 0000000000..14c42dfb8b
--- /dev/null
+++ b/linuxthreads/tst-cancel-wrappers.sh
@@ -0,0 +1,96 @@
+#! /bin/sh
+# Test whether all cancellable functions are cancellable.
+# Copyright (C) 2002 Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+# Contributed by Jakub Jelinek <jakub@redhat.com>, 2002.
+
+# The GNU C Library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+
+# The GNU C Library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+
+# You should have received a copy of the GNU Lesser General Public
+# License along with the GNU C Library; if not, write to the Free
+# Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+# 02111-1307 USA.
+
+while [ $# -gt 0 ]; do
+  ( nm -P $1; echo 'end[end]:' ) | awk ' BEGIN {
+C["accept"]=1
+C["close"]=1
+C["connect"]=1
+C["creat"]=1
+C["fcntl"]=1
+C["fsync"]=1
+C["llseek"]=1
+C["lseek"]=1
+C["msgrcv"]=1
+C["msgsnd"]=1
+C["msync"]=1
+C["nanosleep"]=1
+C["open"]=1
+C["open64"]=1
+C["pause"]=1
+C["poll"]=1
+C["pread"]=1
+C["pread64"]=1
+C["pselect"]=1
+C["pwrite"]=1
+C["pwrite64"]=1
+C["read"]=1
+C["readv"]=1
+C["recv"]=1
+C["recvfrom"]=1
+C["recvmsg"]=1
+C["select"]=1
+C["send"]=1
+C["sendmsg"]=1
+C["sendto"]=1
+C["sigpause"]=1
+C["sigsuspend"]=1
+C["sigwait"]=1
+C["sigwaitinfo"]=1
+C["system"]=1
+C["tcdrain"]=1
+C["wait"]=1
+C["waitid"]=1
+C["waitpid"]=1
+C["write"]=1
+C["writev"]=1
+C["__xpg_sigpause"]=1
+}
+/:$/ {
+  if (seen)
+    {
+      # signals.c in linuxthreads does the cancellation checks not using
+      # *_{enable,disable}_asynccancel.
+      if ((!seen_enable || !seen_disable) && !(object ~ /^signals.o/))
+	{
+	  printf "in '$1'(%s) %s'\''s cancellation missing\n", object, seen
+	  ret = 1
+	}
+    }
+  seen=""
+  seen_enable=""
+  seen_disable=""
+  object=gensub(/^.*\[(.*)\]:$/,"\\1","",$0)
+  next
+}
+{
+  if (C[$1] && $2 ~ /^[TW]$/)
+    seen=$1
+  else if ($1 ~ /^__(libc|pthread)_enable_asynccancel$/ && $2 == "U")
+    seen_enable=1
+  else if ($1 ~ /^__(libc|pthread)_disable_asynccancel$/ && $2 == "U")
+    seen_disable=1
+}
+END {
+  exit ret
+}' || exit
+  shift
+done
diff --git a/linuxthreads/weaks.c b/linuxthreads/weaks.c
deleted file mode 100644
index cd17e6804b..0000000000
--- a/linuxthreads/weaks.c
+++ /dev/null
@@ -1,97 +0,0 @@
-/* The weak pthread functions for Linux.
-   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
-   modify it under the terms of the GNU Lesser General Public License as
-   published by the Free Software Foundation; either version 2.1 of the
-   License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; see the file COPYING.LIB.  If not,
-   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
-
-#include <limits.h>
-#include <stdlib.h>
-#include <shlib-compat.h>
-#include <bp-sym.h>
-
-extern int __pthread_return_0 (void);
-extern int __pthread_return_1 (void);
-extern void __pthread_return_void (void);
-extern void weak_function pthread_exit (void *__retval)
-     __attribute__ ((noreturn));
-
-/* Those are pthread functions which return 0 if successful. */
-weak_alias (__pthread_return_0, BP_SYM (__libc_pthread_attr_init_2_1))
-versioned_symbol (libpthread, BP_SYM (__libc_pthread_attr_init_2_1),
-		  BP_SYM (pthread_attr_init), GLIBC_2_1);
-#if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_1)
-weak_alias (__pthread_return_0, BP_SYM (__libc_pthread_attr_init_2_0))
-compat_symbol (libpthread, BP_SYM (__libc_pthread_attr_init_2_0),
-	       BP_SYM (pthread_attr_init), GLIBC_2_0);
-#endif
-weak_alias (__pthread_return_0, BP_SYM (pthread_attr_destroy))
-weak_alias (__pthread_return_0, BP_SYM (pthread_attr_setdetachstate))
-weak_alias (__pthread_return_0, BP_SYM (pthread_attr_getdetachstate))
-weak_alias (__pthread_return_0, BP_SYM (pthread_attr_setschedparam))
-weak_alias (__pthread_return_0, BP_SYM (pthread_attr_getschedparam))
-weak_alias (__pthread_return_0, BP_SYM (pthread_attr_setschedpolicy))
-weak_alias (__pthread_return_0, BP_SYM (pthread_attr_getschedpolicy))
-weak_alias (__pthread_return_0, BP_SYM (pthread_attr_setinheritsched))
-weak_alias (__pthread_return_0, BP_SYM (pthread_attr_getinheritsched))
-weak_alias (__pthread_return_0, BP_SYM (pthread_attr_setscope))
-weak_alias (__pthread_return_0, BP_SYM (pthread_attr_getscope))
-weak_alias (__pthread_return_0, BP_SYM (pthread_attr_setstackaddr))
-weak_alias (__pthread_return_0, BP_SYM (pthread_attr_setstacksize))
-weak_alias (__pthread_return_0, BP_SYM (pthread_mutex_init))
-weak_alias (__pthread_return_0, BP_SYM (pthread_mutex_destroy))
-weak_alias (__pthread_return_0, BP_SYM (pthread_mutex_lock))
-weak_alias (__pthread_return_0, BP_SYM (pthread_mutex_unlock))
-weak_alias (__pthread_return_0, BP_SYM (pthread_condattr_init))
-weak_alias (__pthread_return_0, BP_SYM (pthread_condattr_destroy))
-weak_alias (__pthread_return_0, BP_SYM (pthread_setschedparam))
-weak_alias (__pthread_return_0, BP_SYM (pthread_getschedparam))
-weak_alias (__pthread_return_0, BP_SYM (pthread_setcancelstate))
-weak_alias (__pthread_return_0, BP_SYM (pthread_setcanceltype))
-weak_alias (__pthread_return_0, pthread_self)
-weak_alias (__pthread_return_0, BP_SYM (pthread_cond_init))
-weak_alias (__pthread_return_0, BP_SYM (pthread_cond_destroy))
-weak_alias (__pthread_return_0, BP_SYM (pthread_cond_wait))
-weak_alias (__pthread_return_0, BP_SYM (pthread_cond_signal))
-weak_alias (__pthread_return_0, BP_SYM (pthread_cond_broadcast))
-
-
-/* Those are pthread functions which return 1 if successful. */
-weak_alias (__pthread_return_1, pthread_equal)
-
-/* pthread_exit () is a special case. */
-void
-weak_function
-pthread_exit (void *retval)
-{
-  exit (EXIT_SUCCESS);
-}
-
-int
-__pthread_return_0 (void)
-{
-  return 0;
-}
-
-int
-__pthread_return_1 (void)
-{
-  return 1;
-}
-
-void
-__pthread_return_void (void)
-{
-}
diff --git a/linuxthreads/wrapsyscall.c b/linuxthreads/wrapsyscall.c
deleted file mode 100644
index 1a9436bd84..0000000000
--- a/linuxthreads/wrapsyscall.c
+++ /dev/null
@@ -1,233 +0,0 @@
-/* Wrapper arpund system calls to provide cancelation points.
-   Copyright (C) 1996-1999,2000-2002 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public License as
-   published by the Free Software Foundation; either version 2.1 of the
-   License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; see the file COPYING.LIB.  If not,
-   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
-
-#include <fcntl.h>
-#include <sys/mman.h>
-#include <pthread.h>
-#include <unistd.h>
-#include <stdarg.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include <termios.h>
-#include <sys/poll.h>
-#include <sys/resource.h>
-#include <sys/select.h>
-#include <sys/uio.h>
-#include <sys/wait.h>
-#include <sys/socket.h>
-
-
-#ifndef SHARED
-/* We need a hook to force this file to be linked in when static
-   libpthread is used.  */
-const int __pthread_provide_wrappers = 0;
-#endif
-
-
-#define CANCELABLE_SYSCALL(res_type, name, param_list, params) \
-extern res_type __libc_##name param_list;				      \
-res_type								      \
-name param_list								      \
-{									      \
-  res_type result;							      \
-  int oldtype;								      \
-  pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);	      \
-  result = __libc_##name params;					      \
-  pthread_setcanceltype (oldtype, NULL);				      \
-  return result;							      \
-}
-
-#define CANCELABLE_SYSCALL_VA(res_type, name, param_list, params, last_arg) \
-res_type __libc_##name param_list;					      \
-res_type								      \
-name param_list								      \
-{									      \
-  res_type result;							      \
-  int oldtype;								      \
-  va_list ap;								      \
-  pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);	      \
-  va_start (ap, last_arg);						      \
-  result = __libc_##name params;					      \
-  va_end (ap);								      \
-  pthread_setcanceltype (oldtype, NULL);				      \
-  return result;							      \
-}
-
-#define PROMOTE_INTEGRAL_TYPE(type) __typeof__ ((type) 0 + 0)
-
-
-/* close(2).  */
-CANCELABLE_SYSCALL (int, close, (int fd), (fd))
-strong_alias (close, __close)
-
-
-/* fcntl(2).  */
-CANCELABLE_SYSCALL_VA (int, fcntl, (int fd, int cmd, ...),
-		       (fd, cmd, va_arg (ap, long int)), cmd)
-strong_alias (fcntl, __fcntl)
-
-
-/* fsync(2).  */
-CANCELABLE_SYSCALL (int, fsync, (int fd), (fd))
-
-
-/* lseek(2).  */
-CANCELABLE_SYSCALL (off_t, lseek, (int fd, off_t offset, int whence),
-		    (fd, offset, whence))
-strong_alias (lseek, __lseek)
-
-
-/* lseek64(2).  */
-CANCELABLE_SYSCALL (off64_t, lseek64, (int fd, off64_t offset, int whence),
-		    (fd, offset, whence))
-
-
-/* msync(2).  */
-CANCELABLE_SYSCALL (int, msync, (__ptr_t addr, size_t length, int flags),
-		    (addr, length, flags))
-
-
-/* nanosleep(2).  */
-CANCELABLE_SYSCALL (int, nanosleep, (const struct timespec *requested_time,
-				     struct timespec *remaining),
-		    (requested_time, remaining))
-strong_alias (nanosleep, __nanosleep)
-
-
-/* open(2).  */
-CANCELABLE_SYSCALL_VA (int, open, (const char *pathname, int flags, ...),
-		       (pathname, flags,
-			va_arg (ap, PROMOTE_INTEGRAL_TYPE (mode_t))),
-		       flags)
-strong_alias (open, __open)
-
-
-/* open64(3).  */
-CANCELABLE_SYSCALL_VA (int, open64, (const char *pathname, int flags, ...),
-		       (pathname, flags,
-			va_arg (ap, PROMOTE_INTEGRAL_TYPE (mode_t))),
-		       flags)
-strong_alias (open64, __open64)
-
-
-/* pause(2).  */
-CANCELABLE_SYSCALL (int, pause, (void), ())
-
-
-/* pread(3).  */
-CANCELABLE_SYSCALL (ssize_t, pread, (int fd, void *buf, size_t count,
-				     off_t offset),
-		    (fd, buf, count, offset))
-
-
-/* pread64(3).  */
-CANCELABLE_SYSCALL (ssize_t, pread64, (int fd, void *buf, size_t count,
-				       off64_t offset),
-		    (fd, buf, count, offset))
-strong_alias (pread64, __pread64)
-
-
-/* pwrite(3).  */
-CANCELABLE_SYSCALL (ssize_t, pwrite, (int fd, const void *buf, size_t n,
-				      off_t offset),
-		    (fd, buf, n, offset))
-
-
-/* pwrite64(3).  */
-CANCELABLE_SYSCALL (ssize_t, pwrite64, (int fd, const void *buf, size_t n,
-					off64_t offset),
-		    (fd, buf, n, offset))
-strong_alias (pwrite64, __pwrite64)
-
-
-/* read(2).  */
-CANCELABLE_SYSCALL (ssize_t, read, (int fd, void *buf, size_t count),
-		    (fd, buf, count))
-strong_alias (read, __read)
-
-
-/* system(3).  */
-CANCELABLE_SYSCALL (int, system, (const char *line), (line))
-
-
-/* tcdrain(2).  */
-CANCELABLE_SYSCALL (int, tcdrain, (int fd), (fd))
-
-
-/* wait(2).  */
-CANCELABLE_SYSCALL (__pid_t, wait, (__WAIT_STATUS_DEFN stat_loc), (stat_loc))
-strong_alias (wait, __wait)
-
-
-/* waitpid(2).  */
-CANCELABLE_SYSCALL (__pid_t, waitpid, (__pid_t pid, int *stat_loc,
-				       int options),
-		    (pid, stat_loc, options))
-
-
-/* write(2).  */
-CANCELABLE_SYSCALL (ssize_t, write, (int fd, const void *buf, size_t n),
-		    (fd, buf, n))
-strong_alias (write, __write)
-
-
-/* The following system calls are thread cancellation points specified
-   in XNS.  */
-
-/* accept(2).  */
-CANCELABLE_SYSCALL (int, accept, (int fd, __SOCKADDR_ARG addr,
-				  socklen_t *addr_len),
-		    (fd, addr, addr_len))
-
-/* connect(2).  */
-CANCELABLE_SYSCALL (int, connect, (int fd, __CONST_SOCKADDR_ARG addr,
-				     socklen_t len),
-		    (fd, addr, len))
-strong_alias (connect, __connect)
-
-/* recv(2).  */
-CANCELABLE_SYSCALL (ssize_t, recv, (int fd, __ptr_t buf, size_t n, int flags),
-		    (fd, buf, n, flags))
-
-/* recvfrom(2).  */
-CANCELABLE_SYSCALL (ssize_t, recvfrom, (int fd, __ptr_t buf, size_t n, int flags,
-					__SOCKADDR_ARG addr, socklen_t *addr_len),
-		    (fd, buf, n, flags, addr, addr_len))
-
-/* recvmsg(2).  */
-CANCELABLE_SYSCALL (ssize_t, recvmsg, (int fd, struct msghdr *message, int flags),
-		    (fd, message, flags))
-
-/* send(2).  */
-CANCELABLE_SYSCALL (ssize_t, send, (int fd, const __ptr_t buf, size_t n,
-				    int flags),
-		    (fd, buf, n, flags))
-strong_alias (send, __send)
-
-/* sendmsg(2).  */
-CANCELABLE_SYSCALL (ssize_t, sendmsg, (int fd, const struct msghdr *message,
-				       int flags),
-		    (fd, message, flags))
-
-/* sendto(2).  */
-CANCELABLE_SYSCALL (ssize_t, sendto, (int fd, const __ptr_t buf, size_t n,
-				      int flags, __CONST_SOCKADDR_ARG addr,
-				      socklen_t addr_len),
-		    (fd, buf, n, flags, addr, addr_len))