On 07/01/2015 08:40, Paul Jarc wrote:
> I'm finally digging into a long-standing bug exhibited by runwhen
> (rw-match computes a timestamp 10 seconds too early), and I think the
> problem is in skalibs. tai_from_sysclock() adds 10 seconds depending
> on whether skalibs is configured with --enable-tai-clock. But
> tai_from_timeval doesn't, so they're inconsistent.
Actually, they're not; what is inconsistent is the naming. I probably
should have paid more attention to that, and may change it in the
future (yay API changes).
In "tai_from_sysclock", "tai" means: what will be stored in that
structure is a real, absolute TAI time. It's the TAI time corresponding
to the sysclock time. It's the same whether the clock is TAI-10 (in
which case you simply add 10 seconds) or whether it's UTC (in which case
you add 10 seconds plus the leap seconds). The tai_from_utc function,
which tai_from_sysclock resolves to when --enable-tai-clock is not given,
does add the 10 seconds too.
In "tai_from_timeval", "tai" means: store the same information in a
tai_t. It's a simple format conversion function - the struct timeval
could hold anything, a TAI-10 time, a UTC time, or something else, as
long as it's absolute. No time conversion operation is done here.
Yes, it's confusing. My bad.
> actually both wrong: the correct behavior for both should be to
> unconditionally add 10 seconds, and conditionally add leap seconds
> depending on --enable-tai-clock
That is what happens for tai_from_sysclock.
That is not what happens for tai_from_timeval, on purpose.
I suspect your problem in runwhen is that you are calling
tai_from_timeval(), or any other simple format conversion function,
while expecting a time conversion function.
You should always be using tain_now() to get the current time,
it will give you TAI no matter what your setup is. You should not
generally use tai_from_timeval() yourself.
> With a POSIX clock and no --enable-tai-clock, we need to add the
> appropriate amount of leap seconds or else the tai_t values we
> generate will differ from those simultaneously generated on a system
> using TAI-10 and --enable-tai-clock.
Yes, that is exactly what happens. When you call tai_sysclock(), the
TAI value you get is the same whether your clock is set to TAI-10 and
you have --enable-tai-clock, or your clock is set to UTC and you have
--disable-tai-clock.
The tain_sysclock() function, which is what tain_now() normally
calls (unless you asked --enable-monotonic), goes like this:
* sysclock_get() gets the time from the system clock, no matter its
format, into a tain_t. tain_from_timespec or tain_from_timeval are
just struct conversions, they're time-agnostic.
* tai_from_sysclock() assumes that the time it is given comes directly
from the system clock in its native format, and converts it into TAI:
- by adding 10 seconds if the system clock is TAI-10
- by calling tai_from_utc() otherwise
+ tai_from_utc() adds 10 seconds plus the leap seconds
so what you get in the end is always TAI.
> (This means that on a POSIX
> system, converting future times to TAI will give you wrong results
> after the time when the as-yet-unknown next leap second will be
> added.)
That's unfortunately unavoidable, and a limitation of POSIX.
Time arithmetic can only be performed correctly with linear time,
which TAI is and UTC is not. That is why skalibs uses TAI for all
its time computations. But with a UTC clock, you do need an accurate
leap second table to make the correct conversions, and if you're
computing past the last known leap second, tough luck.
The alternative with a UTC clock, which basically every non-skalibs-
based system uses, is to perform time arithmetic with UTC, which
gives you wrong results whether far into the future or not, and they
simply don't care because "it would be too hard". Thanks POSIX.
--
Laurent
Received on Wed Jan 07 2015 - 11:04:45 UTC