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
}