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 | |
parent | f6fbce7dd72145ed9272ac8ef3ea6123c390a72b (diff) | |
download | glibc-ec138c67cbda8b5826a0a2a7ba456408117996dc.tar.gz glibc-ec138c67cbda8b5826a0a2a7ba456408117996dc.tar.xz 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>
-rw-r--r-- | include/time.h | 3 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/clock_gettime.c | 44 |
2 files changed, 46 insertions, 1 deletions
diff --git a/include/time.h b/include/time.h index d7800eb30f..c19c73ae09 100644 --- a/include/time.h +++ b/include/time.h @@ -211,11 +211,14 @@ extern double __difftime (time_t time1, time_t time0); #if __TIMESIZE == 64 # define __clock_nanosleep_time64 __clock_nanosleep +# define __clock_gettime64 __clock_gettime #else extern int __clock_nanosleep_time64 (clockid_t clock_id, int flags, const struct __timespec64 *req, struct __timespec64 *rem); libc_hidden_proto (__clock_nanosleep_time64) +extern int __clock_gettime64 (clockid_t clock_id, struct __timespec64 *tp); +libc_hidden_proto (__clock_gettime64) #endif /* Use in the clock_* functions. Size of the field representing the 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); |