diff options
author | Ulrich Drepper <drepper@redhat.com> | 2009-07-19 00:00:17 -0700 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2009-07-19 00:00:17 -0700 |
commit | e2dca2fea3f1a0a7b05fd10589f469496f9c42a3 (patch) | |
tree | 5bfac45ae82c8ee580e5082cda7fc17950558172 /nptl/sysdeps | |
parent | 3d77b2687f984700f40e26e0fb06c99eeea1c033 (diff) | |
download | glibc-e2dca2fea3f1a0a7b05fd10589f469496f9c42a3.tar.gz glibc-e2dca2fea3f1a0a7b05fd10589f469496f9c42a3.tar.xz glibc-e2dca2fea3f1a0a7b05fd10589f469496f9c42a3.zip |
Extend x86-64 __lll_robust_timedlock_wait to use futex syscall with absolute timeout.
Diffstat (limited to 'nptl/sysdeps')
-rw-r--r-- | nptl/sysdeps/unix/sysv/linux/x86_64/lowlevelrobustlock.S | 78 |
1 files changed, 76 insertions, 2 deletions
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevelrobustlock.S b/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevelrobustlock.S index fa7516ef71..02db0a4f9d 100644 --- a/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevelrobustlock.S +++ b/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevelrobustlock.S @@ -1,4 +1,4 @@ -/* Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 +/* Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2009 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. @@ -32,6 +32,8 @@ #ifdef __ASSUME_PRIVATE_FUTEX # define LOAD_FUTEX_WAIT(reg) \ xorl $(FUTEX_WAIT | FUTEX_PRIVATE_FLAG), reg +# define LOAD_FUTEX_WAIT_ABS(reg) \ + xorl $(FUTEX_WAIT_BITSET | FUTEX_PRIVATE_FLAG | FUTEX_CLOCK_REALTIME), reg #else # if FUTEX_WAIT == 0 # define LOAD_FUTEX_WAIT(reg) \ @@ -43,6 +45,10 @@ andl %fs:PRIVATE_FUTEX, reg ; \ orl $FUTEX_WAIT, reg # endif +# define LOAD_FUTEX_WAIT_ABS(reg) \ + xorl $FUTEX_PRIVATE_FLAG, reg ; \ + andl %fs:PRIVATE_FUTEX, reg ; \ + orl $FUTEX_WAIT_BITSET | FUTEX_CLOCK_REALTIME, reg #endif /* For the calculation see asm/vsyscall.h. */ @@ -110,6 +116,73 @@ __lll_robust_lock_wait: .align 16 __lll_robust_timedlock_wait: cfi_startproc +# 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 + + pushq %r9 + cfi_adjust_cfa_offset(8) + cfi_rel_offset(%r9, 0) + movq %rdx, %r10 + movl $0xffffffff, %r9d + LOAD_FUTEX_WAIT_ABS (%esi) + +1: testl $FUTEX_OWNER_DIED, %eax + jnz 3f + + movl %eax, %edx + orl $FUTEX_WAITERS, %edx + + cmpl %eax, %edx + je 5f + + LOCK + cmpxchgl %edx, (%rdi) + movq $0, %rcx /* Must use mov to avoid changing cc. */ + jnz 6f + +5: movl $SYS_futex, %eax + syscall + movl %eax, %ecx + + movl (%rdi), %eax + +6: testl %eax, %eax + jne 2f + + movl %fs:TID, %edx + orl $FUTEX_WAITERS, %edx + LOCK + cmpxchgl %edx, (%rdi) + jnz 2f + +3: popq %r9 + cfi_adjust_cfa_offset(-8) + cfi_restore(%r9) + retq + + cfi_adjust_cfa_offset(8) + cfi_rel_offset(%r9, 0) + /* Check whether the time expired. */ +2: cmpl $-ETIMEDOUT, %ecx + je 4f + cmpl $-EINVAL, %ecx + jne 1b + +4: movl %ecx, %eax + negl %eax + jmp 3b + cfi_adjust_cfa_offset(-8) + cfi_restore(%r9) + + +# ifndef __ASSUME_FUTEX_CLOCK_REALTIME +.Lreltmo: /* Check for a valid timeout value. */ cmpq $1000000000, 8(%rdx) jae 3f @@ -223,10 +296,11 @@ __lll_robust_timedlock_wait: cfi_offset(%r12, -32) cfi_offset(%r13, -40) /* Check whether the time expired. */ -7: cmpq $-ETIMEDOUT, %rcx +7: cmpl $-ETIMEDOUT, %ecx jne 1b 8: movl $ETIMEDOUT, %eax jmp 6b +#endif cfi_endproc .size __lll_robust_timedlock_wait,.-__lll_robust_timedlock_wait |