From patchwork Wed Sep 19 07:34:00 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Albert ARIBAUD X-Patchwork-Id: 29459 Received: (qmail 2461 invoked by alias); 19 Sep 2018 07:34:07 -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 2452 invoked by uid 89); 19 Sep 2018 07:34:07 -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=1039, 2541 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_gettime64 Date: Wed, 19 Sep 2018 09:34:00 +0200 Message-Id: <20180919073400.27947-1-albert.aribaud@3adev.fr> * include/time.h: Declare __clock_gettime64(). * ntpl/pthread_clock_gettime.c: Add __pthread_clock_gettime64(). * ntpl/pthread_clock_gettime.c: Make __pthread_clock_gettime() a wrapper around __pthread_clock_gettime64(). * sysdeps/unix/clock_gettime.c (hp_timing_gettime): Use struct __timespec64. * sysdeps/unix/clock_gettime.c (realtime_gettime): Likewise. * sysdeps/unix/clock_gettime.c: Add __clock_gettime64(). * sysdeps/unix/clock_gettime.c: Make __clock_gettime() a wrapper around __clock_gettime64(). * sysdeps/unix/sysv/linux/clock_gettime.c: Add 64-bit-time syscall support. --- 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 | 3 ++ nptl/pthread_clock_gettime.c | 37 ++++++++++++++++++- sysdeps/unix/clock_gettime.c | 49 ++++++++++++++++++++----- sysdeps/unix/sysv/linux/clock_gettime.c | 43 ++++++++++++++++++++-- 4 files changed, 118 insertions(+), 14 deletions(-) diff --git a/include/time.h b/include/time.h index 162afa1012..9efd153b83 100644 --- a/include/time.h +++ b/include/time.h @@ -24,6 +24,9 @@ extern __typeof (clock_settime) __clock_settime; extern __typeof (clock_nanosleep) __clock_nanosleep; extern __typeof (clock_getcpuclockid) __clock_getcpuclockid; +extern int __clock_gettime64 (clockid_t __clock_id, + struct __timespec64 *__tp) __THROW; + /* Now define the internal interfaces. */ struct tm; diff --git a/nptl/pthread_clock_gettime.c b/nptl/pthread_clock_gettime.c index 6bc75cfe3f..508821b878 100644 --- a/nptl/pthread_clock_gettime.c +++ b/nptl/pthread_clock_gettime.c @@ -18,13 +18,14 @@ #include #include #include +#include #include "pthreadP.h" #if HP_TIMING_AVAIL int -__pthread_clock_gettime (clockid_t clock_id, hp_timing_t freq, - struct timespec *tp) +__pthread_clock_gettime64 (clockid_t clock_id, hp_timing_t freq, + struct __timespec64 *tp) { hp_timing_t tsc; @@ -64,4 +65,36 @@ __pthread_clock_gettime (clockid_t clock_id, hp_timing_t freq, return 0; } + +int +__pthread_clock_gettime (clockid_t clock_id, hp_timing_t freq, + struct timespec *tp) +{ + struct __timespec64 ts64; + int res; + + if (tp == NULL) + { + __set_errno(EINVAL); + res = -1; + } + else + { + int res = __pthread_clock_gettime64 (clock_id, freq, &ts64); + if (res == 0) + { + if (fits_in_time_t (ts64.tv_time)) + { + tp->tv_sec = ts64.tv_sec; + tp->tv_nsec = ts64.tv_nsec; + } + else + { + set_errno(EOVERFLOW); + res = -1; + } + } + } + return res; +} #endif diff --git a/sysdeps/unix/clock_gettime.c b/sysdeps/unix/clock_gettime.c index 96df78ab1e..88c1955f17 100644 --- a/sysdeps/unix/clock_gettime.c +++ b/sysdeps/unix/clock_gettime.c @@ -32,12 +32,12 @@ static hp_timing_t freq; /* This function is defined in the thread library. */ -extern int __pthread_clock_gettime (clockid_t clock_id, hp_timing_t freq, - struct timespec *tp) +extern int __pthread_clock_gettime64 (clockid_t clock_id, hp_timing_t freq, + struct __timespec64 *tp) __attribute__ ((__weak__)); static int -hp_timing_gettime (clockid_t clock_id, struct timespec *tp) +hp_timing_gettime (clockid_t clock_id, struct __timespec64 *tp) { hp_timing_t tsc; @@ -55,7 +55,7 @@ hp_timing_gettime (clockid_t clock_id, struct timespec *tp) if (clock_id != CLOCK_PROCESS_CPUTIME_ID && __pthread_clock_gettime != NULL) - return __pthread_clock_gettime (clock_id, freq, tp); + return __pthread_clock_gettime64 (clock_id, freq, tp); /* Get the current counter. */ HP_TIMING_NOW (tsc); @@ -76,20 +76,20 @@ hp_timing_gettime (clockid_t clock_id, struct timespec *tp) static inline int -realtime_gettime (struct timespec *tp) +realtime_gettime (struct __timespec64 *tp) { struct timeval tv; int retval = __gettimeofday (&tv, NULL); if (retval == 0) /* Convert into `timespec'. */ - TIMEVAL_TO_TIMESPEC (&tv, tp); + valid_timeval_to_timespec64 (&tv, tp); return retval; } /* Get current value of CLOCK and store it in TP. */ int -__clock_gettime (clockid_t clock_id, struct timespec *tp) +__clock_gettime64 (clockid_t clock_id, struct __timespec64 *tp) { int retval = -1; @@ -103,9 +103,9 @@ __clock_gettime (clockid_t clock_id, struct timespec *tp) case CLOCK_REALTIME: { struct timeval tv; - retval = __gettimeofday (&tv, NULL); + retval = __gettimeofday (&tv32, NULL); if (retval == 0) - TIMEVAL_TO_TIMESPEC (&tv, tp); + valid_timeval_to_timespec64 (&tv32, tp); } break; #endif @@ -132,5 +132,36 @@ __clock_gettime (clockid_t clock_id, struct timespec *tp) return retval; } + +int +__clock_gettime (clockid_t clock_id, struct timespec *tp) +{ + struct __timespec64 ts64; + int res; + + if (tp == NULL) + { + __set_errno(EINVAL); + res = -1; + } + else + { + res = __clock_gettime64 (clock_id, &ts64); + if (res == 0) + { + if (fits_in_time_t (ts64.tv_sec)) + { + tp->tv_sec = ts64.tv_sec; + tp->tv_nsec = ts64.tv_nsec; + } + else + { + __set_errno(EOVERFLOW); + res = -1; + } + } + } + return res; +} weak_alias (__clock_gettime, clock_gettime) libc_hidden_def (__clock_gettime) diff --git a/sysdeps/unix/sysv/linux/clock_gettime.c b/sysdeps/unix/sysv/linux/clock_gettime.c index d837fa36b1..9920ffa1ab 100644 --- a/sysdeps/unix/sysv/linux/clock_gettime.c +++ b/sysdeps/unix/sysv/linux/clock_gettime.c @@ -25,6 +25,41 @@ # define HAVE_VSYSCALL #endif #include +#include + +# define DO_CLOCK_GETTIME_32 \ + retval = INLINE_VSYSCALL (clock_gettime, 2, clock_id, &ts32); \ + if (retval == 0) \ + { \ + valid_timespec_to_timespec64 (&ts32, tp); \ + } + +#ifdef __NR_clock_gettime64 + +/* We are building with a 64-bit-time clock_gettime syscall */ + +# define DO_CLOCK_GETTIME_64 \ + if (__y2038_linux_support > 0) \ + { \ + retval = INLINE_SYSCALL (clock_gettime64, 2, clock_id, tp); \ + if (retval == -1 && errno == ENOSYS) \ + { \ + __y2038_linux_support = -1; \ + DO_CLOCK_GETTIME_32; \ + } \ + } \ + else \ + { \ + DO_CLOCK_GETTIME_32; \ + } + +#else + +/* We are building without a 64-bit-time clock_gettime syscall */ + +# define DO_CLOCK_GETTIME_64 DO_CLOCK_GETTIME_32 + +#endif /* The REALTIME and MONOTONIC clock are definitely supported in the kernel. */ @@ -32,7 +67,7 @@ SYSDEP_GETTIME_CPUTIME; \ case CLOCK_REALTIME: \ case CLOCK_MONOTONIC: \ - retval = INLINE_VSYSCALL (clock_gettime, 2, clock_id, tp); \ + DO_CLOCK_GETTIME_64; \ break /* We handled the REALTIME clock here. */ @@ -40,8 +75,10 @@ #define HANDLED_CPUTIME 1 #define SYSDEP_GETTIME_CPU(clock_id, tp) \ - retval = INLINE_VSYSCALL (clock_gettime, 2, clock_id, tp); \ + DO_CLOCK_GETTIME_64; \ break -#define SYSDEP_GETTIME_CPUTIME /* Default catches them too. */ + +#define SYSDEP_GETTIME_CPUTIME \ + struct timespec ts32 #include