This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[PATCH 4/6] y2038: linux: Provide __clock_getres64 implementation
- From: Lukasz Majewski <lukma at denx dot de>
- To: libc-alpha at sourceware dot org
- Cc: Paul Eggert <eggert at cs dot ucla dot edu>, Joseph Myers <joseph at codesourcery dot com>, Lukasz Majewski <lukma at denx dot de>
- Date: Mon, 15 Apr 2019 00:08:39 +0200
- Subject: [PATCH 4/6] y2038: linux: Provide __clock_getres64 implementation
- References: <20190414220841.20243-1-lukma@denx.de>
This patch provides new __clock_getres64 explicit 64 bit function for
getting the resolution (precision) of specified clock ID. Moreover, a
32 bit version - __clock_getres has been refactored to internally use
__clock_getres64.
The __clock_getres is now supposed to be used on 32 bit systems -
hence the necessary checks and conversion to 64 bit type. After this
change it is intrinsically Y2038 safe.
The new 64 bit syscall (clock_getres_time64) available from Linux
5.1+ has been used when applicable on 32 bit systems.
The execution path on 64 bit systems has not been changed or affected
in any way.
Tests:
- The code has been tested with x86_64/x86 (native compilation):
make PARALLELMFLAGS="-j8" && make xcheck PARALLELMFLAGS="-j8"
- Run specific tests on ARM/x86 32bit systems (qemu):
https://github.com/lmajewski/meta-y2038
and run tests:
https://github.com/lmajewski/y2038-tests/commits/master
on kernels with and without 64 bit time support.
No regressions were observed.
* include/time.h (__clock_getres64):
Add __clock_getres alias according to __TIMESIZE define
* sysdeps/unix/sysv/linux/clock_getres.c (__clock_getres):
Refactor this function to be used only on 32 bit machines as a
wrapper on __clock_getres64.
* sysdeps/unix/sysv/linux/clock_getres.c (__clock_getres64): Add
* sysdeps/unix/sysv/linux/clock_getres.c (__clock_getres64):
Use clock_getres_time6464 kernel syscall (available from 5.1-rc1+
Linux) by 32 bit Y2038 safe systems
---
include/time.h | 8 ++++++++
sysdeps/unix/sysv/linux/clock_getres.c | 33 ++++++++++++++++++++++++++++++++-
2 files changed, 40 insertions(+), 1 deletion(-)
diff --git a/include/time.h b/include/time.h
index 33eee8eb9a..20b9974078 100644
--- a/include/time.h
+++ b/include/time.h
@@ -132,6 +132,14 @@ extern int __clock_settime64 (clockid_t clock_id,
libc_hidden_proto (__clock_settime64)
#endif
+#if __TIMESIZE == 64
+# define __clock_getres64 __clock_getres
+#else
+extern int __clock_getres64 (clockid_t clock_id,
+ struct __timespec64 *tp);
+libc_hidden_proto (__clock_getres64);
+#endif
+
/* Compute the `struct tm' representation of T,
offset OFFSET seconds east of UTC,
and store year, yday, mon, mday, wday, hour, min, sec into *TP.
diff --git a/sysdeps/unix/sysv/linux/clock_getres.c b/sysdeps/unix/sysv/linux/clock_getres.c
index 24b2299938..3f6c24f1dd 100644
--- a/sysdeps/unix/sysv/linux/clock_getres.c
+++ b/sysdeps/unix/sysv/linux/clock_getres.c
@@ -28,8 +28,39 @@
/* Get resolution of clock. */
int
-__clock_getres (clockid_t clock_id, struct timespec *res)
+__clock_getres64 (clockid_t clock_id, struct __timespec64 *res)
{
+#if defined (__TIMESIZE) && __TIMESIZE != 64
+# if defined __NR_clock_getres_time64
+ return INLINE_VSYSCALL (clock_getres_time64, 2, clock_id, res);
+# else
+ struct timespec ts32;
+ int retval = INLINE_VSYSCALL (clock_getres, 2, clock_id, &ts32);
+ if (! retval)
+ valid_timespec_to_timespec64(&ts32, res);
+
+ return retval;
+# endif
+#else
return INLINE_VSYSCALL (clock_getres, 2, clock_id, res);
+#endif
}
weak_alias (__clock_getres, clock_getres)
+
+#if __TIMESIZE != 64
+int
+__clock_getres (clockid_t clock_id, struct timespec *res)
+{
+ struct __timespec64 ts64;
+ int retval;
+
+ retval = __clock_getres64 (clock_id, &ts64);
+ if (! retval && res && ! timespec64_to_timespec (&ts64, res))
+ {
+ __set_errno (EOVERFLOW);
+ return -1;
+ }
+
+ return retval;
+}
+#endif
--
2.11.0