Message ID | 20191111214758.3677-5-lukma@denx.de |
---|---|
State | New |
Headers | show |
Series | y2038: linux: timer_[sg]ettime conversion to 64 bit time | expand |
Dear All, > This patch provides new __timer_gettime64 explicit 64 bit function > for reading status of specified timer. To be more precise - the > remaining time and interval set with timer_settime. > Moreover, a 32 bit version - __timer_gettime has been refactored to > internally use __timer_gettime64. > > The __timer_gettime is now supposed to be used on systems still > supporting 32 bit time (__TIMESIZE != 64) - hence the necessary > conversion from 64 bit struct __timespec64 to struct timespec. > > The new __timer_gettime64 syscall available from Linux 5.1+ has been > used, when applicable. > > Build tests: > - The code has been tested on x86_64/x86 (native compilation): > make PARALLELMFLAGS="-j8" && make check PARALLELMFLAGS="-j8" && \\ > make xcheck PARALLELMFLAGS="-j8" > > - The glibc has been build tested (make PARALLELMFLAGS="-j8") for > x86 (i386), x86_64-x32, and armv7 > > Run-time tests: > - 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 > > - Use of cross-test-ssh.sh for ARM (armv7): > make PARALLELMFLAGS="-j8" test-wrapper='./cross-test-ssh.sh > root@192.168.7.2' xcheck > > Linux kernel, headers and minimal kernel version for glibc build test > matrix: > - Linux v5.1 (with timer_gettime64) and glibc build with v5.1 as > minimal kernel version (--enable-kernel="5.1.0") > The __ASSUME_TIME64_SYSCALLS flag defined. > > - Linux v5.1 and default minimal kernel version > The __ASSUME_TIME64_SYSCALLS not defined, but kernel supports > timer_gettime64 syscall. > > - Linux v4.19 (no timer_gettime64 support) with default minimal > kernel version for contemporary glibc (3.2.0) > This kernel doesn't support timer_gettime64 syscall, so the > fallback to timer_gettime is tested. > > Above tests were performed with Y2038 redirection applied as well as > without (so the __TIMESIZE != 64 execution path is checked as well). > > No regressions were observed. > --- > include/time.h | 7 ++++ > sysdeps/unix/sysv/linux/timer_gettime.c | 44 > ++++++++++++++++++++++--- 2 files changed, 47 insertions(+), 4 > deletions(-) > > diff --git a/include/time.h b/include/time.h > index 52ee213669..8b9a4b7a60 100644 > --- a/include/time.h > +++ b/include/time.h > @@ -179,6 +179,13 @@ extern int __futimens64 (int fd, const struct > __timespec64 tsp[2]); libc_hidden_proto (__futimens64); > #endif > > +#if __TIMESIZE == 64 > +# define __timer_gettime64 __timer_gettime > +#else > +extern int __timer_gettime64 (timer_t timerid, struct __itimerspec64 > *value); +libc_hidden_proto (__timer_gettime64); > +#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/timer_gettime.c > b/sysdeps/unix/sysv/linux/timer_gettime.c index > 8d9bef9196..31bf5ce25b 100644 --- > a/sysdeps/unix/sysv/linux/timer_gettime.c +++ > b/sysdeps/unix/sysv/linux/timer_gettime.c @@ -20,15 +20,51 @@ > #include <stdlib.h> > #include <time.h> > #include <sysdep.h> > +#include <kernel-features.h> > #include "kernel-posix-timers.h" > > int > -timer_gettime (timer_t timerid, struct itimerspec *value) > +__timer_gettime64 (timer_t timerid, struct __itimerspec64 *value) > { > struct timer *kt = (struct timer *) timerid; > > - /* Delete the kernel timer object. */ > - int res = INLINE_SYSCALL (timer_gettime, 2, kt->ktimerid, value); > +#ifdef __ASSUME_TIME64_SYSCALLS > +# ifndef __NR_timer_gettime64 > +# define __NR_timer_gettime64 __NR_timer_gettime > +# endif > + return INLINE_SYSCALL (timer_gettime64, 2, kt->ktimerid, value); > +#else > +# ifdef __NR_timer_gettime64 > + int ret = INLINE_SYSCALL (timer_gettime64, 2, kt->ktimerid, value); > + if (ret == 0 || errno != ENOSYS) > + return ret; > +# endif > + struct itimerspec its32; > + int retval = INLINE_SYSCALL (timer_gettime, 2, kt->ktimerid, > &its32); > + if (! retval) > + { > + value->it_interval = valid_timespec_to_timespec64 > (its32.it_interval); > + value->it_value = valid_timespec_to_timespec64 > (its32.it_value); > + } > > - return res; > + return retval; > +#endif > } > + > +#if __TIMESIZE != 64 > +int > +__timer_gettime (timer_t timerid, struct itimerspec *value) > +{ > + struct __itimerspec64 its64; > + int retval = __timer_gettime64 (timerid, &its64); > + if (! retval) > + { > + value->it_interval = valid_timespec64_to_timespec > (its64.it_interval); > + value->it_value = valid_timespec64_to_timespec > (its64.it_value); > + } > + > + return retval; > +} > +#endif > +weak_alias (__timer_gettime, timer_gettime) > +libc_hidden_def (timer_gettime) Gentle ping, Best regards, Lukasz Majewski -- DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de
On 11/11/2019 18:47, Lukasz Majewski wrote: > This patch provides new __timer_gettime64 explicit 64 bit function for reading > status of specified timer. To be more precise - the remaining time and interval > set with timer_settime. > Moreover, a 32 bit version - __timer_gettime has been refactored to internally > use __timer_gettime64. > > The __timer_gettime is now supposed to be used on systems still supporting 32 > bit time (__TIMESIZE != 64) - hence the necessary conversion from 64 bit struct > __timespec64 to struct timespec. > > The new __timer_gettime64 syscall available from Linux 5.1+ has been used, when > applicable. > > Build tests: > - The code has been tested on x86_64/x86 (native compilation): > make PARALLELMFLAGS="-j8" && make check PARALLELMFLAGS="-j8" && \\ > make xcheck PARALLELMFLAGS="-j8" > > - The glibc has been build tested (make PARALLELMFLAGS="-j8") for > x86 (i386), x86_64-x32, and armv7 > > Run-time tests: > - 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 Does it have any additional coverage not present in glibc tests? If yes, would be possible to enhance glibc tests? > > - Use of cross-test-ssh.sh for ARM (armv7): > make PARALLELMFLAGS="-j8" test-wrapper='./cross-test-ssh.sh root@192.168.7.2' xcheck > > Linux kernel, headers and minimal kernel version for glibc build test > matrix: > - Linux v5.1 (with timer_gettime64) and glibc build with v5.1 as > minimal kernel version (--enable-kernel="5.1.0") > The __ASSUME_TIME64_SYSCALLS flag defined. > > - Linux v5.1 and default minimal kernel version > The __ASSUME_TIME64_SYSCALLS not defined, but kernel supports timer_gettime64 > syscall. > > - Linux v4.19 (no timer_gettime64 support) with default minimal kernel version > for contemporary glibc (3.2.0) > This kernel doesn't support timer_gettime64 syscall, so the fallback to > timer_gettime is tested. > > Above tests were performed with Y2038 redirection applied as well as without > (so the __TIMESIZE != 64 execution path is checked as well). > > No regressions were observed. LGTM with some changes below. Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org> > --- > include/time.h | 7 ++++ > sysdeps/unix/sysv/linux/timer_gettime.c | 44 ++++++++++++++++++++++--- > 2 files changed, 47 insertions(+), 4 deletions(-) > > diff --git a/include/time.h b/include/time.h > index 52ee213669..8b9a4b7a60 100644 > --- a/include/time.h > +++ b/include/time.h > @@ -179,6 +179,13 @@ extern int __futimens64 (int fd, const struct __timespec64 tsp[2]); > libc_hidden_proto (__futimens64); > #endif > > +#if __TIMESIZE == 64 > +# define __timer_gettime64 __timer_gettime > +#else > +extern int __timer_gettime64 (timer_t timerid, struct __itimerspec64 *value); > +libc_hidden_proto (__timer_gettime64); > +#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. Ok, it follows current practice. > diff --git a/sysdeps/unix/sysv/linux/timer_gettime.c b/sysdeps/unix/sysv/linux/timer_gettime.c > index 8d9bef9196..31bf5ce25b 100644 > --- a/sysdeps/unix/sysv/linux/timer_gettime.c > +++ b/sysdeps/unix/sysv/linux/timer_gettime.c > @@ -20,15 +20,51 @@ > #include <stdlib.h> > #include <time.h> > #include <sysdep.h> > +#include <kernel-features.h> > #include "kernel-posix-timers.h" > > int > -timer_gettime (timer_t timerid, struct itimerspec *value) > +__timer_gettime64 (timer_t timerid, struct __itimerspec64 *value) > { > struct timer *kt = (struct timer *) timerid; > > - /* Delete the kernel timer object. */ > - int res = INLINE_SYSCALL (timer_gettime, 2, kt->ktimerid, value); > +#ifdef __ASSUME_TIME64_SYSCALLS > +# ifndef __NR_timer_gettime64 > +# define __NR_timer_gettime64 __NR_timer_gettime > +# endif > + return INLINE_SYSCALL (timer_gettime64, 2, kt->ktimerid, value); Use INLINE_SYSCALL_CALL. > +#else > +# ifdef __NR_timer_gettime64 > + int ret = INLINE_SYSCALL (timer_gettime64, 2, kt->ktimerid, value); Ditto. > + if (ret == 0 || errno != ENOSYS) > + return ret; > +# endif > + struct itimerspec its32; > + int retval = INLINE_SYSCALL (timer_gettime, 2, kt->ktimerid, &its32); Ditto. > + if (! retval) Please use an explicit comparison with == 0. > + { > + value->it_interval = valid_timespec_to_timespec64 (its32.it_interval); > + value->it_value = valid_timespec_to_timespec64 (its32.it_value); > + } > > - return res; > + return retval; > +#endif > } > + Ok. > +#if __TIMESIZE != 64 > +int > +__timer_gettime (timer_t timerid, struct itimerspec *value) > +{ > + struct __itimerspec64 its64; > + int retval = __timer_gettime64 (timerid, &its64); > + if (! retval) Please use an explicit comparison with == 0. > + { > + value->it_interval = valid_timespec64_to_timespec (its64.it_interval); > + value->it_value = valid_timespec64_to_timespec (its64.it_value); > + } > + > + return retval; > +} > +#endif > +weak_alias (__timer_gettime, timer_gettime) > +libc_hidden_def (timer_gettime) > Ok.
Hi Adhemerval, Thank you for your review. I'm making those pointed out minor adjustments, re-test the code and pull to master. > On 11/11/2019 18:47, Lukasz Majewski wrote: > > This patch provides new __timer_gettime64 explicit 64 bit function > > for reading status of specified timer. To be more precise - the > > remaining time and interval set with timer_settime. > > Moreover, a 32 bit version - __timer_gettime has been refactored to > > internally use __timer_gettime64. > > > > The __timer_gettime is now supposed to be used on systems still > > supporting 32 bit time (__TIMESIZE != 64) - hence the necessary > > conversion from 64 bit struct __timespec64 to struct timespec. > > > > The new __timer_gettime64 syscall available from Linux 5.1+ has > > been used, when applicable. > > > > Build tests: > > - The code has been tested on x86_64/x86 (native compilation): > > make PARALLELMFLAGS="-j8" && make check PARALLELMFLAGS="-j8" && \\ > > make xcheck PARALLELMFLAGS="-j8" > > > > - The glibc has been build tested (make PARALLELMFLAGS="-j8") for > > x86 (i386), x86_64-x32, and armv7 > > > > Run-time tests: > > - 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 > > Does it have any additional coverage not present in glibc tests? If > yes, would be possible to enhance glibc tests? Those tests are for 32 bit archs (ARM, x86, x86-x32, RISC-V) with set -D_TIME_BITS=64 during the compilation (to check if the system is Y2038 safe). As glibc is not yet supporting this flag, I don't add them to glibc's tests. I do plan to add them when we make "the big switch" and instantly add -D_TIME_BITS64 support to glibc. In the meanwhile I do rely on current glibc's setup to catch regressions when I convert functions eligible for Y2038 enhancement (which do support __ASSUME_TIME64_SYSCALLS flag). > > > > > - Use of cross-test-ssh.sh for ARM (armv7): > > make PARALLELMFLAGS="-j8" test-wrapper='./cross-test-ssh.sh > > root@192.168.7.2' xcheck > > > > Linux kernel, headers and minimal kernel version for glibc build > > test matrix: > > - Linux v5.1 (with timer_gettime64) and glibc build with v5.1 as > > minimal kernel version (--enable-kernel="5.1.0") > > The __ASSUME_TIME64_SYSCALLS flag defined. > > > > - Linux v5.1 and default minimal kernel version > > The __ASSUME_TIME64_SYSCALLS not defined, but kernel supports > > timer_gettime64 syscall. > > > > - Linux v4.19 (no timer_gettime64 support) with default minimal > > kernel version for contemporary glibc (3.2.0) > > This kernel doesn't support timer_gettime64 syscall, so the > > fallback to timer_gettime is tested. > > > > Above tests were performed with Y2038 redirection applied as well > > as without (so the __TIMESIZE != 64 execution path is checked as > > well). > > > > No regressions were observed. > > LGTM with some changes below. > > Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org> > > > --- > > include/time.h | 7 ++++ > > sysdeps/unix/sysv/linux/timer_gettime.c | 44 > > ++++++++++++++++++++++--- 2 files changed, 47 insertions(+), 4 > > deletions(-) > > > > diff --git a/include/time.h b/include/time.h > > index 52ee213669..8b9a4b7a60 100644 > > --- a/include/time.h > > +++ b/include/time.h > > @@ -179,6 +179,13 @@ extern int __futimens64 (int fd, const struct > > __timespec64 tsp[2]); libc_hidden_proto (__futimens64); > > #endif > > > > +#if __TIMESIZE == 64 > > +# define __timer_gettime64 __timer_gettime > > +#else > > +extern int __timer_gettime64 (timer_t timerid, struct > > __itimerspec64 *value); +libc_hidden_proto (__timer_gettime64); > > +#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. > > > > Ok, it follows current practice. > > > diff --git a/sysdeps/unix/sysv/linux/timer_gettime.c > > b/sysdeps/unix/sysv/linux/timer_gettime.c index > > 8d9bef9196..31bf5ce25b 100644 --- > > a/sysdeps/unix/sysv/linux/timer_gettime.c +++ > > b/sysdeps/unix/sysv/linux/timer_gettime.c @@ -20,15 +20,51 @@ > > #include <stdlib.h> > > #include <time.h> > > #include <sysdep.h> > > +#include <kernel-features.h> > > #include "kernel-posix-timers.h" > > > > int > > -timer_gettime (timer_t timerid, struct itimerspec *value) > > +__timer_gettime64 (timer_t timerid, struct __itimerspec64 *value) > > { > > struct timer *kt = (struct timer *) timerid; > > > > - /* Delete the kernel timer object. */ > > - int res = INLINE_SYSCALL (timer_gettime, 2, kt->ktimerid, value); > > +#ifdef __ASSUME_TIME64_SYSCALLS > > +# ifndef __NR_timer_gettime64 > > +# define __NR_timer_gettime64 __NR_timer_gettime > > +# endif > > + return INLINE_SYSCALL (timer_gettime64, 2, kt->ktimerid, value); > > > > Use INLINE_SYSCALL_CALL. > > > +#else > > +# ifdef __NR_timer_gettime64 > > + int ret = INLINE_SYSCALL (timer_gettime64, 2, kt->ktimerid, > > value); > > Ditto. > > > + if (ret == 0 || errno != ENOSYS) > > + return ret; > > +# endif > > + struct itimerspec its32; > > + int retval = INLINE_SYSCALL (timer_gettime, 2, kt->ktimerid, > > &its32); > > Ditto. > > > + if (! retval) > > Please use an explicit comparison with == 0. > > > + { > > + value->it_interval = valid_timespec_to_timespec64 > > (its32.it_interval); > > + value->it_value = valid_timespec_to_timespec64 > > (its32.it_value); > > + } > > > > - return res; > > + return retval; > > +#endif > > } > > + > > Ok. > > > +#if __TIMESIZE != 64 > > +int > > +__timer_gettime (timer_t timerid, struct itimerspec *value) > > +{ > > + struct __itimerspec64 its64; > > + int retval = __timer_gettime64 (timerid, &its64); > > + if (! retval) > > Please use an explicit comparison with == 0. > > > + { > > + value->it_interval = valid_timespec64_to_timespec > > (its64.it_interval); > > + value->it_value = valid_timespec64_to_timespec > > (its64.it_value); > > + } > > + > > + return retval; > > +} > > +#endif > > +weak_alias (__timer_gettime, timer_gettime) > > +libc_hidden_def (timer_gettime) > > > > Ok. Best regards, Lukasz Majewski -- DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de
On Nov 11 2019, Lukasz Majewski wrote: > diff --git a/include/time.h b/include/time.h > index 52ee213669..8b9a4b7a60 100644 > --- a/include/time.h > +++ b/include/time.h > @@ -179,6 +179,13 @@ extern int __futimens64 (int fd, const struct __timespec64 tsp[2]); > libc_hidden_proto (__futimens64); > #endif > > +#if __TIMESIZE == 64 > +# define __timer_gettime64 __timer_gettime > +#else > +extern int __timer_gettime64 (timer_t timerid, struct __itimerspec64 *value); > +libc_hidden_proto (__timer_gettime64); This libc_hidden_proto is wrong since timer_gettime64 lives in librt. Andreas.
Hi Andreas, > On Nov 11 2019, Lukasz Majewski wrote: > > > diff --git a/include/time.h b/include/time.h > > index 52ee213669..8b9a4b7a60 100644 > > --- a/include/time.h > > +++ b/include/time.h > > @@ -179,6 +179,13 @@ extern int __futimens64 (int fd, const struct > > __timespec64 tsp[2]); libc_hidden_proto (__futimens64); > > #endif > > > > +#if __TIMESIZE == 64 > > +# define __timer_gettime64 __timer_gettime > > +#else > > +extern int __timer_gettime64 (timer_t timerid, struct > > __itimerspec64 *value); +libc_hidden_proto (__timer_gettime64); > > This libc_hidden_proto is wrong since timer_gettime64 lives in librt. > I may be not so experienced glibc developer, but isn't the libc_hidden_proto macro used to bypass plt access to this function when it is used internally in glibc? For librt there is the same symbol (and stub function defined) for backward compatibility. Or am I missing something important? Thanks in advance for the explanation. > Andreas. > Best regards, Lukasz Majewski -- DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de
On Dez 11 2019, Lukasz Majewski wrote: > I may be not so experienced glibc developer, but isn't the > libc_hidden_proto macro used to bypass plt access to this function when > it is used internally in glibc? But there is no timer_gettime in libc. > For librt there is the same symbol (and stub function defined) for > backward compatibility. ??? The implementation in librt is not a stub function. Andreas.
Hi Andreas, > On Dez 11 2019, Lukasz Majewski wrote: > > > I may be not so experienced glibc developer, but isn't the > > libc_hidden_proto macro used to bypass plt access to this function > > when it is used internally in glibc? > > But there is no timer_gettime in libc. Please find below link: https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/timer_gettime.c;h=20d34dbfa97de7e9d8e4071426fa463bb524e863;hb=HEAD > > > For librt there is the same symbol (and stub function defined) for > > backward compatibility. > > ??? The implementation in librt is not a stub function. > Please find following link: https://sourceware.org/git/?p=glibc.git;a=tree;f=rt;h=8187c0183ec2a9ef1a71fc7916e37e6242ef83ca;hb=HEAD > Andreas. > Best regards, Lukasz Majewski -- DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de
On Dez 12 2019, Lukasz Majewski wrote: > Please find below link: > https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/timer_gettime.c;h=20d34dbfa97de7e9d8e4071426fa463bb524e863;hb=HEAD What does that show? > Please find following link: > https://sourceware.org/git/?p=glibc.git;a=tree;f=rt;h=8187c0183ec2a9ef1a71fc7916e37e6242ef83ca;hb=HEAD What does that show? Andreas.
On Thu, 12 Dec 2019 16:46:50 +0100 Andreas Schwab <schwab@suse.de> wrote: > On Dez 12 2019, Lukasz Majewski wrote: > > > Please find below link: > > https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/timer_gettime.c;h=20d34dbfa97de7e9d8e4071426fa463bb524e863;hb=HEAD > > > > What does that show? > > > Please find following link: > > https://sourceware.org/git/?p=glibc.git;a=tree;f=rt;h=8187c0183ec2a9ef1a71fc7916e37e6242ef83ca;hb=HEAD > > > > What does that show? It shows that for rt you have one version of timer_gettime (with stub_warning) in /rt and another one in the Linux specific one for glibc. At least from the directory structure POV. However, I don't know how it is resolved with compatibility symbols. > > Andreas. > Best regards, Lukasz Majewski -- DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de
There is only one timer_gettime, and that lives in librt. The source file rt/timer_gettime.c is not used. Andreas.
diff --git a/include/time.h b/include/time.h index 52ee213669..8b9a4b7a60 100644 --- a/include/time.h +++ b/include/time.h @@ -179,6 +179,13 @@ extern int __futimens64 (int fd, const struct __timespec64 tsp[2]); libc_hidden_proto (__futimens64); #endif +#if __TIMESIZE == 64 +# define __timer_gettime64 __timer_gettime +#else +extern int __timer_gettime64 (timer_t timerid, struct __itimerspec64 *value); +libc_hidden_proto (__timer_gettime64); +#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/timer_gettime.c b/sysdeps/unix/sysv/linux/timer_gettime.c index 8d9bef9196..31bf5ce25b 100644 --- a/sysdeps/unix/sysv/linux/timer_gettime.c +++ b/sysdeps/unix/sysv/linux/timer_gettime.c @@ -20,15 +20,51 @@ #include <stdlib.h> #include <time.h> #include <sysdep.h> +#include <kernel-features.h> #include "kernel-posix-timers.h" int -timer_gettime (timer_t timerid, struct itimerspec *value) +__timer_gettime64 (timer_t timerid, struct __itimerspec64 *value) { struct timer *kt = (struct timer *) timerid; - /* Delete the kernel timer object. */ - int res = INLINE_SYSCALL (timer_gettime, 2, kt->ktimerid, value); +#ifdef __ASSUME_TIME64_SYSCALLS +# ifndef __NR_timer_gettime64 +# define __NR_timer_gettime64 __NR_timer_gettime +# endif + return INLINE_SYSCALL (timer_gettime64, 2, kt->ktimerid, value); +#else +# ifdef __NR_timer_gettime64 + int ret = INLINE_SYSCALL (timer_gettime64, 2, kt->ktimerid, value); + if (ret == 0 || errno != ENOSYS) + return ret; +# endif + struct itimerspec its32; + int retval = INLINE_SYSCALL (timer_gettime, 2, kt->ktimerid, &its32); + if (! retval) + { + value->it_interval = valid_timespec_to_timespec64 (its32.it_interval); + value->it_value = valid_timespec_to_timespec64 (its32.it_value); + } - return res; + return retval; +#endif } + +#if __TIMESIZE != 64 +int +__timer_gettime (timer_t timerid, struct itimerspec *value) +{ + struct __itimerspec64 its64; + int retval = __timer_gettime64 (timerid, &its64); + if (! retval) + { + value->it_interval = valid_timespec64_to_timespec (its64.it_interval); + value->it_value = valid_timespec64_to_timespec (its64.it_value); + } + + return retval; +} +#endif +weak_alias (__timer_gettime, timer_gettime) +libc_hidden_def (timer_gettime)