about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--nptl/Banner2
-rw-r--r--nptl/ChangeLog11
-rw-r--r--nptl/cancellation.c31
-rw-r--r--nptl/pthreadP.h2
-rw-r--r--nptl/sysdeps/pthread/pthread_cond_timedwait.c2
-rw-r--r--nptl/sysdeps/pthread/pthread_cond_wait.c4
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S5
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S5
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S2
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/lowlevelmutex.S2
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S5
11 files changed, 58 insertions, 13 deletions
diff --git a/nptl/Banner b/nptl/Banner
index 6e4ad3f789..7b44e76bdc 100644
--- a/nptl/Banner
+++ b/nptl/Banner
@@ -1 +1 @@
-NPTL 0.28 by Ulrich Drepper
+NPTL 0.29 by Ulrich Drepper
diff --git a/nptl/ChangeLog b/nptl/ChangeLog
index a4cd4f5482..15b9cd71ad 100644
--- a/nptl/ChangeLog
+++ b/nptl/ChangeLog
@@ -1,5 +1,16 @@
 2003-03-11  Ulrich Drepper  <drepper@redhat.com>
 
+	* cancellation.c (__pthread_enable_asynccancel_2): New function.
+	* pthreadP.h: Declare __pthread_enable_asynccancel_2.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S
+	(__pthread_cond_timedwait): Use __pthread_enable_asynccancel_2
+	instead of __pthread_enable_asynccancel.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S
+	(__pthread_cond_wait): Likewise.
+	* sysdeps/pthread/pthread_cond_timedwait.c
+	(__pthread_cond_timedwait): Likewise.
+	* sysdeps/pthread/pthread_cond_wait.c (__pthread_cond_wait): Likewise.
+
 	* sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S
 	(__condvar_cleanup): Wake up all waiters in case we got signaled
 	after being woken up but before disabling asynchronous
diff --git a/nptl/cancellation.c b/nptl/cancellation.c
index f136bbb4c4..1dfbe4baca 100644
--- a/nptl/cancellation.c
+++ b/nptl/cancellation.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -57,6 +57,35 @@ __pthread_enable_asynccancel (void)
   return oldval;
 }
 
+/* XXX Ideally we have only one version.  But this needs preparation.  */
+void
+internal_function attribute_hidden
+__pthread_enable_asynccancel_2 (int *oldvalp)
+{
+  struct pthread *self = THREAD_SELF;
+
+  while (1)
+    {
+      int oldval = *oldvalp = THREAD_GETMEM (self, cancelhandling);
+      int newval = oldval | CANCELTYPE_BITMASK;
+
+      if (newval == oldval)
+	break;
+
+      if (atomic_compare_and_exchange_acq (&self->cancelhandling, newval,
+					   oldval) == 0)
+	{
+	  if (CANCEL_ENABLED_AND_CANCELED_AND_ASYNCHRONOUS (newval))
+	    {
+	      THREAD_SETMEM (self, result, PTHREAD_CANCELED);
+	      __do_cancel ();
+	    }
+
+	  break;
+	}
+    }
+}
+
 
 void
 internal_function attribute_hidden
