From: Albert ARIBAUD (3ADEV) Date: Thu, 7 Sep 2017 22:41:36 +0000 (+0200) Subject: Y2038: add function __clock_getres_time64 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4b076e9e31c3810928f6b8e4f6d23ec7c1c0f65a;p=thirdparty%2Fglibc.git Y2038: add function __clock_getres_time64 * include/time.h (__clock_getres_time64): Add. * sysdeps/posix/clock_getres.c (hp_timing_getres): Use struct __timespec64. * sysdeps/posix/clock_getres.c (realtime_getres): Likewise. * sysdeps/posix/clock_getres.c (__clock_getres_time64): Add. * sysdeps/posix/clock_getres.c Use SYSDEP_GETRES64. * sysdeps/posix/clock_getres.c Use SYSDEP_GETRES_CPU64. * sysdeps/posix/clock_getres.c (__clock_getres): Use __clock_getres_time64. * sysdeps/unix/sysv/linux/clock_getres.c (SYSCALL_GETRES32): Add. * sysdeps/unix/sysv/linux/clock_getres.c (SYSCALL_GETRES64): Likewise. * sysdeps/unix/sysv/linux/clock_getres.c (SYSDEP_GETRES64): Likewise. * sysdeps/unix/sysv/linux/clock_getres.c (SYSDEP_GETRES_CPU64): Likewise. --- diff --git a/include/time.h b/include/time.h index 4db6cb17ce1..f24ae1992d8 100644 --- a/include/time.h +++ b/include/time.h @@ -44,6 +44,8 @@ extern int __clock_gettime64 (clockid_t __clock_id, struct __timespec64 *__tp) __THROW; extern int __clock_settime64 (clockid_t __clock_id, const struct __timespec64 *__tp) __THROW; +extern int __clock_getres_time64 (clockid_t __clock_id, + struct __timespec64 *__res) __THROW; /* Now define the internal interfaces. */ struct tm; diff --git a/sysdeps/posix/clock_getres.c b/sysdeps/posix/clock_getres.c index e7924e0891b..6b0d5da23cf 100644 --- a/sysdeps/posix/clock_getres.c +++ b/sysdeps/posix/clock_getres.c @@ -23,12 +23,11 @@ #include #include - #if HP_TIMING_AVAIL static long int nsec; /* Clock frequency of the processor. */ static int -hp_timing_getres (struct timespec *res) +hp_timing_getres (struct __timespec64 *res) { if (__glibc_unlikely (nsec == 0)) { @@ -56,7 +55,7 @@ hp_timing_getres (struct timespec *res) #endif static inline int -realtime_getres (struct timespec *res) +realtime_getres (struct __timespec64 *res) { long int clk_tck = __sysconf (_SC_CLK_TCK); @@ -73,17 +72,16 @@ realtime_getres (struct timespec *res) return -1; } - /* Get resolution of clock. */ int -__clock_getres (clockid_t clock_id, struct timespec *res) +__clock_getres_time64 (clockid_t clock_id, struct __timespec64 *res) { int retval = -1; switch (clock_id) { -#ifdef SYSDEP_GETRES - SYSDEP_GETRES; +#ifdef SYSDEP_GETRES64 + SYSDEP_GETRES64; #endif #ifndef HANDLED_REALTIME @@ -93,8 +91,8 @@ __clock_getres (clockid_t clock_id, struct timespec *res) #endif /* handled REALTIME */ default: -#ifdef SYSDEP_GETRES_CPU - SYSDEP_GETRES_CPU; +#ifdef SYSDEP_GETRES_CPU64 + SYSDEP_GETRES_CPU64; #endif #if HP_TIMING_AVAIL if ((clock_id & ((1 << CLOCK_IDFIELD_SIZE) - 1)) @@ -115,4 +113,19 @@ __clock_getres (clockid_t clock_id, struct timespec *res) return retval; } + +int +__clock_getres (clockid_t clock_id, struct timespec *res) +{ + struct __timespec64 ts64; + int retval = __clock_getres_time64 (clock_id, &ts64); + if (retval == 0) + { + // We assume we never run with a CPU clock period greater than + // 2**31 seconds and therefore we do not check the seconds field + res->tv_sec = ts64.tv_sec; + res->tv_nsec = ts64.tv_nsec; + } + return retval; +} weak_alias (__clock_getres, clock_getres) diff --git a/sysdeps/unix/sysv/linux/clock_getres.c b/sysdeps/unix/sysv/linux/clock_getres.c index 5d94f59afee..6b895f1e87b 100644 --- a/sysdeps/unix/sysv/linux/clock_getres.c +++ b/sysdeps/unix/sysv/linux/clock_getres.c @@ -19,6 +19,7 @@ #include #include #include +#include #include "kernel-posix-cpu-timers.h" #ifdef HAVE_CLOCK_GETRES_VSYSCALL @@ -48,4 +49,64 @@ #define SYSDEP_GETRES_CPU SYSCALL_GETRES #define SYSDEP_GETRES_CPUTIME /* Default catches them too. */ +/* The 64-bit version */ + +// Call the 32-bit syscall and convert to 64-bit time +#define SYSCALL_GETRES32 \ + retval = INLINE_VSYSCALL (clock_getres, 2, clock_id, &ts32); \ + if (retval==0) \ + { \ + timespec_to_timespec64(&ts32, res); \ + res->tv_pad = 0; \ + } + +#ifdef __NR_clock_getres_time64 + +/* We are building with a 64-bit-time getres syscall */ + +#define SYSCALL_GETRES64 \ + if (__y2038_linux_support > 0) \ + { \ + retval = INLINE_SYSCALL (clock_getres_time64, 2, clock_id, res); \ + if (retval == -1 && errno == ENOSYS) \ + { \ + __y2038_linux_support = -1; \ + SYSCALL_GETRES32; \ + } \ + } \ + else \ + { \ + SYSCALL_GETRES32; \ + } \ + break + +#else + +/* We are building without a 64-bit-time getres syscall */ + +#define SYSCALL_GETRES64 \ + SYSCALL_GETRES32; \ + break + +#endif + +/* The REALTIME and MONOTONIC clock are definitely supported in the + kernel. */ +#define SYSDEP_GETRES64 \ + SYSDEP_GETRES_CPUTIME64 \ + case CLOCK_REALTIME: \ + case CLOCK_MONOTONIC: \ + case CLOCK_MONOTONIC_RAW: \ + case CLOCK_REALTIME_COARSE: \ + case CLOCK_MONOTONIC_COARSE: \ + SYSCALL_GETRES64 + +/* We handled the REALTIME clock here. */ +#define HANDLED_REALTIME64 1 +#define HANDLED_CPUTIME64 1 + +#define SYSDEP_GETRES_CPU64 SYSCALL_GETRES64 +#define SYSDEP_GETRES_CPUTIME64 \ + struct timespec ts32; + #include