about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAlbert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>2017-09-08 00:41:36 +0200
committerAlbert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>2018-10-24 12:53:27 +0200
commit4b076e9e31c3810928f6b8e4f6d23ec7c1c0f65a (patch)
tree2359275ad58ad1f3c99fafe89dc18c432f777e14
parent641e465b8494c698ed9aefa32e3b97a8a0627dd8 (diff)
downloadglibc-4b076e9e31c3810928f6b8e4f6d23ec7c1c0f65a.tar.gz
glibc-4b076e9e31c3810928f6b8e4f6d23ec7c1c0f65a.tar.xz
glibc-4b076e9e31c3810928f6b8e4f6d23ec7c1c0f65a.zip
Y2038: add function __clock_getres_time64
* include/time.h (__clock_getres_time64): Add.
* sysdeps/posix/clock_getres.c (hp_timing_getres): Use
  struct __timespec64.
* sysdeps/posix/clock_getres.c (realtime_getres): Likewise.
* sysdeps/posix/clock_getres.c (__clock_getres_time64): Add.
* sysdeps/posix/clock_getres.c Use SYSDEP_GETRES64.
* sysdeps/posix/clock_getres.c Use SYSDEP_GETRES_CPU64.
* sysdeps/posix/clock_getres.c (__clock_getres):
  Use __clock_getres_time64.
* sysdeps/unix/sysv/linux/clock_getres.c (SYSCALL_GETRES32): Add.
* sysdeps/unix/sysv/linux/clock_getres.c (SYSCALL_GETRES64): Likewise.
* sysdeps/unix/sysv/linux/clock_getres.c (SYSDEP_GETRES64): Likewise.
* sysdeps/unix/sysv/linux/clock_getres.c (SYSDEP_GETRES_CPU64): Likewise.
-rw-r--r--include/time.h2
-rw-r--r--sysdeps/posix/clock_getres.c31
-rw-r--r--sysdeps/unix/sysv/linux/clock_getres.c61
3 files changed, 85 insertions, 9 deletions
diff --git a/include/time.h b/include/time.h
index 4db6cb17ce..f24ae1992d 100644
--- a/include/time.h
+++ b/include/time.h
@@ -44,6 +44,8 @@ extern int __clock_gettime64 (clockid_t __clock_id,
 			      struct __timespec64 *__tp) __THROW;
 extern int __clock_settime64 (clockid_t __clock_id,
 			       const struct __timespec64 *__tp) __THROW;
+extern int __clock_getres_time64 (clockid_t __clock_id,
+				  struct __timespec64 *__res) __THROW;
 
 /* Now define the internal interfaces.  */
 struct tm;
diff --git a/sysdeps/posix/clock_getres.c b/sysdeps/posix/clock_getres.c
index e7924e0891..6b0d5da23c 100644
--- a/sysdeps/posix/clock_getres.c
+++ b/sysdeps/posix/clock_getres.c
@@ -23,12 +23,11 @@
 #include <sys/param.h>
 #include <libc-internal.h>
 
-
 #if HP_TIMING_AVAIL
 static long int nsec;		/* Clock frequency of the processor.  */
 
 static int
