This is an automated email from the ASF dual-hosted git repository.

acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx-apps.git

commit f4d71b6074ba5cd0cf042c72066ae4a87d649347
Author: Justin Hammond <[email protected]>
AuthorDate: Sat Aug 15 17:31:49 2026 +0800

    testing/libc/arch_libc: Time against a clock that runs.
    
    Every measurement repeats until a stated interval has passed, so a clock
    that reads the same value twice does not slow the benchmark down, it stops
    it returning at all.
    
    CLOCK_MONOTONIC does not advance on every target.  On qemu-intel64 it
    reports success and stays at zero, while CLOCK_REALTIME advances normally,
    and the benchmark spins in its first measurement with no output after the
    heading.
    
    Sample each candidate twice around a busy wait and take the first one whose
    reading changes.  Where none does, say so and skip the timing rather than
    hang.
    
    Assisted-by: Claude:claude-opus-5
    Signed-off-by: Justin Hammond <[email protected]>
---
 testing/libc/arch_libc/arch_libc_bench.c | 56 +++++++++++++++++++++++++++++++-
 1 file changed, 55 insertions(+), 1 deletion(-)

diff --git a/testing/libc/arch_libc/arch_libc_bench.c 
b/testing/libc/arch_libc/arch_libc_bench.c
index af5bb4dd9..c24118e1a 100644
--- a/testing/libc/arch_libc/arch_libc_bench.c
+++ b/testing/libc/arch_libc/arch_libc_bench.c
@@ -116,6 +116,7 @@ struct bench_op_s
 static FAR char *g_src;
 static FAR char *g_dst;
 static volatile unsigned long g_sink;
+static clockid_t g_clock = CLOCK_MONOTONIC;
 
 static const struct bench_op_s g_ops[] =
 {
@@ -182,10 +183,57 @@ static double bench_now(void)
 {
   struct timespec t;
 
-  clock_gettime(CLOCK_MONOTONIC, &t);
+  clock_gettime(g_clock, &t);
   return t.tv_sec + t.tv_nsec / 1e9;
 }
 
+/****************************************************************************
+ * Name: bench_pick_clock
+ *
+ * Description:
+ *   Settle on a clock that runs.  Every measurement below repeats until a
+ *   stated interval has passed, so a clock that reads the same value twice
+ *   would spin forever rather than report anything.  CLOCK_MONOTONIC is
+ *   preferred and does not advance on every target.
+ *
+ ****************************************************************************/
+
+static bool bench_pick_clock(void)
+{
+  static const clockid_t tries[] =
+  {
+    CLOCK_MONOTONIC, CLOCK_REALTIME
+  };
+
+  struct timespec a;
+  struct timespec b;
+  volatile int i;
+  size_t k;
+
+  for (k = 0; k < sizeof(tries) / sizeof(tries[0]); k++)
+    {
+      if (clock_gettime(tries[k], &a) < 0)
+        {
+          continue;
+        }
+
+      for (i = 0; i < 1000000; i++);
+
+      if (clock_gettime(tries[k], &b) < 0)
+        {
+          continue;
+        }
+
+      if (b.tv_sec != a.tv_sec || b.tv_nsec != a.tv_nsec)
+        {
+          g_clock = tries[k];
+          return true;
+        }
+    }
+
+  return false;
+}
+
 /****************************************************************************
  * Name: bench_seen_src
  *
@@ -385,6 +433,12 @@ int arch_libc_bench(void)
   size_t si;
   size_t ai;
 
+  if (!bench_pick_clock())
+    {
+      printf("arch_libc bench: no clock advances, cannot time anything\n");
+      return 1;
+    }
+
   g_src = malloc(BENCH_BUF);
   g_dst = malloc(BENCH_BUF);
   if (g_src == NULL || g_dst == NULL)

Reply via email to