Re: Large timecounter delta handling

From: Konstantin Belousov <kostikbel_at_gmail.com>
Date: Mon, 11 Oct 2021 08:58:24 UTC
On Mon, Oct 11, 2021 at 09:53:31AM +0200, Sebastian Huber wrote:
> Hello,
> 
> I synchronize currently the port of the FreeBSD timecounters to RTEMS. I
> have to write test cases for all code we use in RTEMS. In 2020 some code was
> added to fix integer overflow issues with large time deltas while getting
> the time from a timehand.
> 
> https://github.com/freebsd/freebsd-src/commit/6cf2362e2c7e9061611f93a48ec654a5b7451d6b#diff-8b8e2f8e41e6a847f14ab08c7d50454c20a4a135f2c2241d91687c0832c1d99e
> 
> If a time delta obtained by tc_delta(th) is greater than or equal to
> th->th_large_delta, then some extra calculation is carried out.
> 
> The th->th_large_delta is computed like this
> 
> 	scale = (uint64_t)1 << 63;
> 	scale += (th->th_adjustment / 1024) * 2199;
> 	scale /= th->th_counter->tc_frequency;
> 	th->th_scale = scale * 2;
> 	th->th_large_delta = MIN(((uint64_t)1 << 63) / scale, UINT_MAX);
> 
> If we ignore the th->th_adjustment (== 0), then we have ideally
> 
> scale = 2**64 / f
> th->th_large_delta = MIN( f / 2, UINT_MAX )
> 
> Does this mean that we only need the large delta processing if a timehand
> was not updated for about 0.5s?

I do not understand your question.  We need large_delta to handle overflows
in bintime_off().  tc_large_delta is computed in advance during windup to
avoid this calculation in time reading code.

Your question is more like "under which conditions we switch to use
tc_large_delta path in bintime_off()?"  Then it is mostly right, that
long intervals between tc_windup() calls would trigger it, and it seems
that indeed it is around 0.5 sec.

If you have a controlled environment, just skip some tc_windup() calls
to see.