[RFC v4 03/24] sysdeps/gettimeofday: Use clock_gettime64 if avaliable
Alistair Francis
alistair.francis@wdc.com
Sat Aug 10 01:03:00 GMT 2019
Not all architectures support the obsolete gettimeofday so use the
newer clock_gettime64 syscall if it is avaliable. This fixes RV32
build issues.
This has the side effect of not setting the struct timezone *tz variable
if __ASSUME_TIME64_SYSCALLS or __NR_clock_gettime64 is defined!!!
The struct timezone *tz variable contaions information on the current
timezone, in this structure:
struct timezone {
int tz_minuteswest; /* minutes west of Greenwich */
int tz_dsttime; /* type of DST correction */
};
On 32-bit systems with __ARCH_WANT_TIME32_SYSCALLS not defined there is
no way way to get the struct timezone via a syscall. AFAIK there are no
plans to add suppor to a future kernel.
The Linux documentation says that "The use of the timezone structure
is obsolete; the tz argument should normally be specified as NULL."
Most callers of gettimeofday() don't use the timezone data, see
example code from Debian below.
If __ASSUME_TIME64_SYSCALLS and __NR_clock_gettime64 are not defined
then struct timezone *tz will be set as usual.
Example code from Debian:
struct timeval my_gettime(void)
{
struct timezone tz_ignored;
struct timeval tv;
gettimeofday(&tv, &tz_ignored);
return tv;
}
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
ChangeLog | 1 +
sysdeps/unix/sysv/linux/gettimeofday.c | 51 ++++++++++++++++++++++++++
2 files changed, 52 insertions(+)
diff --git a/ChangeLog b/ChangeLog
index aab4469b3d4..82a2cdc746d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1424,6 +1424,7 @@
* nptl/thrd_sleep.c: Use clock_nanosleep_time64 instead of nanosleep.
* sysdeps/unix/sysv/linux/nanosleep.c: Likewise.
* sysdeps/unix/sysv/linux/nanosleep_nocancel.c: Likewise.
+ * sysdeps/unix/sysv/linux/gettimeofday.c: Use clock_gettime64 syscall for gettimeofday.
2019-06-20 Dmitry V. Levin <ldv@altlinux.org>
Florian Weimer <fweimer@redhat.com>
diff --git a/sysdeps/unix/sysv/linux/gettimeofday.c b/sysdeps/unix/sysv/linux/gettimeofday.c
index a74f03825a5..bfbe7216198 100644
--- a/sysdeps/unix/sysv/linux/gettimeofday.c
+++ b/sysdeps/unix/sysv/linux/gettimeofday.c
@@ -32,7 +32,58 @@
int
__gettimeofday (struct timeval *tv, struct timezone *tz)
{
+#ifdef __ASSUME_TIME64_SYSCALLS
+ long int ret;
+ struct timespec now;
+
+ ret = INLINE_VSYSCALL (clock_gettime64, 2, CLOCK_REALTIME,
+ &now);
+
+ if (ret == 0 || errno != ENOSYS)
+ {
+ /* Convert from timespec to timeval */
+ tv->tv_sec = now.tv_sec;
+ tv->tv_usec = now.tv_nsec / 1000;
+ }
+ return ret;
+#else
+# ifdef __NR_clock_nanosleep_time64
+ long int ret;
+# if __TIMESIZE == 64
+ ret = INLINE_VSYSCALL (clock_gettime64, 2, CLOCK_REALTIME,
+ &now);
+
+ if (ret == 0 || errno != ENOSYS)
+ {
+ /* Convert from timespec to timeval */
+ tv->tv_sec = now.tv_sec;
+ tv->tv_usec = now.tv_nsec / 1000;
+ return ret;
+ }
+# else
+ struct __timespec64 now;
+
+ ret = INLINE_VSYSCALL (clock_gettime64, 2, CLOCK_REALTIME,
+ &now);
+
+ if (ret == 0 || errno != ENOSYS)
+ {
+ /* Convert from timespec to timeval */
+ tv->tv_sec = now.tv_sec;
+ tv->tv_usec = now.tv_nsec / 1000;
+ return ret;
+ }
+# endif /* __TIMESIZE == 64 */
+# endif /* __NR_clock_nanosleep_time64 */
+# if __TIMESIZE == 64
+ if (! in_time_t_range (tv->tv_sec))
+ {
+ __set_errno (EOVERFLOW);
+ return -1;
+ }
+# endif /* __TIMESIZE == 64 */
return INLINE_VSYSCALL (gettimeofday, 2, tv, tz);
+#endif
}
libc_hidden_def (__gettimeofday)
weak_alias (__gettimeofday, gettimeofday)
--
2.22.0
More information about the Libc-alpha
mailing list