diff --git a/nptl/pthreadP.h b/nptl/pthreadP.h
index c9f31e801a..ca458974c8 100644
--- a/nptl/pthreadP.h
+++ b/nptl/pthreadP.h
@@ -319,6 +319,8 @@ extern int __pthread_cond_wait_2_0 (pthread_cond_2_0_t *cond,
 
 /* The two functions are in libc.so and not exported.  */
 extern int __libc_enable_asynccancel (void) attribute_hidden;
+extern void __libc_enable_asynccancel_2 (int *oldvalp)
+     internal_function attribute_hidden;
 extern void __libc_disable_asynccancel (int oldtype)
      internal_function attribute_hidden;
 
diff --git a/nptl/sysdeps/pthread/pthread_cond_timedwait.c b/nptl/sysdeps/pthread/pthread_cond_timedwait.c
index 417f873868..0635e6ed93 100644
--- a/nptl/sysdeps/pthread/pthread_cond_timedwait.c
+++ b/nptl/sysdeps/pthread/pthread_cond_timedwait.c
@@ -120,7 +120,7 @@ __pthread_cond_timedwait (cond, mutex, abstime)
       lll_mutex_unlock (cond->__data.__lock);
 
       /* Enable asynchronous cancellation.  Required by the standard.  */
-      cbuffer.oldtype = __pthread_enable_asynccancel ();
+      __pthread_enable_asynccancel_2 (&cbuffer.oldtype);
 
       /* Wait until woken by signal or broadcast.  Note that we
 	 truncate the 'val' value to 32 bits.  */
diff --git a/nptl/sysdeps/pthread/pthread_cond_wait.c b/nptl/sysdeps/pthread/pthread_cond_wait.c
index 78fcc7f6c6..b681ef26fd 100644
--- a/nptl/sysdeps/pthread/pthread_cond_wait.c
+++ b/nptl/sysdeps/pthread/pthread_cond_wait.c
@@ -123,7 +123,7 @@ __pthread_cond_wait (cond, mutex)
       lll_mutex_unlock (cond->__data.__lock);
 
       /* Enable asynchronous cancellation.  Required by the standard.  */
-      cbuffer.oldtype = __pthread_enable_asynccancel ();
+      __pthread_enable_asynccancel_2 (&cbuffer.oldtype);
 
       /* Wait until woken by signal or broadcast.  Note that we
 	 truncate the 'val' value to 32 bits.  */
@@ -133,7 +133,7 @@ __pthread_cond_wait (cond, mutex)
       __pthread_disable_asynccancel (cbuffer.oldtype);
 
       /* We are going to look at shared data again, so get the lock.  */
-      lll_mutex_lock(cond->__data.__lock);
+      lll_mutex_lock (cond->__data.__lock);
 
       /* Check whether we are eligible for wakeup.  */
       val = cond->__data.__wakeup_seq;
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S
index 122be6f714..f11a44ec43 100644
--- a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S
+++ b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S
@@ -108,8 +108,8 @@ __pthread_cond_timedwait:
 #endif
 	jne	3f
 
-4:	call	__pthread_enable_asynccancel
-	movl	%eax, (%esp)
+4:	movl	%esp, %eax
+	call	__pthread_enable_asynccancel_2
 
 	/* Get the current time.  */
 	movl	%ebx, %edx
@@ -145,6 +145,7 @@ __pthread_cond_timedwait:
 	subl	$wakeup_seq, %ebx
 	movl	%eax, %esi
 
+	movl	(%esp), %eax
 	call	__pthread_disable_asynccancel
 
 	/* Lock.  */
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S
index b3a49e794a..c13c38290e 100644
--- a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S
+++ b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S
@@ -165,8 +165,8 @@ __pthread_cond_wait:
 #endif
 	jne	3f
 
-4:	call	__pthread_enable_asynccancel
-	movl	%eax, (%esp)
+4:	movl	%esp, %eax
+	call	__pthread_enable_asynccancel_2
 
 	movl	%esi, %ecx	/* movl $FUTEX_WAIT, %ecx */
 	movl	%edi, %edx
@@ -175,6 +175,7 @@ __pthread_cond_wait:
 	ENTER_KERNEL
 	subl	$wakeup_seq, %ebx
 
+	movl	(%esp), %eax
 	call	__pthread_disable_asynccancel
 
 	/* Lock.  */
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S b/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S
index e7e1707a48..1585921ff0 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S
@@ -49,7 +49,7 @@ __lll_lock_wait:
 	xorq	%r10, %r10	/* No timeout.  */
 
 1:
-	leal	-1(%esi), %edx	/* account for the preceeded xadd.  */
+	leaq	-1(%rsi), %rdx	/* account for the preceeded xadd.  */
 	movq	%r10, %rsi	/* movl $FUTEX_WAIT, %ecx */
 	movq	$SYS_futex, %rax
 	syscall
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevelmutex.S b/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevelmutex.S
index a494e0efaa..55e4ec4682 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevelmutex.S
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevelmutex.S
@@ -50,7 +50,7 @@ __lll_mutex_lock_wait:
 	xorq	%r10, %r10	/* No timeout.  */
 
 1:
-	leal	1(%esi), %edx	/* account for the preceeded xadd.  */
+	leaq	1(%rsi), %rdx	/* account for the preceeded xadd.  */
 	movq	%r10, %rsi	/* movl $FUTEX_WAIT, %ecx */
 	movq	$SYS_futex, %rax
 	syscall
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S
index c15566fdf0..193cc081e1 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S
@@ -153,9 +153,10 @@ __pthread_cond_wait:
 #endif
 	jne	3f
 
-4:	callq	__pthread_enable_asynccancel
-	movq	%rax, (%rsp)
+4:	movq	%rsp, %edi
+	callq	__pthread_enable_asynccancel_2
 
+	movq	8(%rsp), %rdi
 	xorq	%r10, %r10
 	movq	%r12, %rdx
 	addq	$wakeup_seq-cond_lock, %rdi