about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--nptl/ChangeLog16
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_rdlock.S2
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedrdlock.S2
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedwrlock.S2
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_wrlock.S2
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S253
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S8
7 files changed, 275 insertions, 10 deletions
diff --git a/nptl/ChangeLog b/nptl/ChangeLog
index ac1b2af78d..6ba843a9a3 100644
--- a/nptl/ChangeLog
+++ b/nptl/ChangeLog
@@ -1,3 +1,19 @@
+2003-03-12  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedwrlock.S
+	(__pthread_rwlock_timedwrlock): Add missing opcode suffix.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedrdlock.S
+	(__pthread_rwlock_timedrdlock): Likewise.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_wrlock.S
+	(__pthread_rwlock_wrlock): Likewise.
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_rdlock.S
+	(__pthread_rwlock_rdlock): Likewise.
+
+	* sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S: New file.
+
+	* sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S: Return
+	result of lock re-get if it fails.
+
 2003-03-11  Ulrich Drepper  <drepper@redhat.com>
 
 	* sysdeps/unix/sysv/linux/x86_64/lowlevellock.S: Fix asm syntax.
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_rdlock.S b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_rdlock.S
index 1ddc6bb323..43d00a2300 100644
--- a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_rdlock.S
+++ b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_rdlock.S
@@ -61,7 +61,7 @@ __pthread_rwlock_rdlock:
 2:	movl	WRITER(%ebx), %eax
 	testl	%eax, %eax
 	jne	14f
-	cmp	$0, WRITERS_QUEUED(%ebx)
+	cmpl	$0, WRITERS_QUEUED(%ebx)
 	je	5f
 	cmpl	$0, FLAGS(%ebx)
 	je	5f
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedrdlock.S b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedrdlock.S
index a69e857a14..a0b2734280 100644
--- a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedrdlock.S
+++ b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedrdlock.S
@@ -67,7 +67,7 @@ pthread_rwlock_timedrdlock:
 2:	movl	WRITER(%ebp), %eax
 	testl	%eax, %eax
 	jne	14f
-	cmp	$0, WRITERS_QUEUED(%ebp)
+	cmpl	$0, WRITERS_QUEUED(%ebp)
 	je	5f
 	cmpl	$0, FLAGS(%ebp)
 	je	5f
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedwrlock.S b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedwrlock.S
index bd812263f1..8c6245afb7 100644
--- a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedwrlock.S
+++ b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedwrlock.S
@@ -67,7 +67,7 @@ pthread_rwlock_timedwrlock:
 2:	movl	WRITER(%ebp), %eax
 	testl	%eax, %eax
 	jne	14f
-	cmp	$0, NR_READERS(%ebp)
+	cmpl	$0, NR_READERS(%ebp)
 	je	5f
 
 	/* Check the value of the timeout parameter.  */
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_wrlock.S b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_wrlock.S
index 939a3176e0..0455372343 100644
--- a/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_wrlock.S
+++ b/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_wrlock.S
@@ -61,7 +61,7 @@ __pthread_rwlock_wrlock:
 2:	movl	WRITER(%ebx), %eax
 	testl	%eax, %eax
 	jne	14f
