[PATCH v3 2/4] time: Implement newly add timebase defines for c23 timespec_get and timespec_getres

Yonggang Luo luoyonggang@gmail.com
Wed Jun 21 09:43:24 GMT 2023


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(-)

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
+  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,
diff --git a/include/time.h b/include/time.h
index f599eeed4e..19db10ffc6 100644
--- a/include/time.h
+++ b/include/time.h
@@ -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)
diff --git a/sysdeps/unix/sysv/linux/timespec_get.c b/sysdeps/unix/sysv/linux/timespec_get.c
index 3c852be99b..40d3ae3f0d 100644
--- a/sysdeps/unix/sysv/linux/timespec_get.c
+++ b/sysdeps/unix/sysv/linux/timespec_get.c
@@ -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;
 }
diff --git a/sysdeps/unix/sysv/linux/timespec_getres.c b/sysdeps/unix/sysv/linux/timespec_getres.c
index 7e61d78a77..e73c73cf74 100644
--- a/sysdeps/unix/sysv/linux/timespec_getres.c
+++ b/sysdeps/unix/sysv/linux/timespec_getres.c
@@ -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;
diff --git a/time/time.h b/time/time.h
index 368f4dc588..76ab4eb322 100644
--- a/time/time.h
+++ b/time/time.h
@@ -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
diff --git a/time/timespec_get.c b/time/timespec_get.c
index 9b1d4f22ed..93aa442ca0 100644
--- a/time/timespec_get.c
+++ b/time/timespec_get.c
@@ -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;
 }
diff --git a/time/timespec_getres.c b/time/timespec_getres.c
index fd64dc7a47..3cc7a4b3bb 100644
--- a/time/timespec_getres.c
+++ b/time/timespec_getres.c
@@ -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;
 }
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
@@ -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;
 }
 
diff --git a/time/tst-timespec_getres.c b/time/tst-timespec_getres.c
index b400a70138..55a6dd21e8 100644
--- a/time/tst-timespec_getres.c
+++ b/time/tst-timespec_getres.c
@@ -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;
 }
 
-- 
2.39.0.windows.1



More information about the Libc-alpha mailing list