Message ID | 20191123222708.17021-2-alistair.francis@wdc.com |
---|---|
State | New, archived |
Headers |
Received: (qmail 119074 invoked by alias); 23 Nov 2019 22:32:47 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: <libc-alpha.sourceware.org> List-Unsubscribe: <mailto:libc-alpha-unsubscribe-##L=##H@sourceware.org> List-Subscribe: <mailto:libc-alpha-subscribe@sourceware.org> List-Archive: <http://sourceware.org/ml/libc-alpha/> List-Post: <mailto:libc-alpha@sourceware.org> List-Help: <mailto:libc-alpha-help@sourceware.org>, <http://sourceware.org/ml/#faqs> Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 118982 invoked by uid 89); 23 Nov 2019 22:32:46 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-26.7 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT autolearn=ham version=3.3.1 spammy= X-HELO: esa2.hgst.iphmx.com DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=wdc.com; i=@wdc.com; q=dns/txt; s=dkim.wdc.com; t=1574548398; x=1606084398; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=zB49YsymUj0JCf4h3HW2g3M+NEPaOd4o0eG9hTpP7V4=; b=LbxaR2lee//o0bax/iEXXOQjVKXmQmq8kPRX/UGr6uc3LaY6rV+Z5PDd quekphMIA98mvdQOxpoUk4eAIFyN0NL9EKCfJ4jgtjCXTggv3Azjg1iRC 6OiSz5CNkWWGRR9gsw+Elq44RB3DzFTzh9ci6IIx2RPgEG6pZ/jwZXkzp l5zC1M63Kp2gwIAmpHMrL3/ldKbllS/n/0GVwyvtnrZrrLrHdI2YpOcYv p5EpczYW4E58SUzGYLDd+DCm9nu7aq0Lh3niiY0bY2V7CBF0zJg2Am8tE B9PoQnYS8qlDFDaN4yWPF3S4UZ71MiJGx+xR+1w0kzQ45Xu+GbkTjmrYf w==; IronPort-SDR: O3S7rTRgU5PL0qi8QqzhhLgBZjii/Q4vOY3m9M/MrprZErOX+SbW89lanPuUtdD/ffQMUJ5YGg hEWDRZFEWilEu4Hq0StstSj2XPy1ZumYTMGKKmU6FJM+FX8OvUDa9EPPj13bdLE9Paq+w4BU/H paldpATx+BH6Vj0rAeOW4cAl8U5mrQIHqRA96y32PXJbwcqNUp9kEGGDdqNq8lGukRhoJPs7do DJCt5QblpdUlz/bGa5YVkQ5Qks7FrUqpZbMZGCcLQfyjzVgdcjue6yyOmSQK3lt2b9+NwQHdfu 7rI= IronPort-SDR: fd4fFGttux5D41+pfD7MJ0BXFBnMhrT0iMFL0thj0JAKPfDkprc3YJo3dXyRin8c/a1hfxW9BY Dsrljn5/v+5+zqkEF/fZiUTJ4a4IV7xoujM0L+0TPRxWPKTSqhbKJotNs8vY2fBhxDvCE57DBk dJTow2zf/7qVKhMvmTZ8d2AVJiWLvA1MhrCU08Q89fIqMO8BKNLdUTP4ksK9Sl8p/sBOUlo1jX hYI1BBIaknq0wHk08809+QA48YMIUQSvL4/onwuQChUavAudsGNWdRUtQKYAn35FBo9QmUSp5W z/LVWROY27e1rURHRqPm0GBf IronPort-SDR: Ak3C0XMHsiBZAKe5gH0MPhiTctmgY6e9BaSebhkr3uM81NE2RLy4JXrWVtLrL/LoRDR1Srarq0 w+NYEi4QIXPD9AcdueYG42MM0nG2qJlY0+xE39b0urJ52wV2i9paOPHR+1S83ne47oDKRdjcvM 2Sba3miY8VDEoaNihkRSp6D7fg7vtynMczOnbgMvIHBbFT86b8QncezWVsJvq3Hv/Gq8idIznw 9cDucvO60h2moKi2xrIjZXZprf94CWxsFanPin20kQvKoUQCpyyldivFZEAc+xsxcLNwjyaFao tvc= WDCIronportException: Internal From: Alistair Francis <alistair.francis@wdc.com> To: libc-alpha@sourceware.org Cc: alistair23@gmail.com, Alistair Francis <alistair.francis@wdc.com> Subject: [PATCH v3 2/2] sysdeps/clock_gettime: Use clock_gettime64 if avaliable Date: Sat, 23 Nov 2019 14:27:08 -0800 Message-Id: <20191123222708.17021-2-alistair.francis@wdc.com> In-Reply-To: <20191123222708.17021-1-alistair.francis@wdc.com> References: <20191123222708.17021-1-alistair.francis@wdc.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit |
Commit Message
Alistair Francis
Nov. 23, 2019, 10:27 p.m. UTC
With the clock_gettime64 call we prefer to use vDSO. There is no call to clock_gettime64 on glibc with older headers and kernel 5.1+ if it doesn't support vDSO. --- This was patch was runtime tested with RV32 and RV64 It was build tested using the ./scripts/build-many-glibcs.py script. I also ran: $ 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 and didn't see any regressions v3: - Assume HAVE_CLOCK_GETTIME64_VSYSCALL means we have __NR_clock_gettime64 - Change code style to be more glibc-ish v2: - Add commit message - Change ret_64 to int include/time.h | 3 ++ sysdeps/unix/sysv/linux/clock_gettime.c | 44 ++++++++++++++++++++++++- 2 files changed, 46 insertions(+), 1 deletion(-)
Comments
On Sat, Nov 23, 2019 at 2:32 PM Alistair Francis <alistair.francis@wdc.com> wrote: > > With the clock_gettime64 call we prefer to use vDSO. There is no call > to clock_gettime64 on glibc with older headers and kernel 5.1+ if it > doesn't support vDSO. Ping! Alistair > --- > This was patch was runtime tested with RV32 and RV64 > It was build tested using the ./scripts/build-many-glibcs.py script. > > I also ran: > $ 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 > and didn't see any regressions > > v3: > - Assume HAVE_CLOCK_GETTIME64_VSYSCALL means we have __NR_clock_gettime64 > - Change code style to be more glibc-ish > v2: > - Add commit message > - Change ret_64 to int > > include/time.h | 3 ++ > sysdeps/unix/sysv/linux/clock_gettime.c | 44 ++++++++++++++++++++++++- > 2 files changed, 46 insertions(+), 1 deletion(-) > > diff --git a/include/time.h b/include/time.h > index d7800eb30f..c19c73ae09 100644 > --- a/include/time.h > +++ b/include/time.h > @@ -211,11 +211,14 @@ extern double __difftime (time_t time1, time_t time0); > > #if __TIMESIZE == 64 > # define __clock_nanosleep_time64 __clock_nanosleep > +# define __clock_gettime64 __clock_gettime > #else > extern int __clock_nanosleep_time64 (clockid_t clock_id, > int flags, const struct __timespec64 *req, > struct __timespec64 *rem); > libc_hidden_proto (__clock_nanosleep_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 ca40983f6c..875c4fe905 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,51 @@ > > /* 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 HAVE_CLOCK_GETTIME64_VSYSCALL > + int ret64 = INLINE_VSYSCALL (clock_gettime64, 2, clock_id, tp); > + if (ret64 == 0 || errno != ENOSYS) > + return ret64; > +# endif > + struct timespec tp32; > + int ret = INLINE_VSYSCALL (clock_gettime, 2, clock_id, &tp32); > + if (ret == 0) > + *tp = valid_timespec_to_timespec64 (tp32); > + return ret; > +#endif > +} > + > +#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) > + { > + 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); > -- > 2.24.0 >
On 23/11/2019 19:27, Alistair Francis wrote: > With the clock_gettime64 call we prefer to use vDSO. There is no call > to clock_gettime64 on glibc with older headers and kernel 5.1+ if it > doesn't support vDSO. Ok with the fix below regarding HAVE_CLOCK_GETTIME64_VSYSCALL. > --- > This was patch was runtime tested with RV32 and RV64 > It was build tested using the ./scripts/build-many-glibcs.py script. > > I also ran: > $ 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 > and didn't see any regressions > > v3: > - Assume HAVE_CLOCK_GETTIME64_VSYSCALL means we have __NR_clock_gettime64 > - Change code style to be more glibc-ish > v2: > - Add commit message > - Change ret_64 to int > > include/time.h | 3 ++ > sysdeps/unix/sysv/linux/clock_gettime.c | 44 ++++++++++++++++++++++++- > 2 files changed, 46 insertions(+), 1 deletion(-) > > diff --git a/include/time.h b/include/time.h > index d7800eb30f..c19c73ae09 100644 > --- a/include/time.h > +++ b/include/time.h > @@ -211,11 +211,14 @@ extern double __difftime (time_t time1, time_t time0); > > #if __TIMESIZE == 64 > # define __clock_nanosleep_time64 __clock_nanosleep > +# define __clock_gettime64 __clock_gettime > #else > extern int __clock_nanosleep_time64 (clockid_t clock_id, > int flags, const struct __timespec64 *req, > struct __timespec64 *rem); > libc_hidden_proto (__clock_nanosleep_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 ca40983f6c..875c4fe905 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,51 @@ > > /* 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); Ok, in this case either __vdso_clock_gettime/__NR_clock_gettime or __vdso_clock_gettime64/__NR_clock_gettime64 will be called. > +#else > +# if defined HAVE_CLOCK_GETTIME64_VSYSCALL > + int ret64 = INLINE_VSYSCALL (clock_gettime64, 2, clock_id, tp); > + if (ret64 == 0 || errno != ENOSYS) > + return ret64; > +# endif This should be: #if defined __NR_clock_gettime64 int ret64 = INLINE_VSYSCALL (clock_gettime64, ...) [...] And before sysdep-vdso.h it should be. #if defined HAVE_CLOCK_GETTIME_VSYSCALL || defined HAVE_CLOCK_GETTIME64_VSYSCALL # define HAVE_SYSCALL #endif If !HAVE_SYSCALL the INLINE_VSYSCALL is defined as INLINE_SYCALL. It means that if an architecture does provide __NR_clock_gettime64 but not provide HAVE_CLOCK_GETTIME64_VSYSCALL, it will still use the syscall. This code only uses the syscall if the vDSO is still present. I hope I can get my vDSO refactor, which would simplify a bit this code. > + struct timespec tp32; > + int ret = INLINE_VSYSCALL (clock_gettime, 2, clock_id, &tp32); > + if (ret == 0) > + *tp = valid_timespec_to_timespec64 (tp32); > + return ret; > +#endif > +} Ok, old fallback to time32 vdso/syscall. > + > +#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) > + { > + 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); > Ok.
On 03/12/2019 16:29, Adhemerval Zanella wrote: > > > On 23/11/2019 19:27, Alistair Francis wrote: >> With the clock_gettime64 call we prefer to use vDSO. There is no call >> to clock_gettime64 on glibc with older headers and kernel 5.1+ if it >> doesn't support vDSO. > > Ok with the fix below regarding HAVE_CLOCK_GETTIME64_VSYSCALL. As [1] I think we can handle both the cases: 8. Define both __NR_clock_gettime64, provide a 64-bit vDSO, define __NR_clock_gettime, and provide a 32-bit vDSO. - i.e: some 32-bits ports built against kernel header equal or newer then v5.1 (i386, arm, and mips). 9. Define both __NR_clock_gettime64, provide a 64-bit vDSO, and define __NR_clock_gettime (unlikely, but possible).. With my vDSO refactor to use relro data structures. This patch is ok. Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org> [1] https://sourceware.org/ml/libc-alpha/2019-12/msg00142.html > >> --- >> This was patch was runtime tested with RV32 and RV64 >> It was build tested using the ./scripts/build-many-glibcs.py script. >> >> I also ran: >> $ 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 >> and didn't see any regressions >> >> v3: >> - Assume HAVE_CLOCK_GETTIME64_VSYSCALL means we have __NR_clock_gettime64 >> - Change code style to be more glibc-ish >> v2: >> - Add commit message >> - Change ret_64 to int >> >> include/time.h | 3 ++ >> sysdeps/unix/sysv/linux/clock_gettime.c | 44 ++++++++++++++++++++++++- >> 2 files changed, 46 insertions(+), 1 deletion(-) >> >> diff --git a/include/time.h b/include/time.h >> index d7800eb30f..c19c73ae09 100644 >> --- a/include/time.h >> +++ b/include/time.h >> @@ -211,11 +211,14 @@ extern double __difftime (time_t time1, time_t time0); >> >> #if __TIMESIZE == 64 >> # define __clock_nanosleep_time64 __clock_nanosleep >> +# define __clock_gettime64 __clock_gettime >> #else >> extern int __clock_nanosleep_time64 (clockid_t clock_id, >> int flags, const struct __timespec64 *req, >> struct __timespec64 *rem); >> libc_hidden_proto (__clock_nanosleep_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 ca40983f6c..875c4fe905 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,51 @@ >> >> /* 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); > > Ok, in this case either __vdso_clock_gettime/__NR_clock_gettime or > __vdso_clock_gettime64/__NR_clock_gettime64 will be called. > >> +#else >> +# if defined HAVE_CLOCK_GETTIME64_VSYSCALL >> + int ret64 = INLINE_VSYSCALL (clock_gettime64, 2, clock_id, tp); >> + if (ret64 == 0 || errno != ENOSYS) >> + return ret64; >> +# endif > This should be: > > #if defined __NR_clock_gettime64 > int ret64 = INLINE_VSYSCALL (clock_gettime64, ...) > [...] > > And before sysdep-vdso.h it should be. > > #if defined HAVE_CLOCK_GETTIME_VSYSCALL || defined HAVE_CLOCK_GETTIME64_VSYSCALL > # define HAVE_SYSCALL > #endif > > If !HAVE_SYSCALL the INLINE_VSYSCALL is defined as INLINE_SYCALL. > It means that if an architecture does provide __NR_clock_gettime64 > but not provide HAVE_CLOCK_GETTIME64_VSYSCALL, it will still use > the syscall. This code only uses the syscall if the vDSO is still > present. > > I hope I can get my vDSO refactor, which would simplify a bit this > code. > >> + struct timespec tp32; >> + int ret = INLINE_VSYSCALL (clock_gettime, 2, clock_id, &tp32); >> + if (ret == 0) >> + *tp = valid_timespec_to_timespec64 (tp32); >> + return ret; >> +#endif >> +} > > Ok, old fallback to time32 vdso/syscall. > >> + >> +#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) >> + { >> + 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); >> > > Ok. >
On Wed, Dec 4, 2019 at 9:24 AM Adhemerval Zanella <adhemerval.zanella@linaro.org> wrote: > > > > On 03/12/2019 16:29, Adhemerval Zanella wrote: > > > > > > On 23/11/2019 19:27, Alistair Francis wrote: > >> With the clock_gettime64 call we prefer to use vDSO. There is no call > >> to clock_gettime64 on glibc with older headers and kernel 5.1+ if it > >> doesn't support vDSO. > > > > Ok with the fix below regarding HAVE_CLOCK_GETTIME64_VSYSCALL. > > As [1] I think we can handle both the cases: > > 8. Define both __NR_clock_gettime64, provide a 64-bit vDSO, define > __NR_clock_gettime, and provide a 32-bit vDSO. > - i.e: some 32-bits ports built against kernel header equal or newer > then v5.1 (i386, arm, and mips). > > 9. Define both __NR_clock_gettime64, provide a 64-bit vDSO, and > define __NR_clock_gettime (unlikely, but possible).. > > With my vDSO refactor to use relro data structures. > > This patch is ok. > > Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org> Thanks :) I'll apply these two patches later today unless there are any other comments. Alistair > > [1] https://sourceware.org/ml/libc-alpha/2019-12/msg00142.html > > > > >> --- > >> This was patch was runtime tested with RV32 and RV64 > >> It was build tested using the ./scripts/build-many-glibcs.py script. > >> > >> I also ran: > >> $ 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 > >> and didn't see any regressions > >> > >> v3: > >> - Assume HAVE_CLOCK_GETTIME64_VSYSCALL means we have __NR_clock_gettime64 > >> - Change code style to be more glibc-ish > >> v2: > >> - Add commit message > >> - Change ret_64 to int > >> > >> include/time.h | 3 ++ > >> sysdeps/unix/sysv/linux/clock_gettime.c | 44 ++++++++++++++++++++++++- > >> 2 files changed, 46 insertions(+), 1 deletion(-) > >> > >> diff --git a/include/time.h b/include/time.h > >> index d7800eb30f..c19c73ae09 100644 > >> --- a/include/time.h > >> +++ b/include/time.h > >> @@ -211,11 +211,14 @@ extern double __difftime (time_t time1, time_t time0); > >> > >> #if __TIMESIZE == 64 > >> # define __clock_nanosleep_time64 __clock_nanosleep > >> +# define __clock_gettime64 __clock_gettime > >> #else > >> extern int __clock_nanosleep_time64 (clockid_t clock_id, > >> int flags, const struct __timespec64 *req, > >> struct __timespec64 *rem); > >> libc_hidden_proto (__clock_nanosleep_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 ca40983f6c..875c4fe905 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,51 @@ > >> > >> /* 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); > > > > Ok, in this case either __vdso_clock_gettime/__NR_clock_gettime or > > __vdso_clock_gettime64/__NR_clock_gettime64 will be called. > > > >> +#else > >> +# if defined HAVE_CLOCK_GETTIME64_VSYSCALL > >> + int ret64 = INLINE_VSYSCALL (clock_gettime64, 2, clock_id, tp); > >> + if (ret64 == 0 || errno != ENOSYS) > >> + return ret64; > >> +# endif > > This should be: > > > > #if defined __NR_clock_gettime64 > > int ret64 = INLINE_VSYSCALL (clock_gettime64, ...) > > [...] > > > > And before sysdep-vdso.h it should be. > > > > #if defined HAVE_CLOCK_GETTIME_VSYSCALL || defined HAVE_CLOCK_GETTIME64_VSYSCALL > > # define HAVE_SYSCALL > > #endif > > > > If !HAVE_SYSCALL the INLINE_VSYSCALL is defined as INLINE_SYCALL. > > It means that if an architecture does provide __NR_clock_gettime64 > > but not provide HAVE_CLOCK_GETTIME64_VSYSCALL, it will still use > > the syscall. This code only uses the syscall if the vDSO is still > > present. > > > > I hope I can get my vDSO refactor, which would simplify a bit this > > code. > > > >> + struct timespec tp32; > >> + int ret = INLINE_VSYSCALL (clock_gettime, 2, clock_id, &tp32); > >> + if (ret == 0) > >> + *tp = valid_timespec_to_timespec64 (tp32); > >> + return ret; > >> +#endif > >> +} > > > > Ok, old fallback to time32 vdso/syscall. > > > >> + > >> +#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) > >> + { > >> + 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); > >> > > > > Ok. > >
diff --git a/include/time.h b/include/time.h index d7800eb30f..c19c73ae09 100644 --- a/include/time.h +++ b/include/time.h @@ -211,11 +211,14 @@ extern double __difftime (time_t time1, time_t time0); #if __TIMESIZE == 64 # define __clock_nanosleep_time64 __clock_nanosleep +# define __clock_gettime64 __clock_gettime #else extern int __clock_nanosleep_time64 (clockid_t clock_id, int flags, const struct __timespec64 *req, struct __timespec64 *rem); libc_hidden_proto (__clock_nanosleep_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 ca40983f6c..875c4fe905 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,51 @@ /* 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 HAVE_CLOCK_GETTIME64_VSYSCALL + int ret64 = INLINE_VSYSCALL (clock_gettime64, 2, clock_id, tp); + if (ret64 == 0 || errno != ENOSYS) + return ret64; +# endif + struct timespec tp32; + int ret = INLINE_VSYSCALL (clock_gettime, 2, clock_id, &tp32); + if (ret == 0) + *tp = valid_timespec_to_timespec64 (tp32); + return ret; +#endif +} + +#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) + { + 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);