about summary refs log tree commit diff
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)
downloadglibc-b22d701bb72b928526efff83c019b912f469af72.tar.gz
glibc-b22d701bb72b928526efff83c019b912f469af72.tar.xz
glibc-b22d701bb72b928526efff83c019b912f469af72.zip
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);
     }