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 2021/07/02 10:02:49 UTC

[incubator-nuttx] 02/04: sim/up_oneshot.c: take host time as current

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

commit 36c1bba88cd97ea7bf32552f62caabd553b2e673
Author: ligd <li...@xiaomi.com>
AuthorDate: Fri Mar 26 22:56:00 2021 +0800

    sim/up_oneshot.c: take host time as current
    
    Change-Id: I34625f3d3f9557a103017124388dba6104aba7cc
    Signed-off-by: ligd <li...@xiaomi.com>
---
 arch/sim/src/sim/up_hosttime.c | 24 +++++++++++-------
 arch/sim/src/sim/up_oneshot.c  | 55 ++++++++++++++++++++++++++++--------------
 2 files changed, 52 insertions(+), 27 deletions(-)

diff --git a/arch/sim/src/sim/up_hosttime.c b/arch/sim/src/sim/up_hosttime.c
index 5b18b17..03c9ed7 100644
--- a/arch/sim/src/sim/up_hosttime.c
+++ b/arch/sim/src/sim/up_hosttime.c
@@ -40,10 +40,24 @@
 
 uint64_t host_gettime(bool rtc)
 {
+  static uint64_t start;
   struct timespec tp;
+  uint64_t current;
 
   clock_gettime(rtc ? CLOCK_REALTIME : CLOCK_MONOTONIC, &tp);
-  return 1000000000ull * tp.tv_sec + tp.tv_nsec;
+  current = 1000000000ull * tp.tv_sec + tp.tv_nsec;
+
+  if (rtc)
+    {
+      return current;
+    }
+
+  if (start == 0)
+    {
+      start = current;
+    }
+
+  return current - start;
 }
 
 /****************************************************************************
@@ -61,17 +75,9 @@ void host_sleep(uint64_t nsec)
 
 void host_sleepuntil(uint64_t nsec)
 {
-  static uint64_t base;
   uint64_t now;
 
   now = host_gettime(false);
-  if (base == 0)
-    {
-      base = now;
-    }
-
-  now -= base;
-
   if (nsec > now + 1000)
     {
       usleep((nsec - now) / 1000);
diff --git a/arch/sim/src/sim/up_oneshot.c b/arch/sim/src/sim/up_oneshot.c
index fa0610f..c0a8f2f 100644
--- a/arch/sim/src/sim/up_oneshot.c
+++ b/arch/sim/src/sim/up_oneshot.c
@@ -85,7 +85,6 @@ static int sim_current(FAR struct oneshot_lowerhalf_s *lower,
  * Private Data
  ****************************************************************************/
 
-static struct timespec g_current;
 static sq_queue_t g_oneshot_list;
 
 /* Lower half operations */
@@ -103,6 +102,27 @@ static const struct oneshot_operations_s g_oneshot_ops =
  ****************************************************************************/
 
 /****************************************************************************
+ * Name: sim_timer_current
+ *
+ * Description:
+ *   Get current time from host.
+ *
+ ****************************************************************************/
+
+static inline void sim_timer_current(FAR struct timespec *ts)
+{
+  uint64_t nsec;
+  time_t sec;
+
+  nsec  = host_gettime(false);
+  sec   = nsec / NSEC_PER_SEC;
+  nsec -= sec * NSEC_PER_SEC;
+
+  ts->tv_sec  = sec;
+  ts->tv_nsec = nsec;
+}
+
+/****************************************************************************
  * Name: sim_timer_update
  *
  * Description:
@@ -113,16 +133,8 @@ static const struct oneshot_operations_s g_oneshot_ops =
 
 static void sim_timer_update(void)
 {
-  static const struct timespec tick =
-  {
-    .tv_sec  = 0,
-    .tv_nsec = NSEC_PER_TICK,
-  };
-
   FAR sq_entry_t *entry;
 
-  clock_timespec_add(&g_current, &tick, &g_current);
-
   for (entry = sq_peek(&g_oneshot_list); entry; entry = sq_next(entry))
     {
       sim_process_tick(entry);
@@ -154,7 +166,10 @@ static void sim_process_tick(sq_entry_t *entry)
 
   if (priv->callback)
     {
-      if (clock_timespec_compare(&priv->alarm, &g_current) > 0)
+      struct timespec current;
+
+      sim_timer_current(&current);
+      if (clock_timespec_compare(&priv->alarm, &current) > 0)
         {
           return; /* Alarm doesn't expire yet */
         }
@@ -228,10 +243,12 @@ static int sim_start(FAR struct oneshot_lowerhalf_s *lower,
 {
   FAR struct sim_oneshot_lowerhalf_s *priv =
     (FAR struct sim_oneshot_lowerhalf_s *)lower;
+  struct timespec current;
 
   DEBUGASSERT(priv != NULL && callback != NULL && ts != NULL);
 
-  clock_timespec_add(&g_current, ts, &priv->alarm);
+  sim_timer_current(&current);
+  clock_timespec_add(&current, ts, &priv->alarm);
 
   priv->callback = callback;
   priv->arg      = arg;
@@ -268,10 +285,12 @@ static int sim_cancel(FAR struct oneshot_lowerhalf_s *lower,
 {
   FAR struct sim_oneshot_lowerhalf_s *priv =
     (FAR struct sim_oneshot_lowerhalf_s *)lower;
+  struct timespec current;
 
   DEBUGASSERT(priv != NULL && ts != NULL);
 
-  clock_timespec_subtract(&priv->alarm, &g_current, ts);
+  sim_timer_current(&current);
+  clock_timespec_subtract(&priv->alarm, &current, ts);
 
   priv->callback = NULL;
   priv->arg      = NULL;
@@ -303,7 +322,8 @@ static int sim_current(FAR struct oneshot_lowerhalf_s *lower,
 {
   DEBUGASSERT(ts != NULL);
 
-  *ts = g_current;
+  sim_timer_current(ts);
+
   return OK;
 }
 
@@ -417,15 +437,14 @@ void up_timer_initialize(void)
 
 void up_timer_update(void)
 {
-#ifdef CONFIG_SIM_WALLTIME_SLEEP
+  static uint64_t until;
 
   /* Wait a bit so that the timing is close to the correct rate. */
 
-  host_sleepuntil(g_current.tv_nsec +
-    (uint64_t)g_current.tv_sec * NSEC_PER_SEC);
-#endif
+  until += NSEC_PER_TICK;
+  host_sleepuntil(until);
 
-#ifndef CONFIG_SIM_WALLTIME_SIGNAL
+#ifdef CONFIG_SIM_WALLTIME_SLEEP
   sim_timer_update();
 #endif
 }