summaryrefslogtreecommitdiff
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
parentf077a4a9f027b938bd091583e3ec34725cba428c (diff)
downloadglibc-82f81a9086320d12eb2fc45766203954b90461a2.tar.gz
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.
-rw-r--r--ChangeLog12
-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
-rw-r--r--sysdeps/unix/sysv/linux/alpha/syscalls.list4
-rw-r--r--sysdeps/unix/sysv/linux/hppa/syscalls.list4
-rw-r--r--sysdeps/unix/sysv/linux/ia64/sigsuspend.c13
-rw-r--r--sysdeps/unix/sysv/linux/ia64/syscalls.list4
-rw-r--r--sysdeps/unix/sysv/linux/s390/s390-64/syscalls.list4
-rw-r--r--sysdeps/unix/sysv/linux/x86_64/syscalls.list4
36 files changed, 1381 insertions, 541 deletions
diff --git a/ChangeLog b/ChangeLog
index e9eba10084..f95644617b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,17 @@
2002-12-17 Jakub Jelinek <jakub@redhat.com>
+ * 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.
+
* malloc/thread-m.h (mutex_init, mutex_lock, mutex_trylock,
mutex_unlock): If not building NPTL, use __libc_maybe_call2 if
available, otherwise __libc_maybe_call.
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))
diff --git a/sysdeps/unix/sysv/linux/alpha/syscalls.list b/sysdeps/unix/sysv/linux/alpha/syscalls.list
index 7f5c9d0052..6907ef1d2f 100644
--- a/sysdeps/unix/sysv/linux/alpha/syscalls.list
+++ b/sysdeps/unix/sysv/linux/alpha/syscalls.list
@@ -2,8 +2,8 @@
oldmsgctl EXTRA msgctl 3 __old_msgctl msgctl@GLIBC_2.0
msgget - msgget 2 __msgget msgget
-msgrcv - msgrcv 5 __msgrcv msgrcv
-msgsnd - msgsnd 4 __msgsnd msgsnd
+msgrcv - msgrcv C:5 __msgrcv msgrcv
+msgsnd - msgsnd C:4 __msgsnd msgsnd
shmat - osf_shmat 3 __shmat shmat
oldshmctl EXTRA shmctl 3 __old_shmctl shmctl@GLIBC_2.0
shmdt - shmdt 1 __shmdt shmdt
diff --git a/sysdeps/unix/sysv/linux/hppa/syscalls.list b/sysdeps/unix/sysv/linux/hppa/syscalls.list
index 6edb2d2b16..bc977e2e30 100644
--- a/sysdeps/unix/sysv/linux/hppa/syscalls.list
+++ b/sysdeps/unix/sysv/linux/hppa/syscalls.list
@@ -3,8 +3,8 @@
# semaphore and shm system calls
msgctl - msgctl i:iip __msgctl msgctl
msgget - msgget i:ii __msgget msgget
-msgrcv - msgrcv i:ibnii __msgrcv msgrcv
-msgsnd - msgsnd i:ibni __msgsnd msgsnd
+msgrcv - msgrcv Ci:ibnii __msgrcv msgrcv
+msgsnd - msgsnd Ci:ibni __msgsnd msgsnd
shmat - shmat i:ipi __shmat shmat
shmctl - shmctl i:iip __shmctl shmctl
shmdt - shmdt i:s __shmdt shmdt
diff --git a/sysdeps/unix/sysv/linux/ia64/sigsuspend.c b/sysdeps/unix/sysv/linux/ia64/sigsuspend.c
index a0023acb7f..5accdda05f 100644
--- a/sysdeps/unix/sysv/linux/ia64/sigsuspend.c
+++ b/sysdeps/unix/sysv/linux/ia64/sigsuspend.c
@@ -20,7 +20,7 @@
#include <signal.h>
#include <unistd.h>
-#include <sysdep.h>
+#include <sysdep-cancel.h>
#include <sys/syscall.h>
#include <bp-checks.h>
@@ -35,7 +35,16 @@ __sigsuspend (set)
{
/* XXX The size argument hopefully will have to be changed to the
real size of the user-level sigset_t. */
- return INLINE_SYSCALL (rt_sigsuspend, 2, CHECK_SIGSET (set), _NSIG / 8);
+ if (SINGLE_THREAD_P)
+ return INLINE_SYSCALL (rt_sigsuspend, 2, CHECK_SIGSET (set), _NSIG / 8);
+
+ int oldtype = LIBC_CANCEL_ASYNC ();
+
+ int result = INLINE_SYSCALL (rt_sigsuspend, 2, CHECK_SIGSET (set), _NSIG / 8);
+
+ LIBC_CANCEL_RESET (oldtype);
+
+ return result;
}
libc_hidden_def (__sigsuspend)
weak_alias (__sigsuspend, sigsuspend)
diff --git a/sysdeps/unix/sysv/linux/ia64/syscalls.list b/sysdeps/unix/sysv/linux/ia64/syscalls.list
index 7c0f11f668..7df0265feb 100644
--- a/sysdeps/unix/sysv/linux/ia64/syscalls.list
+++ b/sysdeps/unix/sysv/linux/ia64/syscalls.list
@@ -22,8 +22,8 @@ sendfile - sendfile i:iipi sendfile sendfile64
# semaphore and shm system calls
msgctl - msgctl i:iip __msgctl msgctl
msgget - msgget i:ii __msgget msgget
-msgrcv - msgrcv i:ibnii __msgrcv msgrcv
-msgsnd - msgsnd i:ibni __msgsnd msgsnd
+msgrcv - msgrcv Ci:ibnii __msgrcv msgrcv
+msgsnd - msgsnd Ci:ibni __msgsnd msgsnd
shmat - shmat i:ipi __shmat shmat
shmctl - shmctl i:iip __shmctl shmctl
shmdt - shmdt i:s __shmdt shmdt
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/syscalls.list b/sysdeps/unix/sysv/linux/s390/s390-64/syscalls.list
index 55c8c3aa8e..d813d7af51 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/syscalls.list
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/syscalls.list
@@ -15,8 +15,8 @@ setrlimit - setrlimit 2 __setrlimit setrlimit setrlimit64
# semaphore and shm system calls
msgctl - msgctl i:iip __msgctl msgctl
msgget - msgget i:ii __msgget msgget
-msgrcv - msgrcv i:ibnii __msgrcv msgrcv
-msgsnd - msgsnd i:ibni __msgsnd msgsnd
+msgrcv - msgrcv Ci:ibnii __msgrcv msgrcv
+msgsnd - msgsnd Ci:ibni __msgsnd msgsnd
shmat - shmat i:ipi __shmat shmat
shmctl - shmctl i:iip __shmctl shmctl
shmdt - shmdt i:s __shmdt shmdt
diff --git a/sysdeps/unix/sysv/linux/x86_64/syscalls.list b/sysdeps/unix/sysv/linux/x86_64/syscalls.list
index a5c1288f61..64abc4fc74 100644
--- a/sysdeps/unix/sysv/linux/x86_64/syscalls.list
+++ b/sysdeps/unix/sysv/linux/x86_64/syscalls.list
@@ -18,8 +18,8 @@ sendfile - sendfile i:iipi sendfile sendfile64
# semaphore and shm system calls
msgctl - msgctl i:iip __msgctl msgctl
msgget - msgget i:ii __msgget msgget
-msgrcv - msgrcv i:ibnii __msgrcv msgrcv
-msgsnd - msgsnd i:ibni __msgsnd msgsnd
+msgrcv - msgrcv Ci:ibnii __msgrcv msgrcv
+msgsnd - msgsnd Ci:ibni __msgsnd msgsnd
shmat - shmat i:ipi __shmat shmat
shmctl - shmctl i:iip __shmctl shmctl
shmdt - shmdt i:s __shmdt shmdt