From patchwork Wed Sep 19 08:14:43 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Albert ARIBAUD X-Patchwork-Id: 29461 Received: (qmail 110189 invoked by alias); 19 Sep 2018 08:18:12 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 102592 invoked by uid 89); 19 Sep 2018 08:14:50 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-24.1 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_LAZY_DOMAIN_SECURITY, KAM_NUMSUBJECT, RCVD_IN_BL_SPAMCOP_NET, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.2 spammy=nsec X-HELO: smtp3-g21.free.fr From: "Albert ARIBAUD (3ADEV)" To: libc-alpha@sourceware.org Cc: "Albert ARIBAUD (3ADEV)" Subject: [PATCH] Y2038: add function __clock_getres_time64 Date: Wed, 19 Sep 2018 10:14:43 +0200 Message-Id: <20180919081443.30910-1-albert.aribaud@3adev.fr> * 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. --- The Unix implementation uses 32-bit calls and converts to 64-bit time. The Linux implementation uses the 64-bit time syscall if available, otherwise it falls back to 32-bit syscall and conversion. This implementation depends on the clock_getres_time64 syscall being provided by the kernel at build as well as run time. This patch is part of the Y2038 patch series, which is available at . Warning: this branch may be rebased on current master and/or updated based on feedback from the list at any time. include/time.h | 2 + sysdeps/posix/clock_getres.c | 31 +++++++++---- 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 5a658223ce..d5bddeb23f 100644 --- a/include/time.h +++ b/include/time.h @@ -28,6 +28,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 #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 5d94f59afe..6b895f1e87 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