This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[RFC v4 03/24] sysdeps/gettimeofday: Use clock_gettime64 if avaliable


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]