From f006d3a007b7caffd4c810fa71623b39334a1580 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Tue, 11 Mar 2003 19:02:26 +0000 Subject: Update. * sysdeps/unix/sysv/linux/ia64/system.c: New file. * sysdeps/unix/sysv/linux/kernel-features.h (__ASSUME_CLONE_THREAD_FLAGS): Define for IA-64 and s390* with kernel >= 2.5.64. 2003-03-11 Jakub Jelinek * sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S: Don't clobber R7. --- ChangeLog | 9 ++- nptl/init.c | 7 +++ nptl/sysdeps/ia64/bits/atomic.h | 10 +-- nptl/sysdeps/pthread/pthread_cond_timedwait.c | 10 ++- nptl/sysdeps/pthread/pthread_cond_wait.c | 4 +- nptl/sysdeps/unix/sysv/linux/ia64/sem_post.c | 1 + nptl/sysdeps/unix/sysv/linux/ia64/sem_timedwait.c | 1 + nptl/sysdeps/unix/sysv/linux/ia64/sem_trywait.c | 1 + nptl/sysdeps/unix/sysv/linux/ia64/sem_wait.c | 1 + nptl/sysdeps/unix/sysv/linux/s390/sem_post.c | 1 + nptl/sysdeps/unix/sysv/linux/s390/sem_timedwait.c | 1 + nptl/sysdeps/unix/sysv/linux/s390/sem_trywait.c | 1 + nptl/sysdeps/unix/sysv/linux/s390/sem_wait.c | 1 + nptl/version.c | 3 +- sysdeps/unix/sysv/linux/ia64/system.c | 74 +++++++++++++++++++++++ sysdeps/unix/sysv/linux/kernel-features.h | 9 +++ 16 files changed, 119 insertions(+), 15 deletions(-) create mode 100644 sysdeps/unix/sysv/linux/ia64/system.c diff --git a/ChangeLog b/ChangeLog index 34d1e6d435..d2659db611 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2003-03-11 Jakub Jelinek + + * sysdeps/unix/sysv/linux/ia64/system.c: New file. + * sysdeps/unix/sysv/linux/kernel-features.h + (__ASSUME_CLONE_THREAD_FLAGS): Define for IA-64 and s390* with + kernel >= 2.5.64. + 2003-03-11 Jakub Jelinek * sysdeps/generic/dl-sysdep.c (_dl_important_hwcaps): If CNT == 1, @@ -13,7 +20,7 @@ 2003-03-10 Steven Munroe - * sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S: Don't clobber R7. + * sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S: Don't clobber R7. Copy extra params for NPTL to registers used in clone syscall. 2003-03-10 Martin Schwidefsky diff --git a/nptl/init.c b/nptl/init.c index df8e67a83e..e4e30815a6 100644 --- a/nptl/init.c +++ b/nptl/init.c @@ -209,6 +209,13 @@ __pthread_initialize_minimal_internal (void) (void) __libc_sigaction (SIGCANCEL, &sa, NULL); + /* The parent process might have left the signal blocked. Just in + case, unblock it. We reuse the signal mask in the sigaction + structure. It is already cleared. */ + __sigaddset (&sa.sa_mask, SIGCANCEL); + (void) INTERNAL_SYSCALL (rt_sigprocmask, err, 4, SIG_UNBLOCK, &sa.sa_mask, + NULL, _NSIG / 8); + /* Determine the default allowed stack size. This is the size used in case the user does not specify one. */ diff --git a/nptl/sysdeps/ia64/bits/atomic.h b/nptl/sysdeps/ia64/bits/atomic.h index 4b1d24f8e7..cfccc6ad71 100644 --- a/nptl/sysdeps/ia64/bits/atomic.h +++ b/nptl/sysdeps/ia64/bits/atomic.h @@ -78,15 +78,17 @@ typedef uintmax_t uatomic_max_t; do \ __oldval = __val; \ while ((__val \ - = __arch_compare_and_exchange_32_val_acq (__memp, __oldval, \ - __oldval + __value)) \ + = __arch_compare_and_exchange_32_val_acq (__memp, \ + __oldval + __value, \ + __oldval)) \ != __oldval); \ else if (sizeof (*mem) == 8) \ do \ __oldval = __val; \ while ((__val \ - = __arch_compare_and_exchange_64_val_acq (__memp, __oldval, \ - __oldval + __value)) \ + = __arch_compare_and_exchange_64_val_acq (__memp, \ + __oldval + __value, \ + __oldval)) \ != __oldval); \ else \ abort (); \ diff --git a/nptl/sysdeps/pthread/pthread_cond_timedwait.c b/nptl/sysdeps/pthread/pthread_cond_timedwait.c index d6a4ae7cfe..417f873868 100644 --- a/nptl/sysdeps/pthread/pthread_cond_timedwait.c +++ b/nptl/sysdeps/pthread/pthread_cond_timedwait.c @@ -46,7 +46,7 @@ __pthread_cond_timedwait (cond, mutex, abstime) { struct _pthread_cleanup_buffer buffer; struct _condvar_cleanup_buffer cbuffer; - int result = 0, err; + int result = 0; /* Catch invalid parameters. */ if (abstime->tv_nsec >= 1000000000) @@ -56,7 +56,7 @@ __pthread_cond_timedwait (cond, mutex, abstime) lll_mutex_lock (cond->__data.__lock); /* Now we can release the mutex. */ - err = __pthread_mutex_unlock_internal (mutex); + int err = __pthread_mutex_unlock_internal (mutex); if (err) { lll_mutex_unlock (cond->__data.__lock); @@ -92,8 +92,6 @@ __pthread_cond_timedwait (cond, mutex, abstime) while (1) { - int err; - /* Get the current time. So far we support only one clock. */ struct timeval tv; (void) gettimeofday (&tv, NULL); @@ -162,9 +160,9 @@ __pthread_cond_timedwait (cond, mutex, abstime) __pthread_cleanup_pop (&buffer, 0); /* Get the mutex before returning. */ - __pthread_mutex_lock_internal (mutex); + err = __pthread_mutex_lock_internal (mutex); - return result; + return err ?: result; } versioned_symbol (libpthread, __pthread_cond_timedwait, pthread_cond_timedwait, diff --git a/nptl/sysdeps/pthread/pthread_cond_wait.c b/nptl/sysdeps/pthread/pthread_cond_wait.c index d96444f49b..399cee89ee 100644 --- a/nptl/sysdeps/pthread/pthread_cond_wait.c +++ b/nptl/sysdeps/pthread/pthread_cond_wait.c @@ -141,9 +141,7 @@ __pthread_cond_wait (cond, mutex) __pthread_cleanup_pop (&buffer, 0); /* Get the mutex before returning. */ - __pthread_mutex_lock_internal (mutex); - - return 0; + return __pthread_mutex_lock_internal (mutex); } versioned_symbol (libpthread, __pthread_cond_wait, pthread_cond_wait, diff --git a/nptl/sysdeps/unix/sysv/linux/ia64/sem_post.c b/nptl/sysdeps/unix/sysv/linux/ia64/sem_post.c index 5a7596288b..32dba265a9 100644 --- a/nptl/sysdeps/unix/sysv/linux/ia64/sem_post.c +++ b/nptl/sysdeps/unix/sysv/linux/ia64/sem_post.c @@ -21,6 +21,7 @@ #include #include #include +#include #include diff --git a/nptl/sysdeps/unix/sysv/linux/ia64/sem_timedwait.c b/nptl/sysdeps/unix/sysv/linux/ia64/sem_timedwait.c index 85b4e3ce5c..b271217c41 100644 --- a/nptl/sysdeps/unix/sysv/linux/ia64/sem_timedwait.c +++ b/nptl/sysdeps/unix/sysv/linux/ia64/sem_timedwait.c @@ -21,6 +21,7 @@ #include #include #include +#include #include diff --git a/nptl/sysdeps/unix/sysv/linux/ia64/sem_trywait.c b/nptl/sysdeps/unix/sysv/linux/ia64/sem_trywait.c index a07d3468a3..25127c21a1 100644 --- a/nptl/sysdeps/unix/sysv/linux/ia64/sem_trywait.c +++ b/nptl/sysdeps/unix/sysv/linux/ia64/sem_trywait.c @@ -21,6 +21,7 @@ #include #include #include +#include #include diff --git a/nptl/sysdeps/unix/sysv/linux/ia64/sem_wait.c b/nptl/sysdeps/unix/sysv/linux/ia64/sem_wait.c index 5409237513..958159f2d5 100644 --- a/nptl/sysdeps/unix/sysv/linux/ia64/sem_wait.c +++ b/nptl/sysdeps/unix/sysv/linux/ia64/sem_wait.c @@ -21,6 +21,7 @@ #include #include #include +#include #include diff --git a/nptl/sysdeps/unix/sysv/linux/s390/sem_post.c b/nptl/sysdeps/unix/sysv/linux/s390/sem_post.c index 6bf577bc5f..b36ebdbceb 100644 --- a/nptl/sysdeps/unix/sysv/linux/s390/sem_post.c +++ b/nptl/sysdeps/unix/sysv/linux/s390/sem_post.c @@ -21,6 +21,7 @@ #include #include #include +#include #include diff --git a/nptl/sysdeps/unix/sysv/linux/s390/sem_timedwait.c b/nptl/sysdeps/unix/sysv/linux/s390/sem_timedwait.c index 669dc3ce12..d2ef2ceb30 100644 --- a/nptl/sysdeps/unix/sysv/linux/s390/sem_timedwait.c +++ b/nptl/sysdeps/unix/sysv/linux/s390/sem_timedwait.c @@ -21,6 +21,7 @@ #include #include #include +#include #include diff --git a/nptl/sysdeps/unix/sysv/linux/s390/sem_trywait.c b/nptl/sysdeps/unix/sysv/linux/s390/sem_trywait.c index eb6fd04ce1..3695ccddfd 100644 --- a/nptl/sysdeps/unix/sysv/linux/s390/sem_trywait.c +++ b/nptl/sysdeps/unix/sysv/linux/s390/sem_trywait.c @@ -21,6 +21,7 @@ #include #include #include +#include #include diff --git a/nptl/sysdeps/unix/sysv/linux/s390/sem_wait.c b/nptl/sysdeps/unix/sysv/linux/s390/sem_wait.c index 2437de0e8a..a56e1e0a60 100644 --- a/nptl/sysdeps/unix/sysv/linux/s390/sem_wait.c +++ b/nptl/sysdeps/unix/sysv/linux/s390/sem_wait.c @@ -21,6 +21,7 @@ #include #include #include +#include #include diff --git a/nptl/version.c b/nptl/version.c index 0f12c6aa18..d0658bac0c 100644 --- a/nptl/version.c +++ b/nptl/version.c @@ -34,7 +34,8 @@ void __nptl_main (void) { INTERNAL_SYSCALL_DECL (err); - INTERNAL_SYSCALL (write, err, 3, STDOUT_FILENO, banner, sizeof banner - 1); + INTERNAL_SYSCALL (write, err, 3, STDOUT_FILENO, (const char *) banner, + sizeof banner - 1); _exit (0); } diff --git a/sysdeps/unix/sysv/linux/ia64/system.c b/sysdeps/unix/sysv/linux/ia64/system.c new file mode 100644 index 0000000000..db4fcfe015 --- /dev/null +++ b/sysdeps/unix/sysv/linux/ia64/system.c @@ -0,0 +1,74 @@ +/* Copyright (C) 2002, 2003 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; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include +#include +#include +#include +#include +#include +#include + +/* We have to and actually can handle cancelable system(). The big + problem: we have to kill the child process if necessary. To do + this a cleanup handler has to be registered and is has to be able + to find the PID of the child. The main problem is to reliable have + the PID when needed. It is not necessary for the parent thread to + return. It might still be in the kernel when the cancellation + request comes. Therefore we have to use the clone() calls ability + to have the kernel write the PID into the user-level variable. */ +#ifdef __ASSUME_CLONE_THREAD_FLAGS +# define FORK() \ + INLINE_SYSCALL (clone2, 6, CLONE_PARENT_SETTID | SIGCHLD, NULL, 0, \ + NULL, &pid, NULL) +#endif + +static void cancel_handler (void *arg); + +#define CLEANUP_HANDLER \ + __libc_cleanup_region_start (1, cancel_handler, &pid) + +#define CLEANUP_RESET \ + __libc_cleanup_region_end (0) + + +/* Linux has waitpid(), so override the generic unix version. */ +#include + + +/* The cancellation handler. */ +static void +cancel_handler (void *arg) +{ + pid_t child = *(pid_t *) arg; + + INTERNAL_SYSCALL_DECL (err); + INTERNAL_SYSCALL (kill, err, 2, child, SIGKILL); + + TEMP_FAILURE_RETRY (__waitpid (child, NULL, 0)); + + DO_LOCK (); + + if (SUB_REF () == 0) + { + (void) __sigaction (SIGQUIT, &quit, (struct sigaction *) NULL); + (void) __sigaction (SIGINT, &intr, (struct sigaction *) NULL); + } + + DO_UNLOCK (); +} diff --git a/sysdeps/unix/sysv/linux/kernel-features.h b/sysdeps/unix/sysv/linux/kernel-features.h index f9d1f09050..53d8860f43 100644 --- a/sysdeps/unix/sysv/linux/kernel-features.h +++ b/sysdeps/unix/sysv/linux/kernel-features.h @@ -270,3 +270,12 @@ #if __LINUX_KERNEL_VERSION >= 132415 # define __ASSUME_POSIX_TIMERS 1 #endif + +/* The late 2.5 kernels saw a lot of new CLONE_* flags. Summarize + their availability with one define. The changes were made first + for i386 and the have to be done separately for the other archs. + For ia64 and s390* we pick 2.5.64 as the first version with support. */ +#if __LINUX_KERNEL_VERSION >= 132416 \ + && (defined __ia64__ || defined __s390__) +# define __ASSUME_CLONE_THREAD_FLAGS 1 +#endif -- cgit 1.4.1