Re: PSA: Clock drift and pkgin
Johnny Billquist <[email protected]>
| Newsgroups | gmane.os.netbsd.devel.kernel |
|---|---|
| Message-ID | <[email protected]> |
By the way, I should point out that adding 1 tick to the reload of the
interval timer in no way gets you away from the possibility that you'll
get two timer signals with almost 0 time between them.
Because the simple truth is that it is completely unknown when the
program will actually get the signal for the first timeout.
Basically, using a similar notation:
Time 0*T: timer_settime(.it_value = T, .it_interval = T), arms timer at 2*T
Time 2*T: timer expires, rearms timer at 4*T
Time 2*T + 1.9*T: process scheduled and signal delivered
Time 4*T: timer expires, rearms timer at 6*T
Time 4*T + 0.1*T: process scheduled and signal delivered
So even though we added one tick, you can still get two timer events in
much closer proximity than a single tick as far as the process is
concerned. So the current code actually does nothing to avoid the
situation, but prevents running a timer at the same frequency as the
system tick.
And we probably do need to talk about the timer expiration and rearming
as separate from signal deliver and process scheduling. Timer expiration
and rearming is happening fairly reliably always close to correct time.
However, signal delivery and scheduling can be way off. And from a
program point of view, that is what really matters in the end. If the
program really wants a minimum amount of time before the next timeout,
it needs to do the request for the next time event at the processing
point, not something kernel internal which happend very disconnected
from the process.
Johnny
On 2023-12-24 02:22, Johnny Billquist wrote:
> On 2023-12-23 23:05, Taylor R Campbell wrote:
>> The attached (untested) patch reverts to the old algorithm
>> specifically for the case of rearming a periodic timer, leaving the
>> new algorithm with +1 in place for all other uses.
>>
>> Now, it's unclear to me whether this is correct, because it can have
>> the following effect. Suppose ticks happen on intervals of time T.
>> Then, owing to unpredictable and uncontrollable scheduling delays, the
>> following sequence of events may happen:
>>
>> Time 0*T: timer_settime(.it_value = T, .it_interval = T), arms timer
>> at 1*T
>> Time 1*T + 0.9*T: timer expires, rearms timer at 2*T
>> Time 2*T + 0.1*T: timer expires, rearms timer at 3*T
>>
>> The duration between these consecutive expirations of the timer is
>> 0.2*T, even though we asked for an interval of T.
>>
>> Of course, the _average_ duration will be around T, but the _minimum_
>> duration is essentially zero. POSIX clearly forbids a _one-shot_
>> timer, which is scheduled to expire after time T, to actually expire
>> after only time 0.2*T. But the language in POSIX is unclear to me on
>> whether this is allowed for _periodic_ timers:
>
> I would argue that the first timeout should not happen with less than T
> time, so the rounding up of that one is correct. The rearming should be
> with T. The fact that the user level program might the events with a
> 0.2*T interval (could even be infinitely close to 0 actually) is an
> effect of how systems work. You can always have higher priority stuff
> going on, which delays the scheduling of a process for an unknown
> amount. Even in soft realtime systems, that is the case. Hard realtime
> is pretty tricky actually, and a lot of the time, people trying to do
> realtime don't understand the problems around this.
> Anyway, this, in the end, goes to the point of what the
> purpose/usecase/reason for the itimer is.
>
> I would like/prefer that they try to give that average interval. Because
> if not, then it have no difference to the process just doing the call in
> the timer signal handler itself, and the interval parameter becomes just
> a convenience to not have to do the call youself, and there is no way to
> get something that essentially gives a higher chance of getting the
> average rate to what you ask for.
> Which seems poorer than having the ability to have both the average, and
> a way of having a minimum interval.
>
> But when it comes to times and timeouts, POSIX have some serious flaws
> already, and POSIX is close to unusable for anything realtime related
> anyway. (Try to do a pthread_cond_timedwait() for a specific number of
> seconds, and consider a time change in between and you'll see the problem.)
>
> So it's questionable if POSIX is useful/helpful here anyway. But maybe
> (as Mouse suggested) we should add/have a second interface which
> actually provides what is useful, if POSIX insists on an always minimum
> interval interpretation.
>
> Johnny
>
--
Johnny Billquist || "I'm on a bus
|| on a psychedelic trip
email: [email protected] || Reading murder books
pdp is alive! || tryin' to stay hip" - B. Idol