about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--nptl/ChangeLog29
-rw-r--r--nptl/pthread_cond_init.c2
-rw-r--r--nptl/sysdeps/pthread/pthread_cond_broadcast.c7
-rw-r--r--nptl/sysdeps/pthread/pthread_cond_timedwait.c6
-rw-r--r--nptl/sysdeps/pthread/pthread_cond_wait.c6
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_broadcast.S11
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S6
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S6
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S10
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S5
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S7
11 files changed, 72 insertions, 23 deletions
diff --git a/nptl/ChangeLog b/nptl/ChangeLog
index 80497111f7..5c9dfa8282 100644
--- a/nptl/ChangeLog
+++ b/nptl/ChangeLog
@@ -1,5 +1,34 @@
 2003-11-21  Ulrich Drepper  <drepper@redhat.com>
 
+	* sysdeps/pthread/pthread_cond_wait.c (__pthread_cond_wait): Don't
+	store mutex address if the current value is ~0l.
+	* sysdeps/pthread/pthread_cond_timedwait.c
+	(__pthread_cond_timedwait): Likewise.
+	* sysdeps/pthread/pthread_cond_broadcast.c
+	(__pthread_cond_broadcast): Don't use requeue for pshared
+	condvars.
+
+	* sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S
+	(__pthread_cond_wait): Don't store mutex address if the current
+	value is ~0l.
+	* sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S
+	(__pthread_cond_timedwait): Likewise.
+	* sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S
+	(__pthread_cond_broadcast): Don't use requeue for pshared
+	condvars.
+
+	* pthread_cond_init.c (__pthread_cond_init): Initialize __mutex
+	element with ~0l for pshared condvars, with NULL otherwise.
+
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S
+	(__pthread_cond_wait): Don't store mutex address if the current
+	value is ~0l.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S
+	(__pthread_cond_timedwait): Likewise.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_cond_broadcast.S
+	(__pthread_cond_broadcast): Don't use requeue for pshared
+	condvars.
+
 	* Makefile: Add rules to build and run tst-cond12 and tst-cond13.
 	* tst-cond12.c: New file.
 	* tst-cond13.c: New file.
diff --git a/nptl/pthread_cond_init.c b/nptl/pthread_cond_init.c
index 73ae4321b0..bb7c6d6ca1 100644
--- a/nptl/pthread_cond_init.c
+++ b/nptl/pthread_cond_init.c
@@ -36,6 +36,8 @@ __pthread_cond_init (cond, cond_attr)
   cond->__data.__total_seq = 0;
   cond->__data.__wakeup_seq = 0;
   cond->__data.__woken_seq = 0;
+  cond->__data.__mutex = (icond_attr == NULL || (icond_attr->value & 1) == 0
+			  ? NULL : (void *) ~0l);
 
   return 0;
 }
diff --git a/nptl/sysdeps/pthread/pthread_cond_broadcast.c b/nptl/sysdeps/pthread/pthread_cond_broadcast.c
index 6c3722a9cd..44c3fe6d5f 100644
--- a/nptl/sysdeps/pthread/pthread_cond_broadcast.c
+++ b/nptl/sysdeps/pthread/pthread_cond_broadcast.c
@@ -54,6 +54,10 @@ __pthread_cond_broadcast (cond)
 # error "No valid byte order"
 #endif
 
