kernel: Improve precision of ticks and ms conversions

The following 2 improvements are contained in this patch:

- When converting from ms to ticks, instead of using hardware cycles
  per tick, use hardware cycles per second. This ensures that the
  multiplication is done before the division, increasing precision.
- When converting from ticks to ms, instead of using cycles per tick
  and cycles per sec, use ticks per sec. This too increases the
  precision.

The concept is to make the dividend as large as possible compared to the
divisor in order to lose as little precision as possible.

Fixes #8898
Fixes #9459
Fixes #9466
Fixes #9468

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
Signed-off-by: Carles Cufi <carles.cufi@nordicsemi.no>
This commit is contained in:
Vinayak Kariappa Chettimada 2018-08-31 08:58:59 +02:00 committed by Anas Nashif
commit c7d2734455

View file

@ -1363,7 +1363,8 @@ static ALWAYS_INLINE s32_t _ms_to_ticks(s32_t ms)
/* use 64-bit math to keep precision */
return (s32_t)ceiling_fraction(
(s64_t)ms * sys_clock_hw_cycles_per_sec,
(s64_t)MSEC_PER_SEC * sys_clock_hw_cycles_per_tick);
((s64_t)MSEC_PER_SEC * sys_clock_hw_cycles_per_sec) /
sys_clock_ticks_per_sec);
#else
/* simple division keeps precision */
s32_t ms_per_tick = MSEC_PER_SEC / sys_clock_ticks_per_sec;
@ -1383,8 +1384,7 @@ static inline s64_t __ticks_to_ms(s64_t ticks)
#ifdef _NEED_PRECISE_TICK_MS_CONVERSION
/* use 64-bit math to keep precision */
return (u64_t)ticks * sys_clock_hw_cycles_per_tick * MSEC_PER_SEC /
sys_clock_hw_cycles_per_sec;
return (u64_t)ticks * MSEC_PER_SEC / sys_clock_ticks_per_sec;
#else
/* simple multiplication keeps precision */
u32_t ms_per_tick = MSEC_PER_SEC / sys_clock_ticks_per_sec;