From: Paul Eggert Date: Tue, 28 Dec 2021 19:39:17 +0000 (-0800) Subject: timespec_getres: new module X-Git-Tag: v1.0~2467 X-Git-Url: https://gitweb.git.savannah.gnu.org/gitweb/?a=commitdiff_plain;h=af4148ce0197502ce017418871da592bd7be5d91;p=gnulib.git timespec_getres: new module * lib/time.in.h (timespec_getres): New decl. * lib/timespec_getres.c, m4/timespec_getres.m4: * modules/timespec_getres, modules/timespec_getres-tests: * tests/test-timespec_getres.c: New files. * m4/time_h.m4 (gl_TIME_H_REQUIRE_DEFAULTS, gl_TIME_H_DEFAULTS): * modules/time (time.h): Support timespec_getres. --- diff --git a/ChangeLog b/ChangeLog index 8b25c542bf..79739541e4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,15 @@ 2021-12-28 Paul Eggert + timespec_getres: new module + * lib/time.in.h (timespec_getres): New decl. + * lib/timespec_getres.c, m4/timespec_getres.m4: + * modules/timespec_getres, modules/timespec_getres-tests: + * tests/test-timespec_getres.c: + New files. + * m4/time_h.m4 (gl_TIME_H_REQUIRE_DEFAULTS, gl_TIME_H_DEFAULTS): + * modules/time (time.h): + Support timespec_getres. + gettime-res: new module * lib/gettime-res.c, modules/gettime-res: New files. * lib/timespec.h (gettime_res): New decl. diff --git a/doc/glibc-functions/timespec_getres.texi b/doc/glibc-functions/timespec_getres.texi new file mode 100644 index 0000000000..45128ee191 --- /dev/null +++ b/doc/glibc-functions/timespec_getres.texi @@ -0,0 +1,16 @@ +@node timespec_getres +@subsection @code{timespec_getres} +@findex timespec_getres + +Gnulib module: timespec_get + +Portability problems fixed by Gnulib: +@itemize +@item +This function is missing on many platforms: +glibc 2.33, macOS 12, FreeBSD 13.0, NetBSD 9.2, OpenBSD 7.0, Minix 3.3.0, AIX 7.1, HP-UX 11.31, IRIX 6.5, Solaris 11.3, Cygwin 2.9, mingw, MSVC 14, Android 9.0. +@end itemize + +Portability problems not fixed by Gnulib: +@itemize +@end itemize diff --git a/doc/posix-functions/timespec_getres.texi b/doc/posix-functions/timespec_getres.texi index 4c6549b916..89d3e6f16f 100644 --- a/doc/posix-functions/timespec_getres.texi +++ b/doc/posix-functions/timespec_getres.texi @@ -4,15 +4,15 @@ ISO C2x specification:@* @url{http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2596.pdf} section 7.27.2.6 -Gnulib module: --- +Gnulib module: timespec_getres Portability problems fixed by Gnulib: @itemize +@item +This function is missing on some platforms: +glibc 2.33, macOS 12, FreeBSD 13.0, NetBSD 9.2, OpenBSD 7.0, Minix 3.3.0, AIX 7.1, HP-UX 11.31, IRIX 6.5, Solaris 11.3, Cygwin 2.9, mingw, MSVC 14, Android 9.0. @end itemize Portability problems not fixed by Gnulib: @itemize -@item -This function is missing on some platforms: -glibc 2.33, macOS 11.1, FreeBSD 13.0, NetBSD 9.0, OpenBSD 6.7, Minix 3.3.0, AIX 7.1, HP-UX 11.31, IRIX 6.5, Solaris 11.4, Cygwin 2.9, mingw, MSVC 14, Android 9.0. @end itemize diff --git a/lib/time.in.h b/lib/time.in.h index a73fe59cbb..383e9768ba 100644 --- a/lib/time.in.h +++ b/lib/time.in.h @@ -120,6 +120,17 @@ _GL_CXXALIAS_SYS (timespec_get, int, (struct timespec *ts, int base)); _GL_CXXALIASWARN (timespec_get); # endif +/* Set *TS to the current time resolution, and return BASE. + Upon failure, return 0. */ +# if @GNULIB_TIMESPEC_GETRES@ +# if ! @HAVE_TIMESPEC_GETRES@ +_GL_FUNCDECL_SYS (timespec_getres, int, (struct timespec *ts, int base) + _GL_ARG_NONNULL ((1))); +# endif +_GL_CXXALIAS_SYS (timespec_getres, int, (struct timespec *ts, int base)); +_GL_CXXALIASWARN (timespec_getres); +# endif + /* Sleep for at least RQTP seconds unless interrupted, If interrupted, return -1 and store the remaining time into RMTP. See . */ diff --git a/lib/timespec_getres.c b/lib/timespec_getres.c new file mode 100644 index 0000000000..6fad0ce2d0 --- /dev/null +++ b/lib/timespec_getres.c @@ -0,0 +1,40 @@ +/* Get resolution of a time base. + Copyright 2021 Free Software Foundation, Inc. + + This file 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 3 of the + License, or (at your option) any later version. + + This file 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 this program. If not, see . */ + +#include + +#include + +#include "timespec.h" + +/* Set TS to resolution of time base BASE. + Return BASE if successful, 0 otherwise. */ +int +timespec_getres (struct timespec *ts, int base) +{ + if (base == TIME_UTC) + { +#if defined CLOCK_REALTIME && HAVE_CLOCK_GETRES + clock_getres (CLOCK_REALTIME, ts); +#else + long int res = gettime_res (); + ts->tv_sec = res / TIMESPEC_HZ; + ts->tv_nsec = res % TIMESPEC_HZ; +#endif + return base; + } + return 0; +} diff --git a/m4/time_h.m4 b/m4/time_h.m4 index b57474b48b..9ba9462caf 100644 --- a/m4/time_h.m4 +++ b/m4/time_h.m4 @@ -2,7 +2,7 @@ # Copyright (C) 2000-2001, 2003-2007, 2009-2021 Free Software Foundation, Inc. -# serial 18 +# serial 19 # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -133,6 +133,7 @@ AC_DEFUN([gl_TIME_H_REQUIRE_DEFAULTS], gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRPTIME]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_TIMEGM]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_TIMESPEC_GET]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_TIMESPEC_GETRES]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_TIME_R]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_TIME_RZ]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_TZSET]) @@ -151,6 +152,7 @@ AC_DEFUN([gl_TIME_H_DEFAULTS], HAVE_STRPTIME=1; AC_SUBST([HAVE_STRPTIME]) HAVE_TIMEGM=1; AC_SUBST([HAVE_TIMEGM]) HAVE_TIMESPEC_GET=1; AC_SUBST([HAVE_TIMESPEC_GET]) + HAVE_TIMESPEC_GETRES=1; AC_SUBST([HAVE_TIMESPEC_GETRES]) dnl Even GNU libc does not have timezone_t yet. HAVE_TIMEZONE_T=0; AC_SUBST([HAVE_TIMEZONE_T]) dnl If another module says to replace or to not replace, do that. diff --git a/m4/timespec_getres.m4 b/m4/timespec_getres.m4 new file mode 100644 index 0000000000..8f42a45f53 --- /dev/null +++ b/m4/timespec_getres.m4 @@ -0,0 +1,18 @@ +# Test whether timespec_getres works. +dnl Copyright 2021 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_FUNC_TIMESPEC_GETRES], +[ + AC_REQUIRE([gl_TIME_H_DEFAULTS]) + + dnl Might be needed for the same reason timespec_get needs it. + AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) + + AC_CHECK_FUNCS_ONCE([timespec_getres]) + if test $ac_cv_func_timespec_getres != yes; then + HAVE_TIMESPEC_GETRES=0 + fi +]) diff --git a/modules/time b/modules/time index fe38a50485..ae8471bb9e 100644 --- a/modules/time +++ b/modules/time @@ -40,6 +40,7 @@ time.h: time.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $( -e 's/@''GNULIB_STRPTIME''@/$(GNULIB_STRPTIME)/g' \ -e 's/@''GNULIB_TIMEGM''@/$(GNULIB_TIMEGM)/g' \ -e 's/@''GNULIB_TIMESPEC_GET''@/$(GNULIB_TIMESPEC_GET)/g' \ + -e 's/@''GNULIB_TIMESPEC_GETRES''@/$(GNULIB_TIMESPEC_GETRES)/g' \ -e 's/@''GNULIB_TIME_R''@/$(GNULIB_TIME_R)/g' \ -e 's/@''GNULIB_TIME_RZ''@/$(GNULIB_TIME_RZ)/g' \ -e 's/@''GNULIB_TZSET''@/$(GNULIB_TZSET)/g' \ @@ -49,6 +50,7 @@ time.h: time.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $( -e 's|@''HAVE_STRPTIME''@|$(HAVE_STRPTIME)|g' \ -e 's|@''HAVE_TIMEGM''@|$(HAVE_TIMEGM)|g' \ -e 's|@''HAVE_TIMESPEC_GET''@|$(HAVE_TIMESPEC_GET)|g' \ + -e 's|@''HAVE_TIMESPEC_GETRES''@|$(HAVE_TIMESPEC_GETRES)|g' \ -e 's|@''HAVE_TIMEZONE_T''@|$(HAVE_TIMEZONE_T)|g' \ -e 's|@''REPLACE_CTIME''@|$(REPLACE_CTIME)|g' \ -e 's|@''REPLACE_GMTIME''@|$(REPLACE_GMTIME)|g' \ diff --git a/modules/timespec_getres b/modules/timespec_getres new file mode 100644 index 0000000000..f9672868e3 --- /dev/null +++ b/modules/timespec_getres @@ -0,0 +1,32 @@ +Description: +timespec_getres: return the timestamp resolution + +Files: +lib/timespec_getres.c +m4/timespec_getres.m4 + +Depends-on: +extensions +time +gettime-res [test $HAVE_TIMESPEC_GETRES = 0] + +configure.ac: +AC_REQUIRE([gl_FUNC_TIMESPEC_GETRES]) +if test $HAVE_TIMESPEC_GETRES = 0; then + AC_LIBOBJ([timespec_getres]) +fi +gl_TIME_MODULE_INDICATOR([timespec_getres]) + +Makefile.am: + +Include: + + +Link: +$(LIB_CLOCK_GETTIME) + +License: +LGPL + +Maintainer: +all diff --git a/modules/timespec_getres-tests b/modules/timespec_getres-tests new file mode 100644 index 0000000000..9bb83cc795 --- /dev/null +++ b/modules/timespec_getres-tests @@ -0,0 +1,13 @@ +Files: +tests/test-timespec_getres.c +tests/signature.h +tests/macros.h + +Depends-on: + +configure.ac: + +Makefile.am: +TESTS += test-timespec_getres +check_PROGRAMS += test-timespec_getres +test_timespec_getres_LDADD = $(LDADD) @LIB_CLOCK_GETTIME@ diff --git a/tests/test-timespec_getres.c b/tests/test-timespec_getres.c new file mode 100644 index 0000000000..8490369364 --- /dev/null +++ b/tests/test-timespec_getres.c @@ -0,0 +1,40 @@ +/* Test timespec_getres. + Copyright 2021 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* Written by Paul Eggert. */ + +#include + +#include + +#include "signature.h" +SIGNATURE_CHECK (timespec_getres, int, (struct timespec *ts, int base)); + +#include "macros.h" + +int +main (void) +{ + struct timespec ts; + ASSERT (timespec_getres (&ts, TIME_UTC) == TIME_UTC); + + /* No clock resolution should be worse than 1 s or better than 1 ns. */ + ASSERT (ts.tv_sec == 0 + ? 0 < ts.tv_nsec && ts.tv_nsec < 1000000000 + : ts.tv_sec == 1 && ts.tv_nsec == 0); + + return 0; +}