aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2003-03-12 08:57:35 +0000
committerUlrich Drepper <drepper@redhat.com>2003-03-12 08:57:35 +0000
commit35e148cb96ec7e34c206c80888f18f52859b8d5f (patch)
tree5a40b38bab8d8a58badf0aa526d33066ff0a2c65
parenta3cd7da30f9ac88b43c913ef0c5b5a014e0dd2e7 (diff)
downloadglibc-35e148cb96ec7e34c206c80888f18f52859b8d5f.tar
glibc-35e148cb96ec7e34c206c80888f18f52859b8d5f.tar.gz
glibc-35e148cb96ec7e34c206c80888f18f52859b8d5f.tar.bz2
glibc-35e148cb96ec7e34c206c80888f18f52859b8d5f.zip
Update.
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.
-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. */