This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[PATCH] Y2038: add function __clock_gettime64
- From: "Albert ARIBAUD (3ADEV)" <albert dot aribaud at 3adev dot fr>
- To: libc-alpha at sourceware dot org
- Cc: "Albert ARIBAUD (3ADEV)" <albert dot aribaud at 3adev dot fr>
- Date: Wed, 19 Sep 2018 09:34:00 +0200
- Subject: [PATCH] Y2038: add function __clock_gettime64
* 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
<https://sourceware.org/git/?p=glibc.git;a=shortlog;h=refs/heads/aaribaud/y2038>.
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 <errno.h>
#include <stdlib.h>
#include <time.h>
+#include <bits/types/struct_timespec64.h>
#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 <sysdep-vdso.h>
+#include <y2038-support.h>
+
+# 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 <sysdeps/unix/clock_gettime.c>
--
2.17.1