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

Message ID 20230621094324.1072-2-luoyonggang@gmail.com
State New
Headers
Series [v3,1/4] clang-format: Do not usage tab to indent code |

Commit Message

Yonggang Luo June 21, 2023, 9:43 a.m. UTC
  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

Joseph Myers June 21, 2023, 12:15 p.m. UTC | #1
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.
  

Patch

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;
 }