You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2022/11/01 13:54:26 UTC

[incubator-nuttx] branch master updated: clock: adjust clock function to support tick

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

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


The following commit(s) were added to refs/heads/master by this push:
     new 8512ca74b1 clock: adjust clock function to support tick
8512ca74b1 is described below

commit 8512ca74b10f250a5b49d594235e7a5ce7cb2a99
Author: zhangyuan21 <zh...@xiaomi.com>
AuthorDate: Mon Sep 26 10:11:16 2022 +0800

    clock: adjust clock function to support tick
    
    When CONFIG_SCHED_TICKLESS_TICK_ARGUMENT enabled, we can
    use up_timer_gettick to get ticks for better performance.
---
 sched/clock/clock_systime_ticks.c    | 115 ++++++++++++++++++-----------------
 sched/clock/clock_systime_timespec.c |  67 ++------------------
 2 files changed, 63 insertions(+), 119 deletions(-)

diff --git a/sched/clock/clock_systime_ticks.c b/sched/clock/clock_systime_ticks.c
index eaa9ef3c61..486adb2f3c 100644
--- a/sched/clock/clock_systime_ticks.c
+++ b/sched/clock/clock_systime_ticks.c
@@ -75,67 +75,70 @@
 
 clock_t clock_systime_ticks(void)
 {
-#ifdef CONFIG_SCHED_TICKLESS
-# ifdef CONFIG_SYSTEM_TIME64
+#ifdef CONFIG_RTC_HIRES
+  /* Do we have a high-resolution RTC that can provide us with the time? */
 
-  struct timespec ts;
-
-  /* Get the time from the platform specific hardware */
-
-  clock_systime_timespec(&ts);
-
-  /* Convert to a 64-bit value in microseconds, then in clock tick units */
-
-  return USEC2TICK(1000000 * (uint64_t)ts.tv_sec + ts.tv_nsec / 1000);
-
-# else /* CONFIG_SYSTEM_TIME64 */
-
-  struct timespec ts;
-  uint64_t tmp;
-
-  /* Get the time from the platform specific hardware */
-
-  clock_systime_timespec(&ts);
-
-  /* Convert to a 64- then a 32-bit value */
-
-  tmp = USEC2TICK(1000000 * (uint64_t)ts.tv_sec + ts.tv_nsec / 1000);
-  return (clock_t)(tmp & TIMER_MASK32);
+  if (g_rtc_enabled)
+    {
+      struct timespec ts;
 
-# endif /* CONFIG_SYSTEM_TIME64 */
-#else /* CONFIG_SCHED_TICKLESS */
-# ifdef CONFIG_SYSTEM_TIME64
+      /* Get the time from the platform specific hardware */
 
-  clock_t sample;
-  clock_t verify;
+      clock_systime_timespec(&ts);
 
-  /* 64-bit accesses are not atomic on most architectures.  The following
-   * loop samples the 64-bit timer twice and loops in the rare event that
-   * there was 32-bit rollover between samples.
-   *
-   * If there is no 32-bit rollover, then:
-   *
-   *  - The MS 32-bits of each sample will be the same, and
-   *  - The LS 32-bits of the second sample will be greater than or equal to
-   *    the LS 32-bits for the first sample.
-   */
+      /* Convert to a 64-bit value in microseconds,
+       * then in clock tick units.
+       */
 
-  do
+      return timespec_to_tick(&ts);
+    }
+  else
+#endif
     {
-      verify = g_system_ticks;
-      sample = g_system_ticks;
+      /* In tickless mode, all timing is controlled by platform-specific
+       * code.  Let the platform timer do the work.
+       */
+
+#if defined(CONFIG_SCHED_TICKLESS_TICK_ARGUMENT)
+      clock_t ticks;
+      up_timer_gettick(&ticks);
+      return ticks;
+#elif defined(CONFIG_SCHED_TICKLESS)
+      struct timespec ts;
+      up_timer_gettime(&ts);
+      return timespec_to_tick(&ts);
+#elif defined(CONFIG_SYSTEM_TIME64)
+
+      clock_t sample;
+      clock_t verify;
+
+      /* 64-bit accesses are not atomic on most architectures.  The following
+       * loop samples the 64-bit timer twice and loops in the rare event that
+       * there was 32-bit rollover between samples.
+       *
+       * If there is no 32-bit rollover, then:
+       *
+       *  - The MS 32-bits of each sample will be the same, and
+       *  - The LS 32-bits of the second sample will be greater than or equal
+       *    to the LS 32-bits for the first sample.
+       */
+
+      do
+        {
+          verify = g_system_ticks;
+          sample = g_system_ticks;
+        }
+      while ((sample &  TIMER_MASK32)  < (verify &  TIMER_MASK32) ||
+             (sample & ~TIMER_MASK32) != (verify & ~TIMER_MASK32));
+
+      return sample;
+
+#else /* CONFIG_SYSTEM_TIME64 */
+
+      /* Return the current system time */
+
+      return g_system_ticks;
+
+#endif /* CONFIG_SYSTEM_TIME64 */
     }
-  while ((sample &  TIMER_MASK32)  < (verify &  TIMER_MASK32) ||
-         (sample & ~TIMER_MASK32) != (verify & ~TIMER_MASK32));
-
-  return sample;
-
-# else /* CONFIG_SYSTEM_TIME64 */
-
-  /* Return the current system time */
-
-  return g_system_ticks;
-
-# endif /* CONFIG_SYSTEM_TIME64 */
-#endif /* CONFIG_SCHED_TICKLESS */
 }
