[v3,2/4] time: Implement newly add timebase defines for c23 timespec_get and timespec_getres
Commit Message
These are implemented https://gustedt.gitlabpages.inria.fr/c23-library/#time_monotonic-time_active-time_thread_active
with:
# define TIME_MONOTONIC 2
# define TIME_ACTIVE 3
# define TIME_THREAD_ACTIVE 4
# define TIME_MONOTONIC_RAW 5
# define TIME_UTC_COARSE 6
# define TIME_MONOTONIC_COARSE 7
# define TIME_BOOTTIME 8
# define TIME_UTC_ALARM 9
# define TIME_BOOTTIME_ALARM 10
# define TIME_SGI_CYCLE 11
# define TIME_TAI 12
And a private function named clock_from_timebase is added, this is used to
map c11 timebase to posix clockid_t in a common place
Maybe it's can be prompted into a POSIX function
in future to resolve issue that from
https://www.openwall.com/lists/libc-coord/2023/04/25/1
Signed-off-by: Yonggang Luo <luoyonggang@gmail.com>
---
NEWS | 13 +++++
include/time.h | 60 +++++++++++++++++++++++
sysdeps/unix/sysv/linux/timespec_get.c | 7 +--
sysdeps/unix/sysv/linux/timespec_getres.c | 5 +-
time/time.h | 15 +++++-
time/timespec_get.c | 7 +--
time/timespec_getres.c | 7 +--
time/tst-timespec_get.c | 7 +++
time/tst-timespec_getres.c | 17 +++++++
9 files changed, 126 insertions(+), 12 deletions(-)
Comments
On Wed, 21 Jun 2023, Yonggang Luo via Libc-alpha wrote:
> diff --git a/NEWS b/NEWS
> index 709ee40e50..c4f53a2fb9 100644
> --- a/NEWS
> +++ b/NEWS
> @@ -9,6 +9,19 @@ Version 2.38
>
> Major new features:
>
> +* C23 timebase defines are supported, thse are:
> + TIME_MONOTONI
> + TIME_ACTIVE
> + TIME_THREAD_ACTIVE
(a) Only these three are in C2x; the description above is a
misrepresentation of the nature of the other macros you add. Please send
a patch that adds *only* the three new C2x time bases, which should be
uncontroversial, not any that are not in C2x, which are definitely
controversial - make it a standalone patch, not part of a patch series
adding any other features. Please make sure you've run the glibc
testsuite with that patch, without any regressions, before posting it, and
say explicitly in the patch posting what configuration you ran the
testsuite for.
(b) "thse" should be "these".
(c) "TIME_MONOTONI" should be "TIME_MONOTONIC".
(d) Please refer to C2X not C23 in all documentation in glibc unless and
until a conclusion is reached that C23 is the proper name despite the
standard not being finished until 2024.
> diff --git a/time/tst-timespec_get.c b/time/tst-timespec_get.c
> index d735160394..e5b86c0422 100644
> --- a/time/tst-timespec_get.c
> +++ b/time/tst-timespec_get.c
Please include tests for all three new C2x time bases added, not just
TIME_MONOTONIC.
@@ -9,6 +9,19 @@ Version 2.38
Major new features:
+* C23 timebase defines are supported, thse are:
+ TIME_MONOTONI
+ TIME_ACTIVE
+ TIME_THREAD_ACTIVE
+ TIME_MONOTONIC_RAW
+ TIME_UTC_COARSE
+ TIME_MONOTONIC_COARSE
+ TIME_BOOTTIME
+ TIME_UTC_ALARM
+ TIME_BOOTTIME_ALARM
+ TIME_SGI_CYCLE
+ TIME_TAI
+
* When C2X features are enabled and the base argument is 0 or 2, the
following functions support binary integers prefixed by 0b or 0B as
input: strtol, strtoll, strtoul, strtoull, strtol_l, strtoll_l,
@@ -361,6 +361,66 @@ in_time_t_range (__time64_t t)
return s == t;
}
+/* Helper that convert from c11 timebase to posix clockid_t,
+ when the mapping not exist, return -1 */
+static inline clockid_t
+clock_from_timebase (int timebase)
+{
+ clockid_t clockid = -1;
+ switch (timebase)
+ {
+ case TIME_UTC:
+ clockid = CLOCK_REALTIME;
+ break;
+ case TIME_MONOTONIC:
+ clockid = CLOCK_MONOTONIC;
+ break;
+ case TIME_ACTIVE:
+ clockid = CLOCK_PROCESS_CPUTIME_ID;
+ break;
+ case TIME_THREAD_ACTIVE:
+ clockid = CLOCK_THREAD_CPUTIME_ID;
+ break;
+ case TIME_MONOTONIC_RAW:
+ clockid = CLOCK_MONOTONIC_RAW;
+ break;
+ case TIME_UTC_COARSE:
+ clockid = CLOCK_REALTIME_COARSE;
+ break;
+ case TIME_MONOTONIC_COARSE:
+ clockid = CLOCK_MONOTONIC_COARSE;
+ break;
+# ifdef CLOCK_BOOTTIME
+ case TIME_BOOTTIME:
+ clockid = CLOCK_BOOTTIME;
+ break;
+# endif
+# ifdef CLOCK_REALTIME_ALARM
+ case TIME_UTC_ALARM:
+ clockid = CLOCK_REALTIME_ALARM;
+ break;
+# endif
+# ifdef CLOCK_BOOTTIME_ALARM
+ case TIME_BOOTTIME_ALARM:
+ clockid = CLOCK_BOOTTIME_ALARM;
+ break;
+# endif
+# ifdef CLOCK_SGI_CYCLE
+ case TIME_SGI_CYCLE:
+ clockid = CLOCK_SGI_CYCLE;
+ break;
+# endif
+# ifdef CLOCK_TAI
+ case TIME_TAI:
+ clockid = CLOCK_TAI;
+ break;
+# endif
+ default:
+ break;
+ }
+ return clockid;
+}
+
/* Convert a known valid struct timeval into a struct __timespec64. */
static inline struct __timespec64
valid_timeval_to_timespec64 (const struct timeval tv)
@@ -23,10 +23,11 @@
int
__timespec_get64 (struct __timespec64 *ts, int base)
{
- if (base == TIME_UTC)
+ clockid_t clockid = clock_from_timebase (base);
+ if (clockid >= 0)
{
- __clock_gettime64 (CLOCK_REALTIME, ts);
- return base;
+ if (__clock_gettime (clockid, ts) >= 0)
+ return base;
}
return 0;
}
@@ -22,9 +22,10 @@
int
__timespec_getres64 (struct __timespec64 *ts, int base)
{
- if (base == TIME_UTC)
+ clockid_t clockid = clock_from_timebase (base);
+ if (clockid >= 0)
{
- __clock_getres64 (CLOCK_REALTIME, ts);
+ __clock_getres64 (clockid, ts);
return base;
}
return 0;
@@ -62,7 +62,20 @@ typedef __pid_t pid_t;
#ifdef __USE_ISOC11
/* Time base values for timespec_get. */
-# define TIME_UTC 1
+# define TIME_UTC 1
+#endif
+#if __GLIBC_USE_ISOC2X
+# define TIME_MONOTONIC 2
+# define TIME_ACTIVE 3
+# define TIME_THREAD_ACTIVE 4
+# define TIME_MONOTONIC_RAW 5
+# define TIME_UTC_COARSE 6
+# define TIME_MONOTONIC_COARSE 7
+# define TIME_BOOTTIME 8
+# define TIME_UTC_ALARM 9
+# define TIME_BOOTTIME_ALARM 10
+# define TIME_SGI_CYCLE 11
+# define TIME_TAI 12
#endif
__BEGIN_DECLS
@@ -22,10 +22,11 @@
int
timespec_get (struct timespec *ts, int base)
{
- if (base == TIME_UTC)
+ clockid_t clockid = clock_from_timebase (base);
+ if (clockid >= 0)
{
- __clock_gettime (CLOCK_REALTIME, ts);
- return base;
+ if (__clock_gettime (clockid, ts) >= 0)
+ return base;
}
return 0;
}
@@ -23,10 +23,11 @@
int
timespec_getres (struct timespec *ts, int base)
{
- if (base == TIME_UTC)
+ clockid_t clockid = clock_from_timebase (base);
+ if (clockid >= 0)
{
- __clock_getres (CLOCK_REALTIME, ts);
- return base;
+ if (__clock_getres (clockid, ts) >= 0)
+ return base;
}
return 0;
}
@@ -34,6 +34,13 @@ do_test (void)
TEST_VERIFY (ts.tv_nsec < 1000000000);
}
+ {
+ struct timespec ts;
+ TEST_COMPARE (timespec_get (&ts, TIME_MONOTONIC), TIME_MONOTONIC);
+ TEST_VERIFY (ts.tv_nsec >= 0);
+ TEST_VERIFY (ts.tv_nsec < 1000000000);
+ }
+
return 0;
}
@@ -45,6 +45,23 @@ do_test (void)
TEST_COMPARE (ts.tv_nsec, cts.tv_nsec);
}
+ {
+ struct timespec ts;
+ TEST_COMPARE (timespec_getres (&ts, TIME_MONOTONIC), TIME_MONOTONIC);
+ /* Expect all supported systems to support TIME_MONOTONIC with
+ resolution better than one second. */
+ TEST_VERIFY (ts.tv_sec == 0);
+ TEST_VERIFY (ts.tv_nsec > 0);
+ TEST_VERIFY (ts.tv_nsec < 1000000000);
+ TEST_COMPARE (timespec_getres (NULL, TIME_MONOTONIC), TIME_MONOTONIC);
+ /* Expect the resolution to be the same as that reported for
+ CLOCK_MONOTONIC with clock_getres. */
+ struct timespec cts;
+ TEST_COMPARE (clock_getres (CLOCK_MONOTONIC, &cts), 0);
+ TEST_COMPARE (ts.tv_sec, cts.tv_sec);
+ TEST_COMPARE (ts.tv_nsec, cts.tv_nsec);
+ }
+
return 0;
}