summaryrefslogtreecommitdiff
path: root/nptl
diff options
context:
space:
mode:
authorAndreas Schwab <aschwab@redhat.com>2009-06-10 14:04:22 +0200
committerAndreas Schwab <aschwab@redhat.com>2009-06-10 14:04:22 +0200
commit0d02cb10e8dd8639b86450cf8e597cf5e2e09894 (patch)
tree0f2174db43a501b946f0600d1b91ae4117977b04 /nptl
parentdfbbe67270efa9c03f9444d50d2f98a7a64622b4 (diff)
parent88ea382fda5af7717f85bb19837c9c99094f3df4 (diff)
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/ChangeLog27
-rw-r--r--nptl/Makefile12
-rw-r--r--nptl/cancellation.c21
-rw-r--r--nptl/libc-cancellation.c102
-rw-r--r--nptl/libc-cleanup.c28
-rw-r--r--nptl/nptl-init.c (renamed from nptl/init.c)0
-rw-r--r--nptl/pthread_cancel.c8
-rw-r--r--nptl/sysdeps/pthread/librt-cancellation.c91
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>