diff --git a/sched/clock/clock_systime_ticks.c b/sched/clock/clock_systime_ticks.c index eaa9ef3c611..486adb2f3cc 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); - -# endif /* CONFIG_SYSTEM_TIME64 */ -#else /* CONFIG_SCHED_TICKLESS */ -# ifdef 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 + if (g_rtc_enabled) { - verify = g_system_ticks; - sample = g_system_ticks; + 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 timespec_to_tick(&ts); } - while ((sample & TIMER_MASK32) < (verify & TIMER_MASK32) || - (sample & ~TIMER_MASK32) != (verify & ~TIMER_MASK32)); + else +#endif + { + /* In tickless mode, all timing is controlled by platform-specific + * code. Let the platform timer do the work. + */ - return sample; +#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) -# else /* CONFIG_SYSTEM_TIME64 */ + clock_t sample; + clock_t verify; - /* Return the current system time */ + /* 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. + */ - return g_system_ticks; + do + { + verify = g_system_ticks; + sample = g_system_ticks; + } + while ((sample & TIMER_MASK32) < (verify & TIMER_MASK32) || + (sample & ~TIMER_MASK32) != (verify & ~TIMER_MASK32)); -# endif /* CONFIG_SYSTEM_TIME64 */ -#endif /* CONFIG_SCHED_TICKLESS */ + return sample; + +#else /* CONFIG_SYSTEM_TIME64 */ + + /* Return the current system time */ + + return g_system_ticks; + +#endif /* CONFIG_SYSTEM_TIME64 */ + } } diff --git a/sched/clock/clock_systime_timespec.c b/sched/clock/clock_systime_timespec.c index 272e1b3f1bf..567f18a55e0 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 }