+      /* Do not use requeue for pshared condvars.  */
+      if (cond->__data.__mutex == (void *) ~0l)
+	goto wake_all;
+
       /* Wake everybody.  */
       pthread_mutex_t *mut = (pthread_mutex_t *) cond->__data.__mutex;
       if (__builtin_expect (lll_futex_requeue (futex, 1, INT_MAX,
@@ -61,9 +65,8 @@ __pthread_cond_broadcast (cond)
 			    0))
 	{
 	  /* The requeue functionality is not available.  */
-#ifndef __ASSUME_FUTEX_REQUEUE
+	wake_all:
 	  lll_futex_wake (futex, INT_MAX);
-#endif
 	}
 
       /* That's all.  */
diff --git a/nptl/sysdeps/pthread/pthread_cond_timedwait.c b/nptl/sysdeps/pthread/pthread_cond_timedwait.c
index 1655c70c2a..9fa2920f85 100644
--- a/nptl/sysdeps/pthread/pthread_cond_timedwait.c
+++ b/nptl/sysdeps/pthread/pthread_cond_timedwait.c
@@ -67,8 +67,10 @@ __pthread_cond_timedwait (cond, mutex, abstime)
   ++cond->__data.__total_seq;
 
   /* Remember the mutex we are using here.  If there is already a
-     different address store this is a bad user bug.  */
-  cond->__data.__mutex = mutex;
+     different address store this is a bad user bug.  Do not store
+     anything for pshared condvars.  */
+  if (cond->__data.__mutex != (void *) ~0l)
+    cond->__data.__mutex = mutex;
 
   /* Prepare structure passed to cancellation handler.  */
   cbuffer.cond = cond;
diff --git a/nptl/sysdeps/pthread/pthread_cond_wait.c b/nptl/sysdeps/pthread/pthread_cond_wait.c
index 75edf3d158..79c6d9951c 100644
--- a/nptl/sysdeps/pthread/pthread_cond_wait.c
+++ b/nptl/sysdeps/pthread/pthread_cond_wait.c
@@ -93,8 +93,10 @@ __pthread_cond_wait (cond, mutex)
   ++cond->__data.__total_seq;
 
   /* Remember the mutex we are using here.  If there is already a
-     different address store this is a bad user bug.  */
-  cond->__data.__mutex = mutex;
+     different address store this is a bad user bug.  Do not store
+     anything for pshared condvars.  */
+  if (cond->__data.__mutex != (void *) ~0l)
+    cond->__data.__mutex = mutex;
 
   /* Prepare structure passed to cancellation handler.  */
   cbuffer.cond = cond;
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_broadcast.S b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_broadcast.S
index cdcf6d2914..8d09e22afd 100644
--- a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_broadcast.S
+++ b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_broadcast.S
@@ -83,8 +83,12 @@ __pthread_cond_broadcast:
 	subl	$1, cond_lock-wakeup_seq(%ebx)
 	jne	7f
 
+	/* Don't use requeue for pshared condvars.  */
+8:	cmpl	$-1, %edi
+	je	9f
+
 	/* Wake up all threads.  */
-8:	movl	$FUTEX_REQUEUE, %ecx
+	movl	$FUTEX_REQUEUE, %ecx
 	movl	$SYS_futex, %eax
 	movl	$0x7fffffff, %esi
 	movl	$1, %edx
@@ -97,10 +101,9 @@ __pthread_cond_broadcast:
 #ifndef __ASSUME_FUTEX_REQUEUE
 	cmpl	$-EINVAL, %eax
 	je	9f
-10:
 #endif
 
-	xorl	%eax, %eax
+10:	xorl	%eax, %eax
 	popl	%edi
 	popl	%esi
 	popl	%ebx
@@ -138,14 +141,12 @@ __pthread_cond_broadcast:
 	call	__lll_mutex_unlock_wake
 	jmp	8b
 
-#ifndef __ASSUME_FUTEX_REQUEUE
 9:	/* The futex requeue functionality is not available.  */
 	movl	$0x7fffffff, %edx
 	movl	$FUTEX_WAKE, %ecx
 	movl	$SYS_futex, %eax
 	ENTER_KERNEL
 	jmp	10b
-#endif
 	.size	__pthread_cond_broadcast, .-__pthread_cond_broadcast
 versioned_symbol (libpthread, __pthread_cond_broadcast, pthread_cond_broadcast,
 		  GLIBC_2_3_2)
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 ca5c1423c0..06ad11c11b 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
@@ -68,11 +68,13 @@ __pthread_cond_timedwait:
 
 	/* Store the reference to the mutex.  If there is already a
 	   different value in there this is a bad user bug.  */
-2:	movl	24(%esp), %eax
+2:	cmpl	$-1, dep_mutex(%ebx)
+	movl	24(%esp), %eax
+	je	17f
 	movl	%eax, dep_mutex(%ebx)
 
 	/* Unlock the mutex.  */
-	xorl	%edx, %edx
+17:	xorl	%edx, %edx
 	call	__pthread_mutex_unlock_usercnt
 
 	testl	%eax, %eax
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 ff3a1ccef3..b38fd6bf3b 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
@@ -65,11 +65,13 @@ __pthread_cond_wait:
 
 	/* Store the reference to the mutex.  If there is already a
 	   different value in there this is a bad user bug.  */
-2:	movl	20(%esp), %eax
+2:	cmpl	$-1, dep_mutex(%ebx)
+	movl	20(%esp), %eax
+	je	15f
 	movl	%eax, dep_mutex(%ebx)
 
 	/* Unlock the mutex.  */
-	xorl	%edx, %edx
+15:	xorl	%edx, %edx
 	call	__pthread_mutex_unlock_usercnt
 
 	testl	%eax, %eax
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S
index e6b2bbf19c..8e26681b3b 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S
@@ -72,8 +72,11 @@ __pthread_cond_broadcast:
 	decl	cond_lock-wakeup_seq(%rdi)
 	jne	7f
 
+8:	cmpq	$-1, %r8
+	je	9f
+
 	/* Wake up all threads.  */
-8:	movq	$FUTEX_REQUEUE, %rsi
+	movq	$FUTEX_REQUEUE, %rsi
 	movq	$SYS_futex, %rax
 	movl	$1, %edx
 	movq	$0x7fffffff, %r10
@@ -82,10 +85,9 @@ __pthread_cond_broadcast:
 #ifndef __ASSUME_FUTEX_REQUEUE
 	cmpq	$-EINVAL, %rax
 	je	9f
-10:
 #endif
 
-	xorl	%eax, %eax
+10:	xorl	%eax, %eax
 	retq
 
 	.align	16
@@ -119,14 +121,12 @@ __pthread_cond_broadcast:
 	subq	$cond_lock-wakeup_seq, %rdi
 	jmp	8b
 
-#ifndef __ASSUME_FUTEX_REQUEUE
 9:	/* The futex requeue functionality is not available.  */
 	movq	$0x7fffffff, %rdx
 	movq	$FUTEX_WAKE, %rsi
 	movq	$SYS_futex, %rax
 	syscall
 	jmp	10b
-#endif
 	.size	__pthread_cond_broadcast, .-__pthread_cond_broadcast
 versioned_symbol (libpthread, __pthread_cond_broadcast, pthread_cond_broadcast,
 		  GLIBC_2_3_2)
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S
index c0c8f55cfb..e001441490 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S
@@ -71,15 +71,18 @@ __pthread_cond_timedwait:
 	            +--------------------------+
 	*/
 
+	cmpq	$-1, dep_mutex(%rdi)
+
 	/* Prepare structure passed to cancellation handler.  */
 	movq	%rdi, 8(%rsp)
 	movq	%rsi, 16(%rsp)
 	movq	%rdx, %r13
 
+	je	22f
 	movq	%rsi, dep_mutex(%rdi)
 
 	/* Get internal lock.  */
-	movl	$1, %esi
+22:	movl	$1, %esi
 	xorl	%eax, %eax
 	LOCK
 #if cond_lock == 0
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 d8681ebe6b..e572874d7a 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
@@ -117,14 +117,17 @@ __pthread_cond_wait:
 	            +--------------------------+
 	*/
 
-	/* Prepare structure passed to cancellation handler.  */
+	cmpq	$-1, dep_mutex(%rdi)
+
+		/* Prepare structure passed to cancellation handler.  */
 	movq	%rdi, 8(%rsp)
 	movq	%rsi, 16(%rsp)
 
+	je	15f
 	movq	%rsi, dep_mutex(%rdi)
 
 	/* Get internal lock.  */
-	movl	$1, %esi
+15:	movl	$1, %esi
 	xorl	%eax, %eax
 	LOCK
 #if cond_lock == 0