commit d53a73acdbf6ac6eb99cd06f5dd695da58d9e8f5 Author: Ulrich Drepper Date: Tue Sep 6 20:22:37 2011 -0400 Avoid gettimeofday vsyscall 2011-09-06 Ulrich Drepper * sysdeps/unix/sysv/linux/getsysstats.c (__get_nprocs): Don't use gettimeofday vsyscall, just use time. diff --git a/sysdeps/unix/sysv/linux/getsysstats.c b/sysdeps/unix/sysv/linux/getsysstats.c index b9bae3d..7feb7a1 100644 --- a/sysdeps/unix/sysv/linux/getsysstats.c +++ b/sysdeps/unix/sysv/linux/getsysstats.c @@ -37,15 +37,6 @@ #include #include -#ifndef HAVE_CLOCK_GETTIME_VSYSCALL -# undef INTERNAL_VSYSCALL -# define INTERNAL_VSYSCALL INTERNAL_SYSCALL -# undef INLINE_VSYSCALL -# define INLINE_VSYSCALL INLINE_SYSCALL -#else -# include -#endif - /* How we can determine the number of available processors depends on the configuration. There is currently (as of version 2.0.21) no @@ -141,17 +132,10 @@ __get_nprocs () static int cached_result; static time_t timestamp; -#ifdef __ASSUME_POSIX_TIMERS - struct timespec ts; - INTERNAL_SYSCALL_DECL (err); - INTERNAL_VSYSCALL (clock_gettime, err, 2, CLOCK_REALTIME, &ts); -#else - struct timeval ts; - __gettimeofday (&ts, NULL); -#endif + time_t now = time (NULL); time_t prev = timestamp; atomic_read_barrier (); - if (ts.tv_sec == prev) + if (now == prev) return cached_result; /* XXX Here will come a test for the new system call. */ @@ -243,7 +227,7 @@ __get_nprocs () out: cached_result = result; atomic_write_barrier (); - timestamp = ts.tv_sec; + timestamp = now; return result; } commit a77d3c17dc6517636c1cf6ab9c6bb8c257772354 Author: Ulrich Drepper Date: Tue Sep 6 21:34:11 2011 -0400 Don't unconditionally use clock_gettime vsyscall on x86-64 2011-09-06 Ulrich Drepper * sysdeps/unix/sysv/linux/x86_64/clock_gettime.c: New file. * sysdeps/unix/sysv/linux/clock_gettime.c (SYSCALL_GETTIME): Allow already be defined. Change to take two parameters and don't assign result to variable. Adjust all users. Define INTERNAL_GETTIME if not already defined. Use INTERNAL_GETTIME instead of INTERNAL_VSYSCALL got clock_gettime call. * sysdeps/unix/sysv/linux/x86_64/sysdep.h: Don't define HAVE_CLOCK_GETTIME_VSYSCALL. * sysdeps/unix/clock_gettime.c: Adjust use of SYSDEP_GETTIME_CPU. diff --git a/sysdeps/unix/clock_gettime.c b/sysdeps/unix/clock_gettime.c index fbaaf30..d467f2b 100644 --- a/sysdeps/unix/clock_gettime.c +++ b/sysdeps/unix/clock_gettime.c @@ -1,5 +1,5 @@ /* clock_gettime -- Get the current time from a POSIX clockid_t. Unix version. - Copyright (C) 1999-2004, 2005, 2007 Free Software Foundation, Inc. + Copyright (C) 1999-2004, 2005, 2007, 2011 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -113,7 +113,7 @@ clock_gettime (clockid_t clock_id, struct timespec *tp) default: #ifdef SYSDEP_GETTIME_CPU - SYSDEP_GETTIME_CPU; + retval = SYSDEP_GETTIME_CPU (clock_id, tp); #endif #if HP_TIMING_AVAIL if ((clock_id & ((1 << CLOCK_IDFIELD_SIZE) - 1)) diff --git a/sysdeps/unix/sysv/linux/clock_gettime.c b/sysdeps/unix/sysv/linux/clock_gettime.c index dd3755c..0ae45de 100644 --- a/sysdeps/unix/sysv/linux/clock_gettime.c +++ b/sysdeps/unix/sysv/linux/clock_gettime.c @@ -1,5 +1,5 @@ /* clock_gettime -- Get current time from a POSIX clockid_t. Linux version. - Copyright (C) 2003,2004,2005,2006,2007,2010 Free Software Foundation, Inc. + Copyright (C) 2003,2004,2005,2006,2007,2010,2011 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -32,9 +32,14 @@ # include #endif -#define SYSCALL_GETTIME \ - retval = INLINE_VSYSCALL (clock_gettime, 2, clock_id, tp); \ - break +#ifndef SYSCALL_GETTIME +# define SYSCALL_GETTIME(id, tp) \ + INLINE_VSYSCALL (clock_gettime, 2, id, tp) +#endif +#ifndef INTERNAL_GETTIME +# define INTERNAL_GETTIME(id, tp) \ + INTERNAL_VSYSCALL (clock_gettime, err, 2, id, tp) +#endif #ifdef __ASSUME_POSIX_TIMERS @@ -44,7 +49,8 @@ SYSDEP_GETTIME_CPUTIME \ case CLOCK_REALTIME: \ case CLOCK_MONOTONIC: \ - SYSCALL_GETTIME + retval = SYSCALL_GETTIME (clock_id, tp); \ + break # define __libc_missing_posix_timers 0 #elif defined __NR_clock_gettime @@ -59,7 +65,7 @@ maybe_syscall_gettime (clockid_t clock_id, struct timespec *tp) if (!__libc_missing_posix_timers) { INTERNAL_SYSCALL_DECL (err); - int r = INTERNAL_VSYSCALL (clock_gettime, err, 2, clock_id, tp); + int r = INTERNAL_GETTIME (clock_id, tp); if (!INTERNAL_SYSCALL_ERROR_P (r, err)) return 0; @@ -89,7 +95,7 @@ maybe_syscall_gettime (clockid_t clock_id, struct timespec *tp) /* Fallback code. */ \ if (retval == EINVAL && clock_id == CLOCK_REALTIME) \ retval = realtime_gettime (tp); \ - else \ + else \ { \ __set_errno (retval); \ retval = -1; \ @@ -119,7 +125,7 @@ maybe_syscall_gettime_cpu (clockid_t clock_id, struct timespec *tp) if (!__libc_missing_posix_cpu_timers) { INTERNAL_SYSCALL_DECL (err); - int r = INTERNAL_VSYSCALL (clock_gettime, err, 2, clock_id, tp); + int r = INTERNAL_GETTIME (clock_id, tp); if (!INTERNAL_SYSCALL_ERROR_P (r, err)) return 0; diff --git a/sysdeps/unix/sysv/linux/x86_64/clock_gettime.c b/sysdeps/unix/sysv/linux/x86_64/clock_gettime.c new file mode 100644 index 0000000..9d6cd23 --- /dev/null +++ b/sysdeps/unix/sysv/linux/x86_64/clock_gettime.c @@ -0,0 +1,10 @@ +#include "bits/libc-vdso.h" + +#ifdef SHARED +# define SYSCALL_GETTIME(id, tp) \ + (*__vdso_clock_gettime) (id, tp) +# define INTERNAL_GETTIME(id, tp) \ + (*__vdso_clock_gettime) (id, tp) +#endif + +#include "../clock_gettime.c" diff --git a/sysdeps/unix/sysv/linux/x86_64/sysdep.h b/sysdeps/unix/sysv/linux/x86_64/sysdep.h index 2b9ea85..a9821dc 100644 --- a/sysdeps/unix/sysv/linux/x86_64/sysdep.h +++ b/sysdeps/unix/sysv/linux/x86_64/sysdep.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2005, 2007 Free Software Foundation, Inc. +/* Copyright (C) 2001-2005, 2007, 2011 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -279,8 +279,8 @@ if (INTERNAL_SYSCALL_ERROR_P (sc_ret, sc_err)) \ { \ iserr: \ - __set_errno (INTERNAL_SYSCALL_ERRNO (sc_ret, sc_err)); \ - sc_ret = -1L; \ + __set_errno (INTERNAL_SYSCALL_ERRNO (sc_ret, sc_err)); \ + sc_ret = -1L; \ } \ out: \ sc_ret; \ @@ -304,9 +304,6 @@ v_ret; \ }) -/* List of system calls which are supported as vsyscalls. */ -# define HAVE_CLOCK_GETTIME_VSYSCALL 1 - # else # define INLINE_VSYSCALL(name, nr, args...) \ INLINE_SYSCALL (name, nr, ##args) commit a0e1f41bd487d2202b6c1e0802c0e6c91630fbea Author: Ulrich Drepper Date: Tue Sep 6 23:17:53 2011 -0400 Don't call gettimeofday vsyscall in x86-64 sem_timedwait 2011-09-06 Ulrich Drepper * sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S (sem_timedwait): Don't use gettimeofday vsyscall, just call gettimeofday. diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S b/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S index ca49cb8..2926b36 100644 --- a/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S +++ b/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S @@ -1,4 +1,4 @@ -/* Copyright (C) 2002,2003,2005,2007,2009,2010 Free Software Foundation, Inc. +/* Copyright (C) 2002,2003,2005,2007,2009,2010,2011 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 2002. @@ -24,10 +24,6 @@ #include #include - -/* For the calculation see asm/vsyscall.h. */ -#define VSYSCALL_ADDR_vgettimeofday 0xffffffffff600000 - .text .globl sem_timedwait @@ -212,9 +208,10 @@ sem_timedwait: addq $1, NWAITERS(%r12) 7: xorl %esi, %esi - movq %rsp, %rdi - movq $VSYSCALL_ADDR_vgettimeofday, %rax - callq *%rax + movq %rsp,%rdi + /* This call works because we directly jump to a system call entry + which preserves all the registers. */ + call JUMPTARGET(__gettimeofday) /* Compute relative timeout. */ movq 8(%rsp), %rax commit fc8bffcccf5821bca179486abef83a7f82526715 Author: Ulrich Drepper Date: Tue Sep 6 23:50:04 2011 -0400 Fix handling of __vdso_clock_gettime 2011-09-06 Ulrich Drepper * sysdeps/unix/sysv/linux/x86_64/clock_gettime.c (INTERNAL_GETTIME): Forgot to demangle the pointer. diff --git a/sysdeps/unix/sysv/linux/x86_64/clock_gettime.c b/sysdeps/unix/sysv/linux/x86_64/clock_gettime.c index 9d6cd23..7802701 100644 --- a/sysdeps/unix/sysv/linux/x86_64/clock_gettime.c +++ b/sysdeps/unix/sysv/linux/x86_64/clock_gettime.c @@ -2,9 +2,13 @@ #ifdef SHARED # define SYSCALL_GETTIME(id, tp) \ - (*__vdso_clock_gettime) (id, tp) + ({ long int (*f) (clockid_t, struct timespec *) = __vdso_clock_gettime; \ + PTR_DEMANGLE (f); \ + f (id, tp); }) # define INTERNAL_GETTIME(id, tp) \ - (*__vdso_clock_gettime) (id, tp) + ({ long int (*f) (clockid_t, struct timespec *) = __vdso_clock_gettime; \ + PTR_DEMANGLE (f); \ + f (id, tp); }) #endif #include "../clock_gettime.c" commit 9e5c9dcd57e80cd56c47fd2bf11de8d167176a0e Author: Ulrich Drepper Date: Wed Sep 7 00:14:06 2011 -0400 Remove gettimeofday vsyscall use from x86-86 libpthread * sysdeps/unix/sysv/linux/x86_64/lowlevellock.S: Likewise. * sysdeps/unix/sysv/linux/x86_64/lowlevelrobustlock.S: Likewise. * sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedrdlock.S: Likewise. * sysdeps/unix/sysv/linux/x86_64/pthread_rwlock_timedwrlock.S: Likewise. * sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S: Likewise. Simplify __vdso_clock_gettime use. diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S b/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S index 3195db2..018da0c 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, 2009, 2010 Free Software Foundation, Inc. +/* Copyright (C) 2002-2007, 2009, 2010, 2011 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 2002. @@ -68,10 +68,6 @@ #endif -/* For the calculation see asm/vsyscall.h. */ -#define VSYSCALL_ADDR_vgettimeofday 0xffffffffff600000 - - .globl __lll_lock_wait_private .type __lll_lock_wait_private,@function .hidden __lll_lock_wait_private @@ -250,10 +246,9 @@ __lll_timedlock_wait: /* Get current time. */ movq %rsp, %rdi xorl %esi, %esi - movq $VSYSCALL_ADDR_vgettimeofday, %rax - /* This is a regular function call, all caller-save registers - might be clobbered. */ - callq *%rax + /* This call works because we directly jump to a system call entry + which preserves all the registers. */ + call JUMPTARGET(__gettimeofday) /* Compute relative timeout. */ movq 8(%rsp), %rax @@ -402,8 +397,9 @@ __lll_timedwait_tid: /* Get current time. */ 2: movq %rsp, %rdi xorl %esi, %esi - movq $VSYSCALL_ADDR_vgettimeofday, %rax - callq *%rax + /* This call works because we directly jump to a system call entry + which preserves all the registers. */ + call JUMPTARGET(__gettimeofday) /* Compute relative timeout. */ movq 8(%rsp), %rax diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevelrobustlock.S b/nptl/sysdeps/unix/sysv/linux/x86_64/lowlevelrobustlock.S index 5218a4f..b7b8b34 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=2007, 2009, 2010 Free Software Foundation, Inc. +/* Copyright (C) 2002, 2011=2007, 2009, 2010 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 2002. @@ -50,9 +50,6 @@ orl $FUTEX_WAIT_BITSET | FUTEX_CLOCK_REALTIME, reg #endif -/* For the calculation see asm/vsyscall.h. */ -#define VSYSCALL_ADDR_vgettimeofday 0xffffffffff600000 - .globl __lll_robust_lock_wait .type __lll_robust_lock_wait,@function @@ -219,10 +216,9 @@ __lll_robust_timedlock_wait: /* Get current time. */ movq %rsp, %rdi xorl %esi, %esi - movq $VSYSCALL_ADDR_vgettimeofday, %rax - /* This is a regular function call, all caller-save registers - might be clobbered. */ - callq *%rax + /* This call works because we directly jump to a system call entry + which preserves all the registers. */ + call JUMPTARGET(__gettimeofday) /* Compute relative timeout. */ movq 8(%rsp), %rax diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S index 48ea8b9..d11b297 100644 --- a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S +++ b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S @@ -26,9 +26,6 @@ #include -/* For the calculation see asm/vsyscall.h. */ -#define VSYSCALL_ADDR_vgettimeofday 0xffffffffff600000 - .text @@ -453,13 +450,11 @@ __pthread_cond_timedwait: movq __vdso_clock_gettime@GOTPCREL(%rip), %rax movq (%rax), %rax PTR_DEMANGLE (%rax) - jz 26f call *%rax - jmp 27f -# endif -26: movl $__NR_clock_gettime, %eax +# else + movl $__NR_clock_gettime, %eax syscall -27: +# endif # ifndef __ASSUME_POSIX_TIMERS cmpq $-ENOSYS, %rax je 19f @@ -473,8 +468,9 @@ __pthread_cond_timedwait: # else leaq 24(%rsp), %rdi xorl %esi, %esi - movq $VSYSCALL_ADDR_vgettimeofday, %rax - callq *%rax + /* This call works because we directly jump to a system call entry + which preserves all the registers. */ + call JUMPTARGET(__gettimeofday) /* Compute relative timeout. */ movq 40(%rsp), %rax @@ -611,8 +607,9 @@ __pthread_cond_timedwait: /* clock_gettime not available. */ 19: leaq 32(%rsp), %rdi xorl %esi, %esi - movq $VSYSCALL_ADDR_vgettimeofday, %rax - callq *%rax + /* This call works because we directly jump to a system call entry + which preserves all the registers. */ + call JUMPTARGET(__gettimeofday) /* Compute relative timeout. */ movq 40(%rsp), %rax 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 f5d055c..0e6a6ee 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-2005, 2007, 2009, 2010 Free Software Foundation, Inc. +/* Copyright (C) 2002-2005,2007,2009,2010,2011 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 2002. @@ -23,10 +23,6 @@ #include #include - -/* For the calculation see asm/vsyscall.h. */ -#define VSYSCALL_ADDR_vgettimeofday 0xffffffffff600000 - .text .globl pthread_rwlock_timedrdlock @@ -123,8 +119,9 @@ pthread_rwlock_timedrdlock: /* Get current time. */ movq %rsp, %rdi xorl %esi, %esi - movq $VSYSCALL_ADDR_vgettimeofday, %rax - callq *%rax + /* This call works because we directly jump to a system call entry + which preserves all the registers. */ + call JUMPTARGET(__gettimeofday) /* Compute relative timeout. */ movq 8(%rsp), %rax 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 6ed8b49..16bf920 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,5 @@ -/* Copyright (C) 2002, 2003, 2005, 2007, 2009, 2010 Free Software Foundation, Inc. +/* Copyright (C) 2002, 2003, 2005, 2007, 2009, 2010, 2011 + Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 2002. @@ -23,10 +24,6 @@ #include #include - -/* For the calculation see asm/vsyscall.h. */ -#define VSYSCALL_ADDR_vgettimeofday 0xffffffffff600000 - .text .globl pthread_rwlock_timedwrlock @@ -120,8 +117,9 @@ pthread_rwlock_timedwrlock: /* Get current time. */ movq %rsp, %rdi xorl %esi, %esi - movq $VSYSCALL_ADDR_vgettimeofday, %rax - callq *%rax + /* This call works because we directly jump to a system call entry + which preserves all the registers. */ + call JUMPTARGET(__gettimeofday) /* Compute relative timeout. */ movq 8(%rsp), %rax commit e38ba7ab6a56d53bde4fcff250f6928fb473bc3c Author: Ulrich Drepper Date: Wed Sep 7 00:07:08 2011 -0400 Make sure __vdso_clock_gettime always contains a valid pointer 2011-09-07 Ulrich Drepper * sysdeps/unix/sysv/linux/x86_64/init-first.c (_libc_vdso_platform_setup): If vDSO is not present store pointer to syscall wrapper around clock_gettime in __vdso_clock_gettime. * sysdeps/unix/sysv/linux/x86_64/syscalls.list: Add entry for clock_gettime. diff --git a/sysdeps/unix/sysv/linux/x86_64/init-first.c b/sysdeps/unix/sysv/linux/x86_64/init-first.c index 25cf08b..cb39aca 100644 --- a/sysdeps/unix/sysv/linux/x86_64/init-first.c +++ b/sysdeps/unix/sysv/linux/x86_64/init-first.c @@ -17,6 +17,8 @@ 02111-1307 USA. */ #ifdef SHARED +# include +# include # include # include @@ -27,12 +29,17 @@ strong_alias (__vdso_clock_gettime, __GI___vdso_clock_gettime attribute_hidden) long int (*__vdso_getcpu) (unsigned *, unsigned *, void *) attribute_hidden; +extern long int __syscall_clock_gettime (clockid_t, struct timespec *); + + static inline void _libc_vdso_platform_setup (void) { PREPARE_VERSION (linux26, "LINUX_2.6", 61765110); void *p = _dl_vdso_vsym ("clock_gettime", &linux26); + if (p == NULL) + p = __syscall_clock_gettime; PTR_MANGLE (p); __GI___vdso_clock_gettime = p; diff --git a/sysdeps/unix/sysv/linux/x86_64/syscalls.list b/sysdeps/unix/sysv/linux/x86_64/syscalls.list index 3e231a0..ccddb84 100644 --- a/sysdeps/unix/sysv/linux/x86_64/syscalls.list +++ b/sysdeps/unix/sysv/linux/x86_64/syscalls.list @@ -14,6 +14,7 @@ semop - semop i:ipi __semop semop semtimedop - semtimedop i:ipip semtimedop semget - semget i:iii __semget semget semctl - semctl i:iiii __semctl semctl +syscall_clock_gettime EXTRA clock_gettime Ei:ip __syscall_clock_gettime # proper socket implementations: