aboutsummaryrefslogtreecommitdiff
path: root/nptl
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2009-07-18 21:35:33 -0700
committerUlrich Drepper <drepper@redhat.com>2009-07-18 21:35:33 -0700
commitd979611eb9f18ead1b8da3e956b941545f682565 (patch)
treebcac2db9118fd2276fb73651816309c138c8e2aa /nptl
parentd9201c13656dc73fba9c5f5f96c3d0e2c7971218 (diff)
downloadglibc-d979611eb9f18ead1b8da3e956b941545f682565.zip
glibc-d979611eb9f18ead1b8da3e956b941545f682565.tar.gz
glibc-d979611eb9f18ead1b8da3e956b941545f682565.tar.bz2
Extend x86-64 pthread_rwlock_timedwrlock to use futex syscall with absolute timeout.
Diffstat (limited to 'nptl')
-rw-r--r--nptl/ChangeLog4
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedwrlock.S61
2 files changed, 53 insertions, 12 deletions
diff --git a/nptl/ChangeLog b/nptl/ChangeLog
index d5b812e..719d781 100644
--- a/nptl/ChangeLog
+++ b/nptl/ChangeLog
@@ -1,5 +1,9 @@
2009-07-18 Ulrich Drepper <drepper@redhat.com>
+ * sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedwrlock.S
+ (pthread_rwlock_timedwrlock): If possible use FUTEX_WAIT_BITSET to
+ directly use absolute timeout.
+
* tst-cond11.c (run_test): Add test to check that the timeout is
long enough.
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedwrlock.S b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedwrlock.S
index dde6b58..bfc653d 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedwrlock.S
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedwrlock.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2005, 2007 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2005, 2007, 2009 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@@ -36,16 +36,21 @@ pthread_rwlock_timedwrlock:
cfi_startproc
pushq %r12
cfi_adjust_cfa_offset(8)
+ cfi_rel_offset(%r12, 0)
pushq %r13
cfi_adjust_cfa_offset(8)
+ cfi_rel_offset(%r13, 0)
+#ifdef __ASSUME_FUTEX_CLOCK_REALTIME
+# define VALREG %edx
+#else
pushq %r14
cfi_adjust_cfa_offset(8)
- cfi_offset(%r12, -16)
- cfi_offset(%r13, -24)
- cfi_offset(%r14, -32)
+ cfi_rel_offset(%r14, 0)
subq $16, %rsp
cfi_adjust_cfa_offset(16)
+# define VALREG %r14d
+#endif
movq %rdi, %r12
movq %rsi, %r13
@@ -74,7 +79,7 @@ pthread_rwlock_timedwrlock:
incl WRITERS_QUEUED(%r12)
je 4f
- movl WRITERS_WAKEUP(%r12), %r14d
+ movl WRITERS_WAKEUP(%r12), VALREG
LOCK
#if MUTEX == 0
@@ -84,8 +89,33 @@ pthread_rwlock_timedwrlock:
#endif
jne 10f
+11:
+#ifndef __ASSUME_FUTEX_CLOCK_REALTIME
+# ifdef PIC
+ cmpl $0, __have_futex_clock_realtime(%rip)
+# else
+ cmpl $0, __have_futex_clock_realtime
+# endif
+ je .Lreltmo
+#endif
+
+ movl $FUTEX_PRIVATE_FLAG|FUTEX_WAIT_BITSET|FUTEX_CLOCK_REALTIME, %esi
+ xorl PSHARED(%r12), %esi
+ movq %r13, %r10
+ movl $0xffffffff, %r9d
+#ifndef __ASSUME_FUTEX_CLOCK_REALTIME
+ movl %r14d, %edx
+#endif
+21: leaq WRITERS_WAKEUP(%r12), %rdi
+ movl $SYS_futex, %eax
+ syscall
+ movq %rax, %rdx
+
+#ifndef __ASSUME_FUTEX_CLOCK_REALTIME
+ .subsection 2
+.Lreltmo:
/* Get current time. */
-11: movq %rsp, %rdi
+ movq %rsp, %rdi
xorl %esi, %esi
movq $VSYSCALL_ADDR_vgettimeofday, %rax
callq *%rax
@@ -122,13 +152,12 @@ pthread_rwlock_timedwrlock:
#endif
movq %rsp, %r10
movl %r14d, %edx
- leaq WRITERS_WAKEUP(%r12), %rdi
- movl $SYS_futex, %eax
- syscall
- movq %rax, %rdx
-17:
- /* Reget the lock. */
+ jmp 21b
+ .previous
+#endif
+
+17: /* Reget the lock. */
movl $1, %esi
xorl %eax, %eax
LOCK
@@ -160,11 +189,13 @@ pthread_rwlock_timedwrlock:
7: movq %rdx, %rax
+#ifndef __ASSUME_PRIVATE_FUTEX
addq $16, %rsp
cfi_adjust_cfa_offset(-16)
popq %r14
cfi_adjust_cfa_offset(-8)
cfi_restore(%r14)
+#endif
popq %r13
cfi_adjust_cfa_offset(-8)
cfi_restore(%r13)
@@ -173,10 +204,16 @@ pthread_rwlock_timedwrlock:
cfi_restore(%r12)
retq
+#ifdef __ASSUME_PRIVATE_FUTEX
+ cfi_adjust_cfa_offset(16)
+ cfi_rel_offset(%r12, 8)
+ cfi_rel_offset(%r13, 0)
+#else
cfi_adjust_cfa_offset(40)
cfi_offset(%r12, -16)
cfi_offset(%r13, -24)
cfi_offset(%r14, -32)
+#endif
1: movl PSHARED(%rdi), %esi
#if MUTEX != 0
addq $MUTEX, %rdi