From cbd8aeb836c8061c23a5e00419e0fb25a34abee7 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Sat, 3 Jan 2009 05:06:46 +0000 Subject: [PATCH] * init.c (__pthread_initialize_minimal_internal): Check for FUTEX_CLOCK_REALTIME flag. * sysdeps/unix/sysv/linux/x86_64/lowlevellock.S (__lll_timedlock_wait): Use FUTEX_WAIT_BITSET|FUTEX_CLOCK_READTIME instead of computing relative timeout. --- localedata/locales/bn_BD | 2 +- nptl/ChangeLog | 6 +++ nptl/init.c | 26 +++++++++- nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S | 58 +++++++++++++++++++++- 4 files changed, 89 insertions(+), 3 deletions(-) diff --git a/localedata/locales/bn_BD b/localedata/locales/bn_BD index dfbe47f050..dceacc34ad 100644 --- a/localedata/locales/bn_BD +++ b/localedata/locales/bn_BD @@ -37,7 +37,7 @@ copy "iso14651_t1" END LC_COLLATE LC_CTYPE -copy "i18n" +copy "bn_IN" translit_start include "translit_combining";"" diff --git a/nptl/ChangeLog b/nptl/ChangeLog index 70fc0b1e1e..ae652ff738 100644 --- a/nptl/ChangeLog +++ b/nptl/ChangeLog @@ -1,5 +1,11 @@ 2009-01-02 Ulrich Drepper + * init.c (__pthread_initialize_minimal_internal): Check for + FUTEX_CLOCK_REALTIME flag. + * sysdeps/unix/sysv/linux/x86_64/lowlevellock.S (__lll_timedlock_wait): + Use FUTEX_WAIT_BITSET|FUTEX_CLOCK_READTIME instead of computing + relative timeout. + * sysdeps/unix/sysv/linux/x86_64/lowlevellock.h: Define FUTEX_CLOCK_REALTIME and FUTEX_BITSET_MATCH_ANY. * sysdeps/unix/sysv/linux/i386/lowlevellock.h: Likewise. diff --git a/nptl/init.c b/nptl/init.c index d445de0795..af5bb24b59 100644 --- a/nptl/init.c +++ b/nptl/init.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002,2003,2004,2005,2006,2007 Free Software Foundation, Inc. +/* Copyright (C) 2002-2007, 2008, 2009 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 2002. @@ -18,6 +18,7 @@ 02111-1307 USA. */ #include +#include #include #include #include @@ -49,6 +50,15 @@ int __set_robust_list_avail; # define set_robust_list_not_avail() do { } while (0) #endif +#ifndef __ASSUME_FUTEX_CLOCK_REALTIME +/* Nonzero if we do not have FUTEX_CLOCK_REALTIME. */ +int __have_futex_clock_realtime; +# define __set_futex_clock_realtime() \ + __have_futex_clock_realtime = 1 +#else +#define __set_futex_clock_realtime() do { } while (0) +#endif + /* Version of the library, used in libthread_db to detect mismatches. */ static const char nptl_version[] __attribute_used__ = VERSION; @@ -292,6 +302,20 @@ __pthread_initialize_minimal_internal (void) } #endif +#ifndef __ASSUME_FUTEX_CLOCK_REALTIME + { + int word = 0; + word = INTERNAL_SYSCALL (futex, err, 6, &word, + FUTEX_WAIT_BITSET | FUTEX_CLOCK_REALTIME + | FUTEX_PRIVATE_FLAG, 1, NULL, 0, + FUTEX_BITSET_MATCH_ANY); + if (!INTERNAL_SYSCALL_ERROR_P (word, err) + || (INTERNAL_SYSCALL_ERRNO (word, err) != ENOSYS + && INTERNAL_SYSCALL_ERRNO (word, err) != EINVAL)) + __set_futex_clock_realtime (); + } +#endif + /* Set initial thread's stack block from 0 up to __libc_stack_end. It will be bigger than it actually is, but for unwind.c/pt-longjmp.c purposes this is good enough. */ diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S b/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S index 4505e2cec6..72c3858238 100644 --- a/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S +++ b/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 , 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(9) + cfi_offset(%r9, -16) + 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 -- 2.11.4.GIT