aboutsummaryrefslogtreecommitdiff
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
glibc-4b076e9e31c3810928f6b8e4f6d23ec7c1c0f65a.tar.gz
glibc-4b076e9e31c3810928f6b8e4f6d23ec7c1c0f65a.tar.bz2
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>