-hp_timing_getres (struct timespec *res)
+hp_timing_getres (struct __timespec64 *res)
 {
   if (__glibc_unlikely (nsec == 0))
     {
@@ -56,7 +55,7 @@ hp_timing_getres (struct timespec *res)
 #endif
 
 static inline int
-realtime_getres (struct timespec *res)
+realtime_getres (struct __timespec64 *res)
 {
   long int clk_tck = __sysconf (_SC_CLK_TCK);
 
@@ -73,17 +72,16 @@ realtime_getres (struct timespec *res)
   return -1;
 }
 
-
 /* Get resolution of clock.  */
 int
-__clock_getres (clockid_t clock_id, struct timespec *res)
+__clock_getres_time64 (clockid_t clock_id, struct __timespec64 *res)
 {
   int retval = -1;
 
   switch (clock_id)
     {
-#ifdef SYSDEP_GETRES
-      SYSDEP_GETRES;
+#ifdef SYSDEP_GETRES64
+      SYSDEP_GETRES64;
 #endif
 
 #ifndef HANDLED_REALTIME
@@ -93,8 +91,8 @@ __clock_getres (clockid_t clock_id, struct timespec *res)
 #endif	/* handled REALTIME */
 
     default:
-#ifdef SYSDEP_GETRES_CPU
-      SYSDEP_GETRES_CPU;
+#ifdef SYSDEP_GETRES_CPU64
+      SYSDEP_GETRES_CPU64;
 #endif
 #if HP_TIMING_AVAIL
       if ((clock_id & ((1 << CLOCK_IDFIELD_SIZE) - 1))
@@ -115,4 +113,19 @@ __clock_getres (clockid_t clock_id, struct timespec *res)
 
   return retval;
 }
+
+int
+__clock_getres (clockid_t clock_id, struct timespec *res)
+{
+  struct __timespec64 ts64;
+  int retval = __clock_getres_time64 (clock_id, &ts64);
+  if (retval == 0)
+    {
+      // We assume we never run with a CPU clock period greater than
+      // 2**31 seconds and therefore we do not check the seconds field
+      res->tv_sec = ts64.tv_sec;
+      res->tv_nsec = ts64.tv_nsec;
+    }
+  return retval;
+}
 weak_alias (__clock_getres, clock_getres)
diff --git a/sysdeps/unix/sysv/linux/clock_getres.c b/sysdeps/unix/sysv/linux/clock_getres.c
index 5d94f59afe..6b895f1e87 100644
--- a/sysdeps/unix/sysv/linux/clock_getres.c
+++ b/sysdeps/unix/sysv/linux/clock_getres.c
@@ -19,6 +19,7 @@
 #include <sysdep.h>
 #include <errno.h>
 #include <time.h>
+#include <y2038-support.h>
 #include "kernel-posix-cpu-timers.h"
 
 #ifdef HAVE_CLOCK_GETRES_VSYSCALL
@@ -48,4 +49,64 @@
 #define SYSDEP_GETRES_CPU SYSCALL_GETRES
 #define SYSDEP_GETRES_CPUTIME	/* Default catches them too.  */
 
+/* The 64-bit version */
+
+// Call the 32-bit syscall and convert to 64-bit time
+#define SYSCALL_GETRES32 \
+  retval = INLINE_VSYSCALL (clock_getres, 2, clock_id, &ts32);		\
+  if (retval==0)							\
+    {									\
+      timespec_to_timespec64(&ts32, res);				\
+      res->tv_pad = 0;							\
+    }
+
+#ifdef __NR_clock_getres_time64
+
+/* We are building with a 64-bit-time getres syscall */
+
+#define SYSCALL_GETRES64 \
+  if (__y2038_linux_support > 0)					\
+    {									\
+      retval = INLINE_SYSCALL (clock_getres_time64, 2, clock_id, res);	\
+      if (retval == -1 && errno == ENOSYS)				\
+	{								\
+	  __y2038_linux_support = -1;					\
+	  SYSCALL_GETRES32;						\
+	}								\
+    }									\
+  else									\
+    {									\
+      SYSCALL_GETRES32;							\
+    }									\
+  break
+
+#else
+
+/* We are building without a 64-bit-time getres syscall */
+
+#define SYSCALL_GETRES64 \
+  SYSCALL_GETRES32;							\
+  break
+
+#endif
+
+/* The REALTIME and MONOTONIC clock are definitely supported in the
+   kernel.  */
+#define SYSDEP_GETRES64							\
+  SYSDEP_GETRES_CPUTIME64						\
+  case CLOCK_REALTIME:							\
+  case CLOCK_MONOTONIC:							\
+  case CLOCK_MONOTONIC_RAW:						\
+  case CLOCK_REALTIME_COARSE:						\
+  case CLOCK_MONOTONIC_COARSE:						\
+    SYSCALL_GETRES64
+
+/* We handled the REALTIME clock here.  */
+#define HANDLED_REALTIME64	1
+#define HANDLED_CPUTIME64	1
+
+#define SYSDEP_GETRES_CPU64 SYSCALL_GETRES64
+#define SYSDEP_GETRES_CPUTIME64 \
+  struct timespec ts32;
+
 #include <sysdeps/posix/clock_getres.c>