From: firk <f...@cantconnect.ru>

(which is used to calculate cputime from cpu ticks) has some imprecision and,
worse, huge timestep (about 20 minutes on 4GHz CPU) near 53.4 days of elapsed
time.

kern_time.c/cputick2timespec() (it is used for clock_gettime() for
querying process or thread consumed cpu time) Uses cputick2usec()
and then needlessly converting usec to nsec, obviously losing
precision even with fixed cputick2usec().

kern_time.c/kern_clock_getres() uses some weird (anyway wrong)
formula for getting cputick resolution.

PR:             262215
Reviewed by:    gnn
Differential Revision:  https://reviews.freebsd.org/D34558
---
 cpukit/score/src/kern_tc.c | 12 +++---------
 1 file changed, 3 insertions(+), 9 deletions(-)

diff --git a/cpukit/score/src/kern_tc.c b/cpukit/score/src/kern_tc.c
index 643026a1c8..8e43169934 100644
--- a/cpukit/score/src/kern_tc.c
+++ b/cpukit/score/src/kern_tc.c
@@ -2617,20 +2617,14 @@ cpu_tickrate(void)
  * years) and in 64 bits at 4 GHz (146 years), but if we do a multiply
  * before divide conversion (to retain precision) we find that the
  * margin shrinks to 1.5 hours (one millionth of 146y).
- * With a three prong approach we never lose significant bits, no
- * matter what the cputick rate and length of timeinterval is.
  */
 
 uint64_t
 cputick2usec(uint64_t tick)
 {
-
-       if (tick > 18446744073709551LL)         /* floor(2^64 / 1000) */
-               return (tick / (cpu_tickrate() / 1000000LL));
-       else if (tick > 18446744073709LL)       /* floor(2^64 / 1000000) */
-               return ((tick * 1000LL) / (cpu_tickrate() / 1000LL));
-       else
-               return ((tick * 1000000LL) / cpu_tickrate());
+       uint64_t tr;
+       tr = cpu_tickrate();
+       return ((tick / tr) * 1000000ULL) + ((tick % tr) * 1000000ULL) / tr;
 }
 
 cpu_tick_f     *cpu_ticks = tc_cpu_ticks;
-- 
2.35.3

_______________________________________________
devel mailing list
devel@rtems.org
http://lists.rtems.org/mailman/listinfo/devel

Reply via email to