Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 10 Nov 2021 11:30:14 +0200
From:      Andriy Gapon <avg@FreeBSD.org>
To:        Konstantin Belousov <kostikbel@gmail.com>
Cc:        FreeBSD Current <freebsd-current@freebsd.org>
Subject:   Re: thread on sleepqueue does not wake up after timeout
Message-ID:  <2c469dd8-ab15-b74e-c108-afc7b68901e0@FreeBSD.org>
In-Reply-To: <fc651014-4f9d-4bc8-5c3b-07014208104f@FreeBSD.org>
References:  <aff7b1e5-c380-9d86-d638-047e618894e6@FreeBSD.org> <20191022104434.GM73312@kib.kiev.ua> <3a67f9a9-31cf-5814-4a68-8bdd6063b21e@FreeBSD.org> <20191022131633.GN73312@kib.kiev.ua> <9c131a2a-cc94-4d93-1ba8-595c0151e366@FreeBSD.org> <32fe4f76-155b-8b99-5782-4daafd4219d5@FreeBSD.org> <YYpg8p7f5q9JNEjE@kib.kiev.ua> <fc651014-4f9d-4bc8-5c3b-07014208104f@FreeBSD.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On 09/11/2021 17:56, Andriy Gapon wrote:
> So, as I was saying, when the delta is large the calculations in tc_windup and 
> bintime_off give slightly different results and that can lead to a discontinuity 
> of the time when timehands are switched.

A quick follow-up.
I think that both tc_windup and bintime_off have fundamentally correct 
calculations but with different precision.  Both seem to produce values slightly 
greater than a "true" value where the bintime fractional delta would be 
calculated as tc_delta * 2^64 / tc_frequency.  That's because of how th_scale is 
calculated.

When the timecounter delta is greater than the frequency then the value in 
tc_windup is closer to the true value because it accounts for whole seconds 
precisely: a tc_frequency number of timecounter ticks is equal to one second. 
bintime_off, however, converts both whole seconds and fractions using th_scale. 
  So, its result is consistently greater when the delta is longer than a second.

E.g., in my environment: tc_frequency = 14318180, th_scale = 1288420532460.
For a delta of 14318180 (== tc_frequency) tc_windup calculates a one second 
advance, bt = { 1, 0 }.
bintime_off for the same delta will produce bt = { 1, 1093027638570944 }.
The difference is minuscule, just 59 ppm in relative terms.
But it's 59 microseconds of "jumping back in time".

I think that the precision of bintime_off is sufficient and its calculations are 
faster, so I think that it's better to use the same calculations in tc_windup as 
well.  Especially given that they are identical for sub-second deltas and longer 
deltas should be extremely rare.

I am working on patch to implement this.

-- 
Andriy Gapon



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?2c469dd8-ab15-b74e-c108-afc7b68901e0>