about summary refs log tree commit diff
path: root/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_signal.S
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2003-05-26 02:47:39 +0000
committerUlrich Drepper <drepper@redhat.com>2003-05-26 02:47:39 +0000
commit69431c9a21f7393f34330a27df1630520930789e (patch)
tree1fbd3f1520502c833e676afa3fb5410f92654f85 /nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_signal.S
parent6a998b09ec734d8dd40e690244122a43bf9d7a16 (diff)
downloadglibc-69431c9a21f7393f34330a27df1630520930789e.tar.gz
glibc-69431c9a21f7393f34330a27df1630520930789e.tar.xz
glibc-69431c9a21f7393f34330a27df1630520930789e.zip
Update.
2003-05-25  Ulrich Drepper  <drepper@redhat.com>

	* sysdeps/unix/sysv/linux/kernel-features.h: Define
	__ASSUME_FUTEX_REQUEUE for >= 2.5.70.

	* math/test-fenv.c (feexcp_nomask_test): Fix comment.
Diffstat (limited to 'nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_signal.S')
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_signal.S55
1 files changed, 43 insertions, 12 deletions
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_signal.S b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_signal.S
index 5465d7b2a8..ed25c554d2 100644
--- a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_signal.S
+++ b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_signal.S
@@ -20,6 +20,7 @@
 #include <sysdep.h>
 #include <shlib-compat.h>
 #include <lowlevelcond.h>
+#include <kernel-features.h>
 
 #ifdef UP
 # define LOCK
@@ -30,6 +31,9 @@
 #define SYS_futex		240
 #define FUTEX_WAIT		0
 #define FUTEX_WAKE		1
+#define FUTEX_REQUEUE		3
+
+#define EINVAL			22
 
 
 	.text
@@ -41,23 +45,25 @@
 __pthread_cond_signal:
 
 	pushl	%ebx
+	pushl	%esi
+	pushl	%edi
 
-	movl	8(%esp), %ebx
+	movl	16(%esp), %edi
 
 	/* Get internal lock.  */
 	movl	$1, %eax
 	LOCK
 #if cond_lock == 0
-	xaddl	%eax, (%ebx)
+	xaddl	%eax, (%edi)
 #else
-	xaddl	%eax, cond_lock(%ebx)
+	xaddl	%eax, cond_lock(%edi)
 #endif
 	testl	%eax, %eax
 	jne	1f
 
-2:	addl	$wakeup_seq, %ebx
-	movl	total_seq+4-wakeup_seq(%ebx), %eax
-	movl	total_seq-wakeup_seq(%ebx), %ecx
+2:	leal	wakeup_seq(%edi), %ebx
+	movl	total_seq+4(%edi), %eax
+	movl	total_seq(%edi), %ecx
 	cmpl	4(%ebx), %eax
 	ja	3f
 	jb	4f
@@ -68,18 +74,30 @@ __pthread_cond_signal:
 3:	addl	$1, (%ebx)
 	adcl	$0, 4(%ebx)
 
-	/* Wake up one thread.  */
-	movl	$FUTEX_WAKE, %ecx
+	/* Wake up one thread by moving it to the internal lock futex.  */
+	movl	$FUTEX_REQUEUE, %ecx
 	movl	$SYS_futex, %eax
-	movl	%ecx, %edx	/* movl $1, %edx */
+	xorl	%edx, %edx
+	movl	$1, %esi
 	ENTER_KERNEL
 
+#ifndef __ASSUME_FUTEX_REQUEUE
+	cmpl	$-EINVAL, %eax
+	je	7f
+#endif
+
+	/* If we moved a thread we in any case have to make the syscall.  */
+	testl	%eax, %eax
+	jne	5f
+
 	/* Unlock.  */
 4:	LOCK
-	subl	$1, cond_lock-wakeup_seq(%ebx)
+	subl	$1, (%edi)
 	jne	5f
 
 6:	xorl	%eax, %eax
+	popl	%edi
+	popl	%esi
 	popl	%ebx
 	ret
 
@@ -93,11 +111,24 @@ __pthread_cond_signal:
 	call	__lll_mutex_lock_wait
 	jmp	2b
 
-	/* Unlock in loop requires waekup.  */
+	/* Unlock in loop requires wakeup.  */
 5:
-	leal	cond_lock-wakeup_seq(%ebx), %eax
+#if cond_lock == 0
+	movl	%edi, %eax
+#else
+	leal	cond_lock(%edi), %eax
+#endif
 	call	__lll_mutex_unlock_wake
 	jmp	6b
+
+#ifndef __ASSUME_FUTEX_REQUEUE
+7:	/* The futex requeue functionality is not available.  */
+	movl	$1, %edx
+	movl	$FUTEX_WAKE, %ecx
+	movl	$SYS_futex, %eax
+	ENTER_KERNEL
+	jmp	4b
+#endif
 	.size	__pthread_cond_signal, .-__pthread_cond_signal
 versioned_symbol (libpthread, __pthread_cond_signal, pthread_cond_signal,
 		  GLIBC_2_3_2)