diff options
author | Alistair Francis <alistair.francis@wdc.com> | 2019-07-15 16:30:59 -0700 |
---|---|---|
committer | Alistair Francis <alistair.francis@wdc.com> | 2019-12-04 09:43:40 -0800 |
commit | ec138c67cbda8b5826a0a2a7ba456408117996dc (patch) | |
tree | 91a3a45ded96f18ea49cde5b76bde4d219fe4436 /sysdeps/unix | |
parent | f6fbce7dd72145ed9272ac8ef3ea6123c390a72b (diff) | |
download | glibc-ec138c67cbda8b5826a0a2a7ba456408117996dc.tar glibc-ec138c67cbda8b5826a0a2a7ba456408117996dc.tar.gz glibc-ec138c67cbda8b5826a0a2a7ba456408117996dc.tar.bz2 glibc-ec138c67cbda8b5826a0a2a7ba456408117996dc.zip |
sysdeps/clock_gettime: Use clock_gettime64 if avaliable
With the clock_gettime64 call we prefer to use vDSO. There is no call
to clock_gettime64 on glibc with older headers and kernel 5.1+ if it
doesn't support vDSO.
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Diffstat (limited to 'sysdeps/unix')
-rw-r--r-- | sysdeps/unix/sysv/linux/clock_gettime.c | 44 |
1 files changed, 43 insertions, 1 deletions
diff --git a/sysdeps/unix/sysv/linux/clock_gettime.c b/sysdeps/unix/sysv/linux/clock_gettime.c index ca40983f6c..875c4fe905 100644 --- a/sysdeps/unix/sysv/linux/clock_gettime.c +++ b/sysdeps/unix/sysv/linux/clock_gettime.c @@ -17,6 +17,7 @@ <https://www.gnu.org/licenses/>. */ #include <sysdep.h> +#include <kernel-features.h> #include <errno.h> #include <time.h> #include "kernel-posix-cpu-timers.h" @@ -30,10 +31,51 @@ /* Get current value of CLOCK and store it in TP. */ int +__clock_gettime64 (clockid_t clock_id, struct __timespec64 *tp) +{ +#ifdef __ASSUME_TIME64_SYSCALLS +# ifndef __NR_clock_gettime64 +# define __NR_clock_gettime64 __NR_clock_gettime +# define __vdso_clock_gettime64 __vdso_clock_gettime +# endif + return INLINE_VSYSCALL (clock_gettime64, 2, clock_id, tp); +#else +# if defined HAVE_CLOCK_GETTIME64_VSYSCALL + int ret64 = INLINE_VSYSCALL (clock_gettime64, 2, clock_id, tp); + if (ret64 == 0 || errno != ENOSYS) + return ret64; +# endif + struct timespec tp32; + int ret = INLINE_VSYSCALL (clock_gettime, 2, clock_id, &tp32); + if (ret == 0) + *tp = valid_timespec_to_timespec64 (tp32); + return ret; +#endif +} + +#if __TIMESIZE != 64 +int __clock_gettime (clockid_t clock_id, struct timespec *tp) { - return INLINE_VSYSCALL (clock_gettime, 2, clock_id, tp); + int ret; + struct __timespec64 tp64; + + ret = __clock_gettime64 (clock_id, &tp64); + + if (ret == 0) + { + if (! in_time_t_range (tp64.tv_sec)) + { + __set_errno (EOVERFLOW); + return -1; + } + + *tp = valid_timespec64_to_timespec (tp64); + } + + return ret; } +#endif libc_hidden_def (__clock_gettime) versioned_symbol (libc, __clock_gettime, clock_gettime, GLIBC_2_17); |