summaryrefslogtreecommitdiff
path: root/nptl/cleanup_defer.c
diff options
context:
space:
mode:
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);
}