Message ID | 20191105234249.25626-2-alistair.francis@wdc.com |
---|---|
State | New |
Headers | show |
Series | [1/2] sysdeps: Add clock_gettime64 vDSO | expand |
Hi Alistair, > --- > This was patch was runtime tested with RV32 and RV64 > It was build tested using the ./scripts/build-many-glibcs.py script. > > I will run: > $ make ; make install ; make check > tests on native ARM (32-bit) with the following three confiugrations: > - 4.19 Kernel and 4.19 Headers > - 5.2 Kernel and 4.19 Headers > - 5.2 Kernel and 5.2 Headers > I should have the results later this week. > > include/time.h | 3 ++ > sysdeps/unix/sysv/linux/clock_gettime.c | 50 > ++++++++++++++++++++++++- 2 files changed, 52 insertions(+), 1 > deletion(-) > > diff --git a/include/time.h b/include/time.h > index e0974309726..d4cdfdf38e8 100644 > --- a/include/time.h > +++ b/include/time.h > @@ -214,6 +214,7 @@ extern double __difftime (time_t time1, time_t > time0); # define __clock_nanosleep_time64 __clock_nanosleep > # define __nanosleep_time64 __nanosleep > # define __nanosleep_nocancel_time64 __nanosleep_nocancel > +# define __clock_gettime64 __clock_gettime > #else > extern int __thrd_sleep_time64 (const struct __timespec64* > time_point, struct __timespec64* remaining); > @@ -228,6 +229,8 @@ libc_hidden_proto (__nanosleep_time64) > extern int __nanosleep_nocancel_time64 (const struct __timespec64 > *requested_time, struct __timespec64 *remaining); > libc_hidden_proto (__nanosleep_nocancel_time64) > +extern int __clock_gettime64 (clockid_t clock_id, struct > __timespec64 *tp); +libc_hidden_proto (__clock_gettime64) > #endif > > /* Use in the clock_* functions. Size of the field representing the > diff --git a/sysdeps/unix/sysv/linux/clock_gettime.c > b/sysdeps/unix/sysv/linux/clock_gettime.c index > ca40983f6ca..b2ed3f2b698 100644 --- > a/sysdeps/unix/sysv/linux/clock_gettime.c +++ > b/sysdeps/unix/sysv/linux/clock_gettime.c @@ -17,6 +17,7 @@ > <https://www.gnu.org/licenses/>. */ > > #include <sysdep.h> > +#include <kernel-features.h> > #include <errno.h> > #include <time.h> > #include "kernel-posix-cpu-timers.h" > @@ -30,10 +31,57 @@ > > /* Get current value of CLOCK and store it in TP. */ > int > +__clock_gettime64 (clockid_t clock_id, struct __timespec64 *tp) > +{ > +#ifdef __ASSUME_TIME64_SYSCALLS > +# ifndef __NR_clock_gettime64 > +# define __NR_clock_gettime64 __NR_clock_gettime > +# define __vdso_clock_gettime64 __vdso_clock_gettime > +# endif > + return INLINE_VSYSCALL (clock_gettime64, 2, clock_id, tp); > +#else > +# if defined __NR_clock_gettime64 && defined > HAVE_CLOCK_GETTIME64_VSYSCALL > + long int ret_64; Minor comment: IMHO it would be enough to have 'int ret_64;' Also, in the commit description it would be worth to mention that with clock_gettime64 call we prefer to use vDSO (no call to clock_gettime64 on glibc with older headers and kernel 5.1+ if it doesn't support vDSO). > + ret_64 = INLINE_VSYSCALL (clock_gettime64, 2, clock_id, tp); > + > + if (ret_64 == 0 || errno != ENOSYS) > + return ret_64; > +# endif /* __NR_clock_gettime64 && HAVE_CLOCK_GETTIME64_VSYSCALL */ > + int ret; > + struct timespec tp32; > + > + ret = INLINE_VSYSCALL (clock_gettime, 2, clock_id, &tp32); > + > + if (ret == 0 || errno != ENOSYS) > + *tp = valid_timespec_to_timespec64 (tp32); > + > + return ret; > +#endif /* __ASSUME_TIME64_SYSCALLS */ > +} > + > +#if __TIMESIZE != 64 > +int > __clock_gettime (clockid_t clock_id, struct timespec *tp) > { > - return INLINE_VSYSCALL (clock_gettime, 2, clock_id, tp); > + int ret; > + struct __timespec64 tp64; > + > + ret = __clock_gettime64 (clock_id, &tp64); > + > + if (ret == 0 || errno != ENOSYS) > + { > + if (! in_time_t_range (tp64.tv_sec)) > + { > + __set_errno (EOVERFLOW); > + return -1; > + } > + > + *tp = valid_timespec64_to_timespec (tp64); > + } > + > + return ret; > } > +#endif > libc_hidden_def (__clock_gettime) > > versioned_symbol (libc, __clock_gettime, clock_gettime, GLIBC_2_17); Thanks for preparing the patch :-) 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
diff --git a/include/time.h b/include/time.h index e0974309726..d4cdfdf38e8 100644 --- a/include/time.h +++ b/include/time.h @@ -214,6 +214,7 @@ extern double __difftime (time_t time1, time_t time0); # define __clock_nanosleep_time64 __clock_nanosleep # define __nanosleep_time64 __nanosleep # define __nanosleep_nocancel_time64 __nanosleep_nocancel +# define __clock_gettime64 __clock_gettime #else extern int __thrd_sleep_time64 (const struct __timespec64* time_point, struct __timespec64* remaining); @@ -228,6 +229,8 @@ libc_hidden_proto (__nanosleep_time64) extern int __nanosleep_nocancel_time64 (const struct __timespec64 *requested_time, struct __timespec64 *remaining); libc_hidden_proto (__nanosleep_nocancel_time64) +extern int __clock_gettime64 (clockid_t clock_id, struct __timespec64 *tp); +libc_hidden_proto (__clock_gettime64) #endif /* Use in the clock_* functions. Size of the field representing the diff --git a/sysdeps/unix/sysv/linux/clock_gettime.c b/sysdeps/unix/sysv/linux/clock_gettime.c index ca40983f6ca..b2ed3f2b698 100644 --- a/sysdeps/unix/sysv/linux/clock_gettime.c +++ b/sysdeps/unix/sysv/linux/clock_gettime.c @@ -17,6 +17,7 @@ <https://www.gnu.org/licenses/>. */ #include <sysdep.h> +#include <kernel-features.h> #include <errno.h> #include <time.h> #include "kernel-posix-cpu-timers.h" @@ -30,10 +31,57 @@ /* Get current value of CLOCK and store it in TP. */ int +__clock_gettime64 (clockid_t clock_id, struct __timespec64 *tp) +{ +#ifdef __ASSUME_TIME64_SYSCALLS +# ifndef __NR_clock_gettime64 +# define __NR_clock_gettime64 __NR_clock_gettime +# define __vdso_clock_gettime64 __vdso_clock_gettime +# endif + return INLINE_VSYSCALL (clock_gettime64, 2, clock_id, tp); +#else +# if defined __NR_clock_gettime64 && defined HAVE_CLOCK_GETTIME64_VSYSCALL + long int ret_64; + ret_64 = INLINE_VSYSCALL (clock_gettime64, 2, clock_id, tp); + + if (ret_64 == 0 || errno != ENOSYS) + return ret_64; +# endif /* __NR_clock_gettime64 && HAVE_CLOCK_GETTIME64_VSYSCALL */ + int ret; + struct timespec tp32; + + ret = INLINE_VSYSCALL (clock_gettime, 2, clock_id, &tp32); + + if (ret == 0 || errno != ENOSYS) + *tp = valid_timespec_to_timespec64 (tp32); + + return ret; +#endif /* __ASSUME_TIME64_SYSCALLS */ +} + +#if __TIMESIZE != 64 +int __clock_gettime (clockid_t clock_id, struct timespec *tp) { - return INLINE_VSYSCALL (clock_gettime, 2, clock_id, tp); + int ret; + struct __timespec64 tp64; + + ret = __clock_gettime64 (clock_id, &tp64); + + if (ret == 0 || errno != ENOSYS) + { + if (! in_time_t_range (tp64.tv_sec)) + { + __set_errno (EOVERFLOW); + return -1; + } + + *tp = valid_timespec64_to_timespec (tp64); + } + + return ret; } +#endif libc_hidden_def (__clock_gettime) versioned_symbol (libc, __clock_gettime, clock_gettime, GLIBC_2_17);