diff options
author | Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr> | 2017-09-08 00:41:36 +0200 |
---|---|---|
committer | Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr> | 2018-10-24 12:53:27 +0200 |
commit | 4b076e9e31c3810928f6b8e4f6d23ec7c1c0f65a (patch) | |
tree | 2359275ad58ad1f3c99fafe89dc18c432f777e14 | |
parent | 641e465b8494c698ed9aefa32e3b97a8a0627dd8 (diff) | |
download | glibc-4b076e9e31c3810928f6b8e4f6d23ec7c1c0f65a.tar.gz glibc-4b076e9e31c3810928f6b8e4f6d23ec7c1c0f65a.tar.xz glibc-4b076e9e31c3810928f6b8e4f6d23ec7c1c0f65a.zip |
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.
-rw-r--r-- | include/time.h | 2 | ||||
-rw-r--r-- | sysdeps/posix/clock_getres.c | 31 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/clock_getres.c | 61 |
3 files changed, 85 insertions, 9 deletions
diff --git a/include/time.h b/include/time.h index 4db6cb17ce..f24ae1992d 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 e7924e0891..6b0d5da23c 100644 --- a/sysdeps/posix/clock_getres.c +++ b/sysdeps/posix/clock_getres.c @@ -23,12 +23,11 @@ #include <sys/param.h> #include <libc-internal.h> - #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 5d94f59afe..6b895f1e87 100644 --- a/sysdeps/unix/sysv/linux/clock_getres.c +++ b/sysdeps/unix/sysv/linux/clock_getres.c @@ -19,6 +19,7 @@ #include <sysdep.h> #include <errno.h> #include <time.h> +#include <y2038-support.h> #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 <sysdeps/posix/clock_getres.c> |