diff options
Diffstat (limited to 'libc/nptl/sysdeps/unix/sysv')
8 files changed, 158 insertions, 26 deletions
diff --git a/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/lowlevellock.S b/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/lowlevellock.S index 9c8a68f5b..056b72900 100644 --- a/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/lowlevellock.S +++ b/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/lowlevellock.S @@ -1,4 +1,4 @@ -/* Copyright (C) 2002, 2003, 2004, 2006, 2007 Free Software Foundation, Inc. +/* Copyright (C) 2002-2004, 2006, 2007, 2009 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. @@ -31,6 +31,8 @@ movl $(FUTEX_WAKE | FUTEX_PRIVATE_FLAG), reg # 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 # define LOAD_FUTEX_WAKE(reg) \ xorl $(FUTEX_WAKE | FUTEX_PRIVATE_FLAG), reg #else @@ -55,6 +57,10 @@ andl %gs:PRIVATE_FUTEX, reg ; \ orl $FUTEX_WAIT, reg # endif +# define LOAD_FUTEX_WAIT_ABS(reg) \ + xorl $FUTEX_PRIVATE_FLAG, reg ; \ + andl %gs:PRIVATE_FUTEX, reg ; \ + orl $FUTEX_WAIT | FUTEX_CLOCK_REALTIME, reg # define LOAD_FUTEX_WAKE(reg) \ xorl $FUTEX_PRIVATE_FLAG, reg ; \ andl %gs:PRIVATE_FUTEX, reg ; \ @@ -154,28 +160,81 @@ __lll_lock_wait: cfi_endproc .size __lll_lock_wait,.-__lll_lock_wait + /* %ecx: futex + %esi: flags + %edx: timeout + %eax: futex value + */ .globl __lll_timedlock_wait .type __lll_timedlock_wait,@function .hidden __lll_timedlock_wait .align 16 __lll_timedlock_wait: cfi_startproc + pushl %ebp + cfi_adjust_cfa_offset(4) + cfi_rel_offset(%ebp, 0) + pushl %ebx + cfi_adjust_cfa_offset(4) + cfi_rel_offset(%ebx, 0) + +# ifndef __ASSUME_FUTEX_CLOCK_REALTIME +# ifdef PIC + LOAD_PIC_REG (bx) + cmpl $0, __have_futex_clock_realtime@GOTOFF(%ebx) +# else + cmpl $0, __have_futex_clock_realtime +# endif + je .Lreltmo +# endif + + movl %ecx, %ebx + movl %esi, %ecx + movl %edx, %esi + movl $0xffffffff, %ebp + LOAD_FUTEX_WAIT_ABS (%ecx) + + movl $2, %edx + cmpl %edx, %eax + jne 2f + +1: movl $SYS_futex, %eax + movl $2, %edx + ENTER_KERNEL + +2: xchgl %edx, (%ebx) /* NB: lock is implied */ + + testl %edx, %edx + jz 3f + + cmpl $-ETIMEDOUT, %eax + je 4f + cmpl $-EINVAL, %eax + jne 1b +4: movl %eax, %edx + negl %edx + +3: movl %edx, %eax +7: popl %ebx + cfi_adjust_cfa_offset(-4) + cfi_restore(%ebx) + popl %ebp + cfi_adjust_cfa_offset(-4) + cfi_restore(%ebp) + ret + +# ifndef __ASSUME_FUTEX_CLOCK_REALTIME +.Lreltmo: /* Check for a valid timeout value. */ cmpl $1000000000, 4(%edx) jae 3f - pushl %edi - cfi_adjust_cfa_offset(4) pushl %esi cfi_adjust_cfa_offset(4) - pushl %ebx - cfi_adjust_cfa_offset(4) - pushl %ebp + cfi_rel_offset(%esi, 0) + pushl %edi cfi_adjust_cfa_offset(4) - cfi_offset(%edi, -8) - cfi_offset(%esi, -12) - cfi_offset(%ebx, -16) - cfi_offset(%ebp, -20) + cfi_rel_offset(%edi, 0) /* Stack frame for the timespec and timeval structs. */ subl $8, %esp @@ -236,23 +295,24 @@ __lll_timedlock_wait: 6: addl $8, %esp cfi_adjust_cfa_offset(-8) - popl %ebp - cfi_adjust_cfa_offset(-4) - cfi_restore(%ebp) - popl %ebx + popl %edi cfi_adjust_cfa_offset(-4) - cfi_restore(%ebx) + cfi_restore(%edi) popl %esi cfi_adjust_cfa_offset(-4) cfi_restore(%esi) - popl %edi +7: popl %ebx cfi_adjust_cfa_offset(-4) - cfi_restore(%edi) + cfi_restore(%ebx) + popl %ebp + cfi_adjust_cfa_offset(-4) + cfi_restore(%ebp) movl %edx, %eax ret -3: movl $EINVAL, %eax - ret +3: movl $EINVAL, %edx + jmp 7b +# endif cfi_endproc .size __lll_timedlock_wait,.-__lll_timedlock_wait #endif diff --git a/libc/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h b/libc/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h index 993dd4be2..66e0e628f 100644 --- a/libc/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h +++ b/libc/nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2004, 2006, 2007, 2008 Free Software Foundation, Inc. +/* Copyright (C) 2002-2004, 2006-2008, 2009 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. @@ -55,6 +55,9 @@ #define FUTEX_WAIT_BITSET 9 #define FUTEX_WAKE_BITSET 10 #define FUTEX_PRIVATE_FLAG 128 +#define FUTEX_CLOCK_REALTIME 256 + +#define FUTEX_BITSET_MATCH_ANY 0xffffffff #define FUTEX_OP_CLEAR_WAKE_IF_GT_ONE ((4 << 24) | 1) diff --git a/libc/nptl/sysdeps/unix/sysv/linux/ia64/lowlevellock.h b/libc/nptl/sysdeps/unix/sysv/linux/ia64/lowlevellock.h index 9c4d16f45..b419c9a5e 100644 --- a/libc/nptl/sysdeps/unix/sysv/linux/ia64/lowlevellock.h +++ b/libc/nptl/sysdeps/unix/sysv/linux/ia64/lowlevellock.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2003, 2004, 2006, 2007, 2008 Free Software Foundation, Inc. +/* Copyright (C) 2003, 2004, 2006-2008, 2009 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Jakub Jelinek <jakub@redhat.com>, 2003. @@ -40,6 +40,9 @@ #define FUTEX_WAIT_BITSET 9 #define FUTEX_WAKE_BITSET 10 #define FUTEX_PRIVATE_FLAG 128 +#define FUTEX_CLOCK_REALTIME 256 + +#define FUTEX_BITSET_MATCH_ANY 0xffffffff /* Values for 'private' parameter of locking macros. Yes, the definition seems to be backwards. But it is not. The bit will be diff --git a/libc/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h b/libc/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h index 76a41bc19..66c02cbbd 100644 --- a/libc/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h +++ b/libc/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2003, 2004, 2006, 2007, 2008 Free Software Foundation, Inc. +/* Copyright (C) 2003, 2004, 2006-2008, 2009 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Paul Mackerras <paulus@au.ibm.com>, 2003. @@ -41,6 +41,9 @@ #define FUTEX_WAIT_BITSET 9 #define FUTEX_WAKE_BITSET 10 #define FUTEX_PRIVATE_FLAG 128 +#define FUTEX_CLOCK_REALTIME 256 + +#define FUTEX_BITSET_MATCH_ANY 0xffffffff /* Values for 'private' parameter of locking macros. Yes, the definition seems to be backwards. But it is not. The bit will be diff --git a/libc/nptl/sysdeps/unix/sysv/linux/pthread_mutex_cond_lock.c b/libc/nptl/sysdeps/unix/sysv/linux/pthread_mutex_cond_lock.c index 93841c5b3..b417da5e2 100644 --- a/libc/nptl/sysdeps/unix/sysv/linux/pthread_mutex_cond_lock.c +++ b/libc/nptl/sysdeps/unix/sysv/linux/pthread_mutex_cond_lock.c @@ -8,6 +8,7 @@ lll_robust_cond_lock ((mutex)->__data.__lock, id, \ PTHREAD_ROBUST_MUTEX_PSHARED (mutex)) #define __pthread_mutex_lock __pthread_mutex_cond_lock +#define __pthread_mutex_lock_full __pthread_mutex_cond_lock_full #define NO_INCR #include <nptl/pthread_mutex_lock.c> diff --git a/libc/nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h b/libc/nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h index 558d87d67..c27332e1c 100644 --- a/libc/nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h +++ b/libc/nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2003, 2004, 2006, 2007, 2008 Free Software Foundation, Inc. +/* Copyright (C) 2003, 2004, 2006-2008, 2009 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2003. @@ -39,6 +39,9 @@ #define FUTEX_WAIT_BITSET 9 #define FUTEX_WAKE_BITSET 10 #define FUTEX_PRIVATE_FLAG 128 +#define FUTEX_CLOCK_REALTIME 256 + +#define FUTEX_BITSET_MATCH_ANY 0xffffffff /* Values for 'private' parameter of locking macros. Yes, the definition seems to be backwards. But it is not. The bit will be diff --git a/libc/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S b/libc/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S index 4505e2cec..8de9cf461 100644 --- a/libc/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S +++ b/libc/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2006, 2007 Free Software Foundation, Inc. +/* Copyright (C) 2002-2006, 2007, 2009 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. @@ -31,6 +31,8 @@ movl $(FUTEX_WAKE | FUTEX_PRIVATE_FLAG), reg # 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 # define LOAD_FUTEX_WAKE(reg) \ xorl $(FUTEX_WAKE | FUTEX_PRIVATE_FLAG), reg #else @@ -55,6 +57,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 # define LOAD_FUTEX_WAKE(reg) \ xorl $FUTEX_PRIVATE_FLAG, reg ; \ andl %fs:PRIVATE_FUTEX, reg ; \ @@ -143,12 +149,61 @@ __lll_lock_wait: cfi_endproc .size __lll_lock_wait,.-__lll_lock_wait + /* %rdi: futex + %rsi: flags + %rdx: timeout + %eax: futex value + */ .globl __lll_timedlock_wait .type __lll_timedlock_wait,@function .hidden __lll_timedlock_wait .align 16 __lll_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) + + movl $2, %edx + cmpl %edx, %eax + jne 2f + +1: movl $SYS_futex, %eax + movl $2, %edx + syscall + +2: xchgl %edx, (%rdi) /* NB: lock is implied */ + + testl %edx, %edx + jz 3f + + cmpl $-ETIMEDOUT, %eax + je 4f + cmpl $-EINVAL, %eax + jne 1b +4: movl %eax, %edx + negl %edx + +3: movl %edx, %eax + popq %r9 + cfi_adjust_cfa_offset(-8) + cfi_restore(%r9) + retq + +# ifndef __ASSUME_FUTEX_CLOCK_REALTIME +.Lreltmo: /* Check for a valid timeout value. */ cmpq $1000000000, 8(%rdx) jae 3f @@ -253,6 +308,7 @@ __lll_timedlock_wait: 3: movl $EINVAL, %eax retq +# endif cfi_endproc .size __lll_timedlock_wait,.-__lll_timedlock_wait #endif diff --git a/libc/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h b/libc/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h index f76d599c4..0b7e3bbab 100644 --- a/libc/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h +++ b/libc/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2004, 2006, 2007, 2008 Free Software Foundation, Inc. +/* Copyright (C) 2002-2004, 2006-2008, 2009 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. @@ -48,13 +48,16 @@ #define FUTEX_WAIT 0 #define FUTEX_WAKE 1 #define FUTEX_CMP_REQUEUE 4 -#define FUTEX_WAKE_OP 5 +#define FUTEX_WAKE_OP 5 #define FUTEX_LOCK_PI 6 #define FUTEX_UNLOCK_PI 7 #define FUTEX_TRYLOCK_PI 8 #define FUTEX_WAIT_BITSET 9 #define FUTEX_WAKE_BITSET 10 #define FUTEX_PRIVATE_FLAG 128 +#define FUTEX_CLOCK_REALTIME 256 + +#define FUTEX_BITSET_MATCH_ANY 0xffffffff #define FUTEX_OP_CLEAR_WAKE_IF_GT_ONE ((4 << 24) | 1) |