Message ID | 20200125203830.27179-1-lukma@denx.de |
---|---|
State | New |
Headers | show |
Series | [v2] y2038: linux: Provide __timespec_get64 implementation | expand |
Dear All, > This patch provides new instance of Linux specific timespec_get.c > file placed in ./sysdeps/unix/sysv/linux/. > > When compared to this file version from ./time directory, it provides > __timespec_get64 explicit 64 bit function for getting 64 bit time in > the struct __timespec64 (for compilation using C11 standard). > Moreover, a 32 bit version - __timespec_get internally uses > __timespec_get64. > > The __timespec_get is now supposed to be used on systems still > supporting 32 bit time (__TIMESIZE != 64) - hence the necessary > conversion to 32 bit struct timespec. > > Internally the timespec_get uses __clock_gettime64. This patch is > necessary for having architectures with __WORDSIZE == 32 Y2038 safe. > > Build tests: > ./src/scripts/build-many-glibcs.py glibcs > > 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 > > Above tests were performed with Y2038 redirection applied as well as > without to test proper usage of both __timespec_get64 and > __timespec_get. > > --- > Changes for v2: > > - The conversion to support 64 bit time for timespec_get() has been > moved from ./time/timespec_get.c to > sysdeps/unix/sysv/linux/timespec_get.c (as suggested by Adhemerval) > to avoid the need to create __clock_gettime64() method for HURD (as > 64 bit time support for machines with __WORDSIZE=32 and __TIMESIZE=32 > is now developed solely for Linux). --- > include/time.h | 3 ++ > sysdeps/unix/sysv/linux/timespec_get.c | 59 > ++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) > create mode 100644 sysdeps/unix/sysv/linux/timespec_get.c > > diff --git a/include/time.h b/include/time.h > index 558923274a..047f431a1a 100644 > --- a/include/time.h > +++ b/include/time.h > @@ -254,6 +254,7 @@ extern double __difftime (time_t time1, time_t > time0); #if __TIMESIZE == 64 > # define __clock_nanosleep_time64 __clock_nanosleep > # define __clock_gettime64 __clock_gettime > +# define __timespec_get64 __timespec_get > #else > extern int __clock_nanosleep_time64 (clockid_t clock_id, > int flags, const struct > __timespec64 *req, @@ -261,6 +262,8 @@ extern int > __clock_nanosleep_time64 (clockid_t clock_id, libc_hidden_proto > (__clock_nanosleep_time64) extern int __clock_gettime64 (clockid_t > clock_id, struct __timespec64 *tp); libc_hidden_proto > (__clock_gettime64) +extern int __timespec_get64 (struct __timespec64 > *ts, int base); +libc_hidden_proto (__timespec_get64) > #endif > > /* Use in the clock_* functions. Size of the field representing the > diff --git a/sysdeps/unix/sysv/linux/timespec_get.c > b/sysdeps/unix/sysv/linux/timespec_get.c new file mode 100644 > index 0000000000..7e634f9dac > --- /dev/null > +++ b/sysdeps/unix/sysv/linux/timespec_get.c > @@ -0,0 +1,59 @@ > +/* timespec_get -- get system time - Linux version supporting 64 bit > time. > + Copyright (C) 2020 Free Software Foundation, Inc. > + This file is part of the GNU C Library. > + > + The GNU C Library is free software; you can redistribute it and/or > + modify it under the terms of the GNU Lesser General Public > + License as published by the Free Software Foundation; either > + version 2.1 of the License. > + > + The GNU C Library is distributed in the hope that it will be > useful, > + but WITHOUT ANY WARRANTY; without even the implied warranty of > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + Lesser General Public License for more details. > + > + You should have received a copy of the GNU Lesser General Public > + License along with the GNU C Library; if not, see > + <https://www.gnu.org/licenses/>. */ > + > +#include <time.h> > +#include <errno.h> > + > +/* Set TS to calendar time based in time base BASE. */ > +int > +__timespec_get64 (struct __timespec64 *ts, int base) > +{ > + if (base == TIME_UTC) > + { > + __clock_gettime64 (CLOCK_REALTIME, ts); > + return base; > + } > + return 0; > +} > + > +#if __TIMESIZE != 64 > +libc_hidden_def (__timespec_get64) > + > +int > +__timespec_get (struct timespec *ts, int base) > +{ > + int ret; > + struct __timespec64 tp64; > + > + ret = __timespec_get64 (&tp64, base); > + > + if (ret == TIME_UTC) > + { > + if (! in_time_t_range (tp64.tv_sec)) > + { > + __set_errno (EOVERFLOW); > + return 0; > + } > + > + *ts = valid_timespec64_to_timespec (tp64); > + } > + > + return ret; > +} > +#endif > +strong_alias (__timespec_get, timespec_get); Gentle ping for review / ACK of this 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
On 25/01/2020 17:38, Lukasz Majewski wrote: > This patch provides new instance of Linux specific timespec_get.c file placed > in ./sysdeps/unix/sysv/linux/. > > When compared to this file version from ./time directory, it provides > __timespec_get64 explicit 64 bit function for getting 64 bit time in the > struct __timespec64 (for compilation using C11 standard). > Moreover, a 32 bit version - __timespec_get internally uses > __timespec_get64. > > The __timespec_get is now supposed to be used on systems still supporting 32 > bit time (__TIMESIZE != 64) - hence the necessary conversion to 32 bit struct > timespec. > > Internally the timespec_get uses __clock_gettime64. This patch is necessary > for having architectures with __WORDSIZE == 32 Y2038 safe. > > Build tests: > ./src/scripts/build-many-glibcs.py glibcs > > 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 > > Above tests were performed with Y2038 redirection applied as well as without > to test proper usage of both __timespec_get64 and __timespec_get. LGTM, thanks. Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org> > > --- > Changes for v2: > > - The conversion to support 64 bit time for timespec_get() has been moved > from ./time/timespec_get.c to sysdeps/unix/sysv/linux/timespec_get.c > (as suggested by Adhemerval) to avoid the need to create __clock_gettime64() > method for HURD (as 64 bit time support for machines with __WORDSIZE=32 > and __TIMESIZE=32 is now developed solely for Linux). > --- > include/time.h | 3 ++ > sysdeps/unix/sysv/linux/timespec_get.c | 59 ++++++++++++++++++++++++++ > 2 files changed, 62 insertions(+) > create mode 100644 sysdeps/unix/sysv/linux/timespec_get.c > > diff --git a/include/time.h b/include/time.h > index 558923274a..047f431a1a 100644 > --- a/include/time.h > +++ b/include/time.h > @@ -254,6 +254,7 @@ extern double __difftime (time_t time1, time_t time0); > #if __TIMESIZE == 64 > # define __clock_nanosleep_time64 __clock_nanosleep > # define __clock_gettime64 __clock_gettime > +# define __timespec_get64 __timespec_get > #else > extern int __clock_nanosleep_time64 (clockid_t clock_id, > int flags, const struct __timespec64 *req, Ok. > @@ -261,6 +262,8 @@ extern int __clock_nanosleep_time64 (clockid_t clock_id, > libc_hidden_proto (__clock_nanosleep_time64) > extern int __clock_gettime64 (clockid_t clock_id, struct __timespec64 *tp); > libc_hidden_proto (__clock_gettime64) > +extern int __timespec_get64 (struct __timespec64 *ts, int base); > +libc_hidden_proto (__timespec_get64) > #endif > > /* Use in the clock_* functions. Size of the field representing the Ok. > diff --git a/sysdeps/unix/sysv/linux/timespec_get.c b/sysdeps/unix/sysv/linux/timespec_get.c > new file mode 100644 > index 0000000000..7e634f9dac > --- /dev/null > +++ b/sysdeps/unix/sysv/linux/timespec_get.c > @@ -0,0 +1,59 @@ > +/* timespec_get -- get system time - Linux version supporting 64 bit time. > + Copyright (C) 2020 Free Software Foundation, Inc. > + This file is part of the GNU C Library. > + > + The GNU C Library is free software; you can redistribute it and/or > + modify it under the terms of the GNU Lesser General Public > + License as published by the Free Software Foundation; either > + version 2.1 of the License. > + > + The GNU C Library is distributed in the hope that it will be useful, > + but WITHOUT ANY WARRANTY; without even the implied warranty of > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + Lesser General Public License for more details. > + > + You should have received a copy of the GNU Lesser General Public > + License along with the GNU C Library; if not, see > + <https://www.gnu.org/licenses/>. */ > + > +#include <time.h> > +#include <errno.h> > + > +/* Set TS to calendar time based in time base BASE. */ > +int > +__timespec_get64 (struct __timespec64 *ts, int base) > +{ > + if (base == TIME_UTC) > + { > + __clock_gettime64 (CLOCK_REALTIME, ts); > + return base; > + } > + return 0; > +} Ok. > + > +#if __TIMESIZE != 64 > +libc_hidden_def (__timespec_get64) > + > +int > +__timespec_get (struct timespec *ts, int base) > +{ > + int ret; > + struct __timespec64 tp64; > + > + ret = __timespec_get64 (&tp64, base); > + > + if (ret == TIME_UTC) > + { > + if (! in_time_t_range (tp64.tv_sec)) > + { > + __set_errno (EOVERFLOW); > + return 0; > + } > + > + *ts = valid_timespec64_to_timespec (tp64); > + } > + > + return ret; > +} > +#endif > +strong_alias (__timespec_get, timespec_get); > Ok.
diff --git a/include/time.h b/include/time.h index 558923274a..047f431a1a 100644 --- a/include/time.h +++ b/include/time.h @@ -254,6 +254,7 @@ extern double __difftime (time_t time1, time_t time0); #if __TIMESIZE == 64 # define __clock_nanosleep_time64 __clock_nanosleep # define __clock_gettime64 __clock_gettime +# define __timespec_get64 __timespec_get #else extern int __clock_nanosleep_time64 (clockid_t clock_id, int flags, const struct __timespec64 *req, @@ -261,6 +262,8 @@ extern int __clock_nanosleep_time64 (clockid_t clock_id, libc_hidden_proto (__clock_nanosleep_time64) extern int __clock_gettime64 (clockid_t clock_id, struct __timespec64 *tp); libc_hidden_proto (__clock_gettime64) +extern int __timespec_get64 (struct __timespec64 *ts, int base); +libc_hidden_proto (__timespec_get64) #endif /* Use in the clock_* functions. Size of the field representing the diff --git a/sysdeps/unix/sysv/linux/timespec_get.c b/sysdeps/unix/sysv/linux/timespec_get.c new file mode 100644 index 0000000000..7e634f9dac --- /dev/null +++ b/sysdeps/unix/sysv/linux/timespec_get.c @@ -0,0 +1,59 @@ +/* timespec_get -- get system time - Linux version supporting 64 bit time. + Copyright (C) 2020 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <https://www.gnu.org/licenses/>. */ + +#include <time.h> +#include <errno.h> + +/* Set TS to calendar time based in time base BASE. */ +int +__timespec_get64 (struct __timespec64 *ts, int base) +{ + if (base == TIME_UTC) + { + __clock_gettime64 (CLOCK_REALTIME, ts); + return base; + } + return 0; +} + +#if __TIMESIZE != 64 +libc_hidden_def (__timespec_get64) + +int +__timespec_get (struct timespec *ts, int base) +{ + int ret; + struct __timespec64 tp64; + + ret = __timespec_get64 (&tp64, base); + + if (ret == TIME_UTC) + { + if (! in_time_t_range (tp64.tv_sec)) + { + __set_errno (EOVERFLOW); + return 0; + } + + *ts = valid_timespec64_to_timespec (tp64); + } + + return ret; +} +#endif +strong_alias (__timespec_get, timespec_get);