On my Ubuntu 15.04 (Linux Kernel 3.19.0-28-generic) I get the same value when requesting CLOCK_TAI and CLOCK_REALTIME with clock_gettime(). This is apparently an error because the difference between CLOCK_TAI and CLOCK_REALTIME should be the number of leap seconds plus the epoch difference considering this article about the RedHat OS.

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 concern (CLOCK_REALTIME is what applications hammer the most), in Linux we actually structure it as:

CLOCK_REALTIME: Initialized at boot from RTC  

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.

My references here and here

  • 1
    Excellent finding. Thank you very much. I asked the same question on stack overflow here stackoverflow.com/q/32652688/75517. If you copy past your answer there I'll give you the answer. Regarding the answer in your second reference, I disagree with Stulz. It's not the same. There is an error at the leap second. If TAI was used, the monotonic clock wouldn't be needed anymore. Converting REALTIME accurately to Gregorian time requires anyway to use the leap second table. – chmike Sep 19 '15 at 17:38

The answer was found inside the referred article. 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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.