diff --git a/sched/clock/clock_systime_timespec.c b/sched/clock/clock_systime_timespec.c
index 272e1b3f1b..567f18a55e 100644
--- a/sched/clock/clock_systime_timespec.c
+++ b/sched/clock/clock_systime_timespec.c
@@ -109,84 +109,25 @@ int clock_systime_timespec(FAR struct timespec *ts)
   else
 #endif
     {
-#if defined(CONFIG_SCHED_TICKLESS)
       /* In tickless mode, all timing is controlled by platform-specific
        * code.  Let the platform timer do the work.
        */
 
-#ifdef CONFIG_SCHED_TICKLESS_TICK_ARGUMENT
+#if defined(CONFIG_SCHED_TICKLESS_TICK_ARGUMENT)
       clock_t ticks;
       int ret;
 
       ret = up_timer_gettick(&ticks);
       timespec_from_tick(ts, ticks);
       return ret;
-#else
+#elif defined(CONFIG_SCHED_TICKLESS)
       return up_timer_gettime(ts);
-#endif
-
-#elif defined(CONFIG_HAVE_LONG_LONG) && (CONFIG_USEC_PER_TICK % 1000) != 0
+#else
       /* 64-bit microsecond calculations should improve our accuracy
        * when the clock period is in units of microseconds.
        */
 
-      uint64_t usecs;
-      uint64_t secs;
-      uint64_t nsecs;
-
-      /* Get the time since power-on in seconds and microseconds.
-       * NOTE that overflow is still possible if we use a 64-bit
-       * timer.
-       */
-
-      usecs = (uint64_t)TICK2USEC(clock_systime_ticks());
-      secs  = usecs / USEC_PER_SEC;
-
-      /* Return the elapsed time in seconds and nanoseconds */
-
-      nsecs = (usecs - (secs * USEC_PER_SEC)) * NSEC_PER_USEC;
-
-      ts->tv_sec  = (time_t)secs;
-      ts->tv_nsec = (long)nsecs;
-      return OK;
-
-#else
-      /* We know that the clock rate is in units of milliseconds
-       * show we should be able to do the calculations with less
-       * chance of overflow.
-       *
-       * 32-bit millisecond calculations should be just fine in
-       * most cases.  For a 32-bit system timer and a clock period
-       * of 10 milliseconds, the msecs value will overflow at about
-       * 49.7 days.
-       *
-       * So.. we will still use 64-bit calculations if we have them
-       * in order to avoid that limitation.
-       */
-
-#ifdef CONFIG_HAVE_LONG_LONG
-      uint64_t msecs;
-      uint64_t secs;
-      uint64_t nsecs;
-#define WIDE_CAST (uint64_t)
-#else
-      clock_t msecs;
-      clock_t secs;
-      clock_t nsecs;
-#define WIDE_CAST
-#endif
-
-      /* Get the time since power-on in seconds and milliseconds */
-
-      msecs = TICK2MSEC(WIDE_CAST clock_systime_ticks());
-      secs  = msecs / MSEC_PER_SEC;
-
-      /* Return the elapsed time in seconds and nanoseconds */
-
-      nsecs = (msecs - (secs * MSEC_PER_SEC)) * NSEC_PER_MSEC;
-
-      ts->tv_sec  = (time_t)secs;
-      ts->tv_nsec = (long)nsecs;
+      timespec_from_tick(ts, clock_systime_ticks());
       return OK;
 #endif
     }