aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlbert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>2018-04-08 11:15:24 +0200
committerAlbert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>2018-10-24 12:53:27 +0200
commit09cb6964e2e03b5fe49e336c800b00354f2c3901 (patch)
treee9235e65e0addc38d1ab891157e7ef0ff5fab38f
parent94811042d73239d35b9d4bf7592c62ccc65ce633 (diff)
downloadglibc-09cb6964e2e03b5fe49e336c800b00354f2c3901.zip
glibc-09cb6964e2e03b5fe49e336c800b00354f2c3901.tar.gz
glibc-09cb6964e2e03b5fe49e336c800b00354f2c3901.tar.bz2
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.
-rw-r--r--include/time.h3
-rw-r--r--nptl/pthread_clock_gettime.c37
-rw-r--r--sysdeps/unix/clock_gettime.c49
-rw-r--r--sysdeps/unix/sysv/linux/clock_gettime.c43
4 files changed, 118 insertions, 14 deletions
diff --git a/include/time.h b/include/time.h
index f95f16e..a8372fa 100644
--- a/include/time.h
+++ b/include/time.h
@@ -40,6 +40,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 6bc75cf..508821b 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 96df78a..88c1955 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 d837fa3..9920ffa 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>