diff --git a/nptl/ChangeLog b/nptl/ChangeLog index 719d781d3a..44f9846365 100644 --- a/nptl/ChangeLog +++ b/nptl/ChangeLog @@ -3,6 +3,8 @@ * sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedwrlock.S (pthread_rwlock_timedwrlock): If possible use FUTEX_WAIT_BITSET to directly use absolute timeout. + * sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedrdlock.S + (pthread_rwlock_timedrdlock): Likewise. * 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_timedrdlock.S b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedrdlock.S index 366c96fc36..23b218af34 100644 --- a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedrdlock.S +++ b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedrdlock.S @@ -1,4 +1,4 @@ -/* Copyright (C) 2002, 2003, 2004, 2005, 2007 Free Software Foundation, Inc. +/* Copyright (C) 2002-2005, 2007, 2009 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 2002. @@ -36,16 +36,21 @@ pthread_rwlock_timedrdlock: 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 @@ -76,7 +81,7 @@ pthread_rwlock_timedrdlock: incl READERS_QUEUED(%r12) je 4f - movl READERS_WAKEUP(%r12), %r14d + movl READERS_WAKEUP(%r12), VALREG /* Unlock. */ LOCK @@ -87,8 +92,33 @@ pthread_rwlock_timedrdlock: #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 READERS_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 @@ -111,27 +141,26 @@ pthread_rwlock_timedrdlock: movq %rcx, (%rsp) /* Store relative timeout. */ movq %rdi, 8(%rsp) -#ifdef __ASSUME_PRIVATE_FUTEX +# ifdef __ASSUME_PRIVATE_FUTEX movl $FUTEX_PRIVATE_FLAG|FUTEX_WAIT, %esi xorl PSHARED(%r12), %esi -#else -# if FUTEX_WAIT == 0 - movl PSHARED(%r12), %esi # else +# if FUTEX_WAIT == 0 + movl PSHARED(%r12), %esi +# else movl $FUTEX_WAIT, %esi orl PSHARED(%r12), %esi -# endif +# endif xorl %fs:PRIVATE_FUTEX, %esi -#endif +# endif movq %rsp, %r10 movl %r14d, %edx - leaq READERS_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 @@ -163,11 +192,13 @@ pthread_rwlock_timedrdlock: 7: movq %rdx, %rax +#ifndef __ASSUME_FUTEX_CLOCK_REALTIME 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) @@ -176,10 +207,16 @@ pthread_rwlock_timedrdlock: 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