-	cmp	$0, NR_READERS(%ebx)
+	cmpl	$0, NR_READERS(%ebx)
 	je	5f
 
 3:	addl	$1, WRITERS_QUEUED(%ebx)
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
new file mode 100644
index 0000000000..d059e64945
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S
@@ -0,0 +1,253 @@
+/* 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.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep.h>
+#include <shlib-compat.h>
+#include <lowlevelcond.h>
+
+#ifdef UP
+# define LOCK
+#else
+# define LOCK lock
+#endif
+
+#define SYS_gettimeofday	__NR_gettimeofday
+#define SYS_futex		202
+#define FUTEX_WAIT		0
+#define FUTEX_WAKE		1
+
+#define ETIMEDOUT		110
+
+
+	.text
+
+/* int pthread_cond_timedwait (pthread_cond_t *cond, pthread_mutex_t *mutex,
+			       const struct timespec *abstime)  */
+	.globl	__pthread_cond_timedwait
+	.type	__pthread_cond_timedwait, @function
+	.align	16
+__pthread_cond_timedwait:
+	pushq	%r12
+	pushq	%r13
+	pushq	%r14
+	subq	$80, %rsp
+
+	/* Prepare structure passed to cancellation handler.  */
+	movq	%rdi, 8(%rsp)
+	movq	%rsi, 16(%rsp)
+	movq	%rdx, %r13
+
+	/* Get internal lock.  */
+	movl	$1, %esi
+	LOCK
+#if cond_lock == 0
+	xaddl	%esi, (%rdi)
+#else
+	xaddl	%esi, cond_lock(%rdi)
+#endif
+	testl	%esi, %esi
+	jne	1f
+
+	/* Unlock the mutex.  */
+2:	movq	16(%rsp), %rdi
+	callq	__pthread_mutex_unlock_internal
+
+	testl	%eax, %eax
+	jne	16f
+
+	movq	8(%rsp), %rdi
+	addq	$1, total_seq(%rdi)
+
+	/* Install cancellation handler.  */
+#ifdef PIC
+	leaq	__condvar_cleanup(%rip), %rsi
+#else
+	leaq	__condvar_cleanup, %rsi
+#endif
+	leaq	48(%rsp), %rdi
+	movq	%rsp, %rdx
+	callq	__pthread_cleanup_push
+
+	/* Get and store current wakeup_seq value.  */
+	movq	8(%rsp), %rdi
+	movq	wakeup_seq(%rdi), %r12
+	movq	%r12, 40(%rsp)
+
+	/* Unlock.  */
+8:	LOCK
+#if cond_lock == 0
+	decl	(%rdi)
+#else
+	decl	cond_lock(%rdi)
+#endif
+	jne	3f
+
+4:	movq	%rsp, %rdi
+	call	__pthread_enable_asynccancel_2
+
+	/* Get the current time.  */
+	leaq	24(%rsp), %rdi
+	xorq	%rcx, %rcx
+	movq	$SYS_gettimeofday, %rax
+	syscall
+
+	/* Compute relative timeout.  */
+	movq	32(%rsp), %rax
+	movq	$1000, %rdx
+	mul	%rdx		/* Milli seconds to nano seconds.  */
+	movq	(%r13), %rcx
+	movq	4(%r13), %rdx
+	subq	24(%rsp), %rcx
+	subq	%rax, %rdx
+	jns	12f
+	addq	$1000000000, %rdx
+	decq	%rcx
+12:	testq	%rcx, %rcx
+	js	13f
+
+	/* Store relative timeout.  */
+	movq	%rcx, 24(%rsp)
+	movq	%rdx, 32(%rsp)
+
+	movq	8(%rsp), %rdi
+	leaq	24(%rsp), %r10
+	xorq	%rsi, %rsi	/* movq $FUTEX_WAIT, %rsi */
+	movq	%r12, %rdx
+	addq	$wakeup_seq-cond_lock, %rdi
+	movq	$SYS_futex, %rax
+	syscall
+	movq	%rax, %r14
+
+	movq	(%rsp), %rdi
+	callq	__pthread_disable_asynccancel
+
+	/* Lock.  */
+	movq	8(%rsp), %rdi
+	movl	$1, %esi
+	LOCK
+#if cond_lock == 0
+	xaddl	%esi, (%rdi)
+#else
+	xaddl	%esi, cond_lock(%rdi)
+#endif
+	testl	%esi, %esi
+	jne	5f
+
+6:	movq	woken_seq(%rdi), %rax
+
+	movq	wakeup_seq(%rdi), %r12
+
+	cmpq	40(%rsp), %rax
+	jb	15f
+
+	cmpq	%rax, %r12
+	ja	9f
+
+15:	cmpq	$-ETIMEDOUT, %r14
+	jne	8b
+
+13:	incq	wakeup_seq(%rdi)
+	movq	$ETIMEDOUT, %rsi
+	jmp	14f
+
+9:	xorq	%rsi, %rsi
+14:	incq	woken_seq(%rdi)
+
+	LOCK
+#if cond_lock == 0
+	decl	(%rdi)
+#else
+	decl	cond_lock(%rdi)
+#endif
+	jne	10f
+
+	/* Remove cancellation handler.  */
+11:	movq	48+CLEANUP_PREV(%rsp), %rdx
+	movq	%rdx, %fs:CLEANUP
+
+	movq	16(%rsp), %rdi
+	callq	__pthread_mutex_lock_internal
+
+	testq	%rax, %rax
+	cmoveq	%rsi, %rax
+
+18:	addq	$80, %rsp
+	popq	%r14
+	popq	%r13
+	popq	%r12
+
+	retq
+
+	/* Initial locking failed.  */
+1:
+#if cond_lock != 0
+	addq	$cond_lock, %rdi
+#endif
+	call	__lll_mutex_lock_wait
+	jmp	2b
+
+	/* Unlock in loop requires waekup.  */
+3:
+#if cond_lock != 0
+	addq	$cond_lock, %rdi
+#endif
+	call	__lll_mutex_unlock_wake
+	jmp	4b
+
+	/* Locking in loop failed.  */
+5:
+#if cond_lock != 0
+	addq	$cond_lock, %rdi
+#endif
+	call	__lll_mutex_lock_wait
+#if cond_lock != 0
+	subq	$cond_lock, %rdi
+#endif
+	jmp	6b
+
+	/* Unlock after loop requires waekup.  */
+10:
+#if cond_lock != 0
+	addq	$cond_lock, %rdi
+#endif
+	call	__lll_mutex_unlock_wake
+	jmp	11b
+
+	/* The initial unlocking of the mutex failed.  */
+16:	movq	8(%rsp), %rdi
+	movq	%rax, (%rsp)
+	LOCK
+#if cond_lock == 0
+	decl	(%rdi)
+#else
+	decl	cond_lock(%rdi)
+#endif
+	jne	17f
+
+#if cond_lock != 0
+	addq	$cond_lock, %rdi
+#endif
+	call	__lll_mutex_unlock_wake
+
+17:	movq	(%rsp), %rax
+	jmp	18b
+	.size	__pthread_cond_wait, .-__pthread_cond_wait
+	.size	__pthread_cond_timedwait, .-__pthread_cond_timedwait
+versioned_symbol (libpthread, __pthread_cond_timedwait, pthread_cond_timedwait,
+		  GLIBC_2_3_2)
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 831d4f9c90..5b6f1ea0a7 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
@@ -126,7 +126,7 @@ __pthread_cond_wait:
 	testl	%eax, %eax
 	jne	12f
 
-	movq	(%rsp), %rdi
+	movq	8(%rsp), %rdi
 	addq	$1, total_seq(%rdi)
 
 	/* Install cancellation handler.  */
@@ -163,7 +163,6 @@ __pthread_cond_wait:
 	movq	$SYS_futex, %rax
 	movq	%r10, %rsi	/* movl $FUTEX_WAIT, %ecx */
 	syscall
-	subl	$wakeup_seq-cond_lock, %ebx
 
 	movq	(%rsp), %rdi
 	callq	__pthread_disable_asynccancel
@@ -202,7 +201,7 @@ __pthread_cond_wait:
 
 	/* Remove cancellation handler.  */
 11:	movq	32+CLEANUP_PREV(%rsp), %rdx
-	movq	%rdx, %gs:CLEANUP
+	movq	%rdx, %fs:CLEANUP
 
 	movq	16(%rsp), %rdi
 	callq	__pthread_mutex_lock_internal
@@ -227,9 +226,6 @@ __pthread_cond_wait:
 	addq	$cond_lock, %rdi
 #endif
 	callq	__lll_mutex_unlock_wake
-#if cond_lock != 0
-	subq	$cond_lock, %rdi
-#endif
 	jmp	4b
 
 	/* Locking in loop failed.  */