summaryrefslogtreecommitdiff
path: root/nptl/cleanup_defer.c
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2003-04-05 05:21:15 +0000
committerUlrich Drepper <drepper@redhat.com>2003-04-05 05:21:15 +0000
commitb22d701bb72b928526efff83c019b912f469af72 (patch)
tree4474c99dbe6f90a380c378817307646f6f8eff5c /nptl/cleanup_defer.c
parent3242201746d74bfbccb8267f8b2e81a9478bf78b (diff)
Update.
2003-04-04 Ulrich Drepper <drepper@redhat.com> * sysdeps/pthread/createthread.c (create_thread): Add some more comments explaining when to set multiple_threads and when not. * pthreadP.h: Define THREAD_ATOMIC_CMPXCHG_VAL and THREAD_ATOMIC_BIT_SET if not already defined. * sysdeps/i386/tls.h: Define THREAD_ATOMIC_CMPXCHG_VAL and THREAD_ATOMIC_BIT_SET: * sysdeps/x86_64/tls.h: Likewise. * cleanup_defer.c (_pthread_cleanup_push_defer): Rewrite to use THREAD_ATOMIC_CMPXCHG_VAL. (_pthread_cleanup_pop_restore): Likewise. * cancellation.c (__pthread_enable_asynccancel): Likewise. (__pthread_enable_asynccancel_2): Likewise. (__pthread_disable_asynccancel): Likewise. * libc-cancellation.c (__libc_enable_asynccancel): Likewise. (__libc_disable_asynccancel): Likewise. * init.c (sigcancel_handler): Likewise. * pthread_setcancelstate.c (__pthread_setcancelstate): Likewise. * pthread_setcanceltype.c (__pthread_setcanceltype): Likewise.
Diffstat (limited to 'nptl/cleanup_defer.c')
-rw-r--r--nptl/cleanup_defer.c40
1 files changed, 27 insertions, 13 deletions
diff --git a/nptl/cleanup_defer.c b/nptl/cleanup_defer.c
index 5d6ed0360b..7945a0ddbb 100644
--- a/nptl/cleanup_defer.c
+++ b/nptl/cleanup_defer.c
@@ -18,7 +18,6 @@
02111-1307 USA. */
#include "pthreadP.h"
-#include <atomic.h>
void
@@ -37,13 +36,19 @@ _pthread_cleanup_push_defer (buffer, routine, arg)
/* Disable asynchronous cancellation for now. */
if (__builtin_expect (cancelhandling & CANCELTYPE_BITMASK, 0))
- {
- while (atomic_compare_and_exchange_bool_acq (&self->cancelhandling,
- cancelhandling
- & ~CANCELTYPE_BITMASK,
- cancelhandling))
- cancelhandling = self->cancelhandling;
- }
+ while (1)
+ {
+ int newval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling,
+ cancelhandling
+ & ~CANCELTYPE_BITMASK,
+ cancelhandling);
+ if (__builtin_expect (newval == cancelhandling, 1))
+ /* Successfully replaced the value. */
+ break;
+
+ /* Prepare for the next round. */
+ cancelhandling = newval;
+ }
buffer->__canceltype = (cancelhandling & CANCELTYPE_BITMASK
? PTHREAD_CANCEL_ASYNCHRONOUS
@@ -53,6 +58,7 @@ _pthread_cleanup_push_defer (buffer, routine, arg)
}
strong_alias (_pthread_cleanup_push_defer, __pthread_cleanup_push_defer)
+
void
_pthread_cleanup_pop_restore (buffer, execute)
struct _pthread_cleanup_buffer *buffer;
@@ -67,11 +73,19 @@ _pthread_cleanup_pop_restore (buffer, execute)
&& ((cancelhandling = THREAD_GETMEM (self, cancelhandling))
& CANCELTYPE_BITMASK) == 0)
{
- while (atomic_compare_and_exchange_bool_acq (&self->cancelhandling,
- cancelhandling
- | CANCELTYPE_BITMASK,
- cancelhandling))
- cancelhandling = self->cancelhandling;
+ while (1)
+ {
+ int newval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling,
+ cancelhandling
+ | CANCELTYPE_BITMASK,
+ cancelhandling);
+ if (__builtin_expect (newval == cancelhandling, 1))
+ /* Successfully replaced the value. */
+ break;
+
+ /* Prepare for the next round. */
+ cancelhandling = newval;
+ }
CANCELLATION_P (self);
}