@@ -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;
@@ -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
@@ -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)
@@ -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>