diff options
author | Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr> | 2018-04-08 11:15:24 +0200 |
---|---|---|
committer | Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr> | 2018-10-24 12:53:27 +0200 |
commit | 09cb6964e2e03b5fe49e336c800b00354f2c3901 (patch) | |
tree | e9235e65e0addc38d1ab891157e7ef0ff5fab38f | |
parent | 94811042d73239d35b9d4bf7592c62ccc65ce633 (diff) | |
download | glibc-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.h | 3 | ||||
-rw-r--r-- | nptl/pthread_clock_gettime.c | 37 | ||||
-rw-r--r-- | sysdeps/unix/clock_gettime.c | 49 | ||||
-rw-r--r-- | 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 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> |