diff options
author | Andreas Schwab <aschwab@redhat.com> | 2009-06-10 14:04:22 +0200 |
---|---|---|
committer | Andreas Schwab <aschwab@redhat.com> | 2009-06-10 14:04:22 +0200 |
commit | 0d02cb10e8dd8639b86450cf8e597cf5e2e09894 (patch) | |
tree | 0f2174db43a501b946f0600d1b91ae4117977b04 /nptl | |
parent | dfbbe67270efa9c03f9444d50d2f98a7a64622b4 (diff) | |
parent | 88ea382fda5af7717f85bb19837c9c99094f3df4 (diff) | |
download | glibc-0d02cb10e8dd8639b86450cf8e597cf5e2e09894.tar glibc-0d02cb10e8dd8639b86450cf8e597cf5e2e09894.tar.gz glibc-0d02cb10e8dd8639b86450cf8e597cf5e2e09894.tar.bz2 glibc-0d02cb10e8dd8639b86450cf8e597cf5e2e09894.zip |
Merge commit 'origin/master' into fedora/master
Conflicts:
ChangeLog
sysdeps/unix/sysv/linux/i386/sysconf.c
sysdeps/x86_64/cacheinfo.c
version.h
Diffstat (limited to 'nptl')
-rw-r--r-- | nptl/ChangeLog | 27 | ||||
-rw-r--r-- | nptl/Makefile | 12 | ||||
-rw-r--r-- | nptl/cancellation.c | 21 | ||||
-rw-r--r-- | nptl/libc-cancellation.c | 102 | ||||
-rw-r--r-- | nptl/libc-cleanup.c | 28 | ||||
-rw-r--r-- | nptl/nptl-init.c (renamed from nptl/init.c) | 0 | ||||
-rw-r--r-- | nptl/pthread_cancel.c | 8 | ||||
-rw-r--r-- | nptl/sysdeps/pthread/librt-cancellation.c | 91 |
8 files changed, 87 insertions, 202 deletions
diff --git a/nptl/ChangeLog b/nptl/ChangeLog index b40e5550a8..fce9209859 100644 --- a/nptl/ChangeLog +++ b/nptl/ChangeLog @@ -1,3 +1,30 @@ +2009-05-16 Ulrich Drepper <drepper@redhat.com> + + * libc-cancellation.c: Move __libc_cleanup_routine to... + * libc-cleanup.c: ...here. New file. + * Makefile (routines): Add libc-cleanup. + + * cancellation.c (__pthread_disable_asynccancel): Remove unnecessary + test. + * libc-cancellation.c: Use <nptl/cancellation.c: to define the code. + * sysdeps/pthread/librt-cancellation.c: Likewise. + + [BZ #9924] + * nptl-init.c: Renamed from init.c. + * Makefile: Change all occurences of init.c to nptl-init.c. + +2009-05-15 Ulrich Drepper <drepper@redhat.com> + + * cancellation.c (__pthread_disable_asynccancel): Correct the bits + to test when deciding on the delay. + * libc-cancellation.c (__libc_disable_asynccancel): Likewise. + * pthread_cancel.c: Close race between deciding on sending a signal + and setting the CANCELING_BIT bit. + + * cancellation.c (__pthread_disable_asynccancel): Don't return if + thread is canceled. + * libc-cancellation.c (__libc_disable_asynccancel): Likewise. + 2009-04-27 Ulrich Drepper <drepper@redhat.com> * cancellation.c (__pthread_disable_asynccancel): Use THREAD_ATOMIC_AND diff --git a/nptl/Makefile b/nptl/Makefile index 7406949376..f2fba243aa 100644 --- a/nptl/Makefile +++ b/nptl/Makefile @@ -1,5 +1,4 @@ -# Copyright (C) 2002,2003,2004,2005,2006,2007,2008 -# Free Software Foundation, Inc. +# Copyright (C) 2002-2008,2009 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 @@ -28,10 +27,11 @@ extra-libs := libpthread extra-libs-others := $(extra-libs) install-lib-ldscripts := libpthread.so -routines = alloca_cutoff forward libc-lowlevellock libc-cancellation +routines = alloca_cutoff forward libc-lowlevellock libc-cancellation \ + libc-cleanup shared-only-routines = forward -libpthread-routines = init vars events version \ +libpthread-routines = nptl-init vars events version \ pthread_create pthread_exit pthread_detach \ pthread_join pthread_tryjoin pthread_timedjoin \ pthread_self pthread_equal pthread_yield \ @@ -139,8 +139,8 @@ CFLAGS-pthread_atfork.c = -DNOT_IN_libc # we have to compile some files with exception handling enabled, some # even with asynchronous unwind tables. -# init.c contains sigcancel_handler(). -CFLAGS-init.c = -fexceptions -fasynchronous-unwind-tables +# nptl-init.c contains sigcancel_handler(). +CFLAGS-nptl-init.c = -fexceptions -fasynchronous-unwind-tables # The unwind code itself, CFLAGS-unwind.c = -fexceptions CFLAGS-unwind-forcedunwind.c = -fexceptions -fasynchronous-unwind-tables diff --git a/nptl/cancellation.c b/nptl/cancellation.c index 81134a679a..eac7973db7 100644 --- a/nptl/cancellation.c +++ b/nptl/cancellation.c @@ -70,18 +70,13 @@ __pthread_disable_asynccancel (int oldtype) return; struct pthread *self = THREAD_SELF; + int newval; -#ifdef THREAD_ATOMIC_AND - THREAD_ATOMIC_AND (self, cancelhandling, ~CANCELTYPE_BITMASK); -#else int oldval = THREAD_GETMEM (self, cancelhandling); while (1) { - int newval = oldval & ~CANCELTYPE_BITMASK; - - if (newval == oldval) - break; + newval = oldval & ~CANCELTYPE_BITMASK; int curval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling, newval, oldval); @@ -91,5 +86,15 @@ __pthread_disable_asynccancel (int oldtype) /* Prepare the next round. */ oldval = curval; } -#endif + + /* We cannot return when we are being canceled. Upon return the + thread might be things which would have to be undone. The + following loop should loop until the cancellation signal is + delivered. */ + while (__builtin_expect ((newval & (CANCELING_BITMASK | CANCELED_BITMASK)) + == CANCELING_BITMASK, 0)) + { + lll_futex_wait (&self->cancelhandling, newval, LLL_PRIVATE); + newval = THREAD_GETMEM (self, cancelhandling); + } } diff --git a/nptl/libc-cancellation.c b/nptl/libc-cancellation.c index cf24f1c0f2..308be382d1 100644 --- a/nptl/libc-cancellation.c +++ b/nptl/libc-cancellation.c @@ -17,105 +17,9 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#include <setjmp.h> -#include <stdlib.h> #include "pthreadP.h" -#include <atomic.h> -#include <bits/libc-lock.h> -#ifndef NOT_IN_libc - -/* 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) -{ - struct pthread *self = THREAD_SELF; - int oldval = THREAD_GETMEM (self, cancelhandling); - - while (1) - { - int newval = oldval | CANCELTYPE_BITMASK; - - if (__builtin_expect ((oldval & CANCELED_BITMASK) != 0, 0)) - { - /* If we are already exiting or if PTHREAD_CANCEL_DISABLED, - stop right here. */ - if ((oldval & (EXITING_BITMASK | CANCELSTATE_BITMASK)) != 0) - break; - - int curval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling, - newval, oldval); - if (__builtin_expect (curval != oldval, 0)) - { - /* Somebody else modified the word, try again. */ - oldval = curval; - continue; - } - - THREAD_SETMEM (self, result, PTHREAD_CANCELED); - - __do_cancel (); - - /* NOTREACHED */ - } - - int curval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling, newval, - oldval); - if (__builtin_expect (curval == oldval, 1)) - break; - - /* Prepare the next round. */ - oldval = curval; - } - - return oldval; -} - - -void -internal_function attribute_hidden -__libc_disable_asynccancel (int oldtype) -{ - /* If asynchronous cancellation was enabled before we do not have - anything to do. */ - if (oldtype & CANCELTYPE_BITMASK) - return; - - struct pthread *self = THREAD_SELF; - -#ifdef THREAD_ATOMIC_AND - THREAD_ATOMIC_AND (self, cancelhandling, ~CANCELTYPE_BITMASK); -#else - int oldval = THREAD_GETMEM (self, cancelhandling); - - while (1) - { - int newval = oldval & ~CANCELTYPE_BITMASK; - - if (newval == oldval) - break; - - int curval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling, newval, - oldval); - if (__builtin_expect (curval == oldval, 1)) - break; - - /* Prepare the next round. */ - oldval = curval; - } -#endif -} - - -void -__libc_cleanup_routine (struct __pthread_cleanup_frame *f) -{ - if (f->__do_it) - f->__cancel_routine (f->__cancel_arg); -} - -#endif +#define __pthread_enable_asynccancel __libc_enable_asynccancel +#define __pthread_disable_asynccancel __libc_disable_asynccancel +#include <nptl/cancellation.c> diff --git a/nptl/libc-cleanup.c b/nptl/libc-cleanup.c new file mode 100644 index 0000000000..0256d09563 --- /dev/null +++ b/nptl/libc-cleanup.c @@ -0,0 +1,28 @@ +/* Copyright (C) 2002, 2003, 2005, 2009 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 "pthreadP.h" + + +void +__libc_cleanup_routine (struct __pthread_cleanup_frame *f) +{ + if (f->__do_it) + f->__cancel_routine (f->__cancel_arg); +} diff --git a/nptl/init.c b/nptl/nptl-init.c index 5e9c250ff7..5e9c250ff7 100644 --- a/nptl/init.c +++ b/nptl/nptl-init.c diff --git a/nptl/pthread_cancel.c b/nptl/pthread_cancel.c index a13af56b37..55bb0da922 100644 --- a/nptl/pthread_cancel.c +++ b/nptl/pthread_cancel.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc. +/* Copyright (C) 2002, 2003, 2004, 2009 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. @@ -44,6 +44,7 @@ pthread_cancel (th) int newval; do { + again: oldval = pd->cancelhandling; newval = oldval | CANCELING_BITMASK | CANCELED_BITMASK; @@ -59,7 +60,10 @@ pthread_cancel (th) if (CANCEL_ENABLED_AND_CANCELED_AND_ASYNCHRONOUS (newval)) { /* Mark the cancellation as "in progress". */ - atomic_bit_set (&pd->cancelhandling, CANCELING_BIT); + if (atomic_compare_and_exchange_bool_acq (&pd->cancelhandling, + oldval | CANCELING_BITMASK, + oldval)) + goto again; /* The cancellation handler will take care of marking the thread as canceled. */ diff --git a/nptl/sysdeps/pthread/librt-cancellation.c b/nptl/sysdeps/pthread/librt-cancellation.c index 753a2d831e..d9f7ad9ea3 100644 --- a/nptl/sysdeps/pthread/librt-cancellation.c +++ b/nptl/sysdeps/pthread/librt-cancellation.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002, 2003 Free Software Foundation, Inc. +/* Copyright (C) 2002, 2003, 2009 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. @@ -17,92 +17,9 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#include <setjmp.h> -#include <signal.h> -#include <stdlib.h> #include "pthreadP.h" -#include "atomic.h" -#ifdef IS_IN_librt -/* 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 -__librt_enable_asynccancel (void) -{ - struct pthread *self = THREAD_SELF; - int oldval = THREAD_GETMEM (self, cancelhandling); - - while (1) - { - int newval = oldval | CANCELTYPE_BITMASK; - - if (__builtin_expect ((oldval & CANCELED_BITMASK) != 0, 0)) - { - /* If we are already exiting or if PTHREAD_CANCEL_DISABLED, - stop right here. */ - if ((oldval & (EXITING_BITMASK | CANCELSTATE_BITMASK)) != 0) - break; - - int curval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling, - newval, oldval); - if (__builtin_expect (curval != oldval, 0)) - { - /* Somebody else modified the word, try again. */ - oldval = curval; - continue; - } - - THREAD_SETMEM (self, result, PTHREAD_CANCELED); - - __do_cancel (); - - /* NOTREACHED */ - } - - int curval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling, newval, - oldval); - if (__builtin_expect (curval == oldval, 1)) - break; - - /* Prepare the next round. */ - oldval = curval; - } - - return oldval; -} - - -void -internal_function attribute_hidden -__librt_disable_asynccancel (int oldtype) -{ - /* If asynchronous cancellation was enabled before we do not have - anything to do. */ - if (oldtype & CANCELTYPE_BITMASK) - return; - - struct pthread *self = THREAD_SELF; - int oldval = THREAD_GETMEM (self, cancelhandling); - - while (1) - { - int newval = oldval & ~CANCELTYPE_BITMASK; - - if (newval == oldval) - break; - - int curval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling, newval, - oldval); - if (__builtin_expect (curval == oldval, 1)) - break; - - /* Prepare the next round. */ - oldval = curval; - } -} - - -#endif +#define __pthread_enable_asynccancel __librt_enable_asynccancel +#define __pthread_disable_asynccancel __librt_disable_asynccancel +#include <nptl/cancellation.c> |