Since Linux kernel version 3.10, the function clock_gettime()
now accept CLOCK_TAI
.
I didn't manage to find a detailed description of this clock. What is its epoch ?
EDIT 1: Just compared the output of CLOCK_REALTIME and CLOCK_TAI on my Linux 3.19 OS and it returns the exact same value (1442582497) !? Is CLOCK_REALTIME decremented at leap seconds ?
EDIT 2: According to this article, the difference between CLOCK_TAI and the (badly named) CLOCK_REALTIME should be the number of leap seconds.
EDIT 3: The reason CLOCK_TAI
and CLOCK_REALTIME
are the same time is explained in the article referenced in Edit 2. The emphasis is by me.
For applications where it would be possible to work with TAI time instead of UTC, the kernel provides a special CLOCK_TAI clock which does include leap seconds and doesn’t need to be corrected after leap second, avoiding the problem with backward jump in the time entirely. It’s implemented as a clock running at a fixed integral offset to CLOCK_REALTIME, which is atomically incremented by 1 when the CLOCK_REALTIME clock is stepped back on leap second. It was introduced in the Linux kernel version 3.10 and is available with the kernels shipped in RHEL7. Please note that the offset from CLOCK_REALTIME is initialized on boot to zero and neither ntpd nor chronyd set it by default to the correct value (currently 35). Switching to CLOCK_TAI in applications would of course require modifications to the code and possibly also all protocols that use the Unix representation of time.
Edit 4 : This answer obtained on Ask Ubuntu clarifies everything.
CLOCK_TAI is basically designed as CLOCK_REALTIME(UTC) + tai_offset.
So the usec/nsec portion of a timeval/timespec should be identical.
CLOCK_MONOTONIC: Zeroed at boot.
CLOCK_TAI = CLOCK_MONOTONIC + tai_mon_offset
CLOCK_REALTIME(UTC) = CLOCK_TAI - tai_utc_offset
But due to performance concerns (CLOCK_REALTIME is what applications hammer the most), in Linux we actually structure it as:
CLOCK_REALTIME: Initialized at boot from RTC
CLOCK_MONOTONIC: CLOCK_REALTIME - wall_to_monotonic
CLOCK_TAI: CLOCK_REALTIME + tai_offset
So CLOCK_REALTIME and CLOCK_TAI return the same because the kernel parameter tai_offset is zero.
Check by using adjtimex(timex tmx)
and read the value. I think that ntpd
will set it if it is new enough (>4.2.6
) and has a leap second file. It may also be able to get it from upstream servers but I haven't been able to verify. The call adjtimex()
can set tai_offset
manually when run as root.