Linux FAQ for clock_gettime(CLOCK_REALTIME)

aix bsd hp-ux linux mac-osx solaris windows

Linux answers by John Stultz (johnstul _at_ us.ibm.com) on June 26, 2008.


> 1. Is clock_gettime(CLOCK_REALTIME) consistent across all processors/cores?
>    (Does arch matter?  e.g. ppc, arm, x86, amd64, sparc).

It *should* or it's considered buggy.

However, on x86/x86_64, it is possible to see unsynced or variable freq TSCs cause time inconsistencies. 2.4 kernels really had no protection against this, and early 2.6 kernels didn't do too well here either. As of 2.6.18 and up the logic for detecting this is better and we'll usually fall back to a safe clocksource.

ppc always has a synced timebase, so that shouldn't be an issue.

arm, i'm not so familiar with, but i assume they do the right thing (i've not seen many arm bugs on this issue).

> 2. Does clock_gettime(CLOCK_REALTIME) pick up the new time when a user
>    (e.g. root) changes the current time on their computer?

Yes. CLOCK_REALTIME is affected by settime()/settimeofday() calls and can also be frequency corrected by NTP via adjtimex(). CLOCK_MONOTONIC is not affected by settime()/settimeofday(), but is frequency adjusted by NTP via adjtimex().

In the future (I'm still trying to get the patch in) there will be a CLOCK_MONOTONIC_RAW that will not be modified at all, and will have a linear correlation with the hardware counters.

> 3. Does clock_gettime(CLOCK_REALTIME) pick up NTP changes?
> 4. Does clock_gettime(CLOCK_REALTIME) pick up NTP clock slew?

With Linux, NTP normally uses settimeofday() for large corrections (over half a second). The adjtimex() inteface allows for small clock frequency changes (slewing). This can be done in a few different ways, see the man page for adjtimex.

With pre-2.6.18 kernels, the slewing was done by adding a little or taking some time away each tick. This could cause small time inconsistencies at the tick boundary. With post 2.6.18 kernels, the frequency adjustment is made directly against the hardware frequency.

> 5. gettimeofday() returns usec.  Aside from that, what are the differences between
>    gettimeofday(), sys/time.h's nanotime(), and clock_gettime(CLOCK_REALTIME)?
>    Which would you recommend programmers use (for linux in particular, but
>    also when trying to write portable code)?

gettimeofday and clock_gettime(CLOCK_REALTIME,..) use the same back end code in the kernel.

In fact, prior to 2.6.18 on many architectures, clock_gettime(CLOCK_REALTIME,) just returned basically gettimeofday()'s value multiplied up to nanoseconds.

More recently its been turned around, and the kernel keeps finer precision, so gettimeofday() uses the clock_gettime(CLOCK_REALTIME) back end.

The only benefits to gettimeofday() is that on powerpc, ia64 and x86_64, it is implemented with a userspace-only vsyscall/vdso, which avoids the syscall overhead. However, recent x86_64 kernels have added support for vsyscall clock_gettime() as well.

>    Is the 2038/2106 problem a possibility for any of these?

The timeval/timespec time_t second value maps to a long, so for 32 bit architectures, yes, the 2038 issue is present. However on 64bit architectures it is not.

> 6. How about setting the current time:  what are the differences between
>    settimeofday() and clock_settime(CLOCK_REALTIME)?

Nope, only that clock_settime allows for nanosecond resolution in setting the time. They are just different interfaces for the same back end code.

> 7. How does clock_gettime(CLOCK_REALTIME) work?  Let's assume linux 2.6.26 on
>    the following systems:

This one will be a little long winded. The code is always the best documentation here (as its the most current). I'll try to give a brief rundown, but if folks are really interested, they should grab the kernel source and dig in.

>    Dual Xeon 3.06ghz (two single-core 32bit cpus).

Likely has a sync'ed TSC, so that would probably be the hardware clocksource used.

>    Dual Intel Xeon X5460 3.0ghz (two quad-core 64bit cpus).

Same as the above. The timekeeping core is generic between architectures.

The only possible difference is if the system was utilizing power saving and the TSC halted in the ACPI C3 state. Then the system would detect this and fall back to a slower but more reliable clocksource. Likely the HPET on a modern system like this.

However, if gettimeofday() was called, the same algorithm would be done completely in userspace using the vsyscall method (kernel maps a page of code and a page of data out as user-readable, and userland executes it directly, avoiding the syscall overhead).

>    Single AMD Turion 1.9ghz (one dual-core 64bit cpu) on a laptop.

Since power saving is important here, its likely the TSC would either change frequency or halt in C3 idle, so it would not be usable. We'd detect this on boot up and switch to another available clocksource. On this system, I'm guessing the ACPI PM counter would be used. Then its exactly as in System A, but instead of reading the TSC, we read the ACPI PM.

Also, while the box is 64 bits, since the ACPI PM uses port-io to access it, it cannot be used in a vsyscall, so the vsyscall gettimeofday would be disabled.

> 8. Are there any interesting points / implementation notes worth knowing about
>    clock_gettime(CLOCK_REALTIME)?  Any notes regarding virtual machines?

Uh. There's potentially lots here. clock_gettime(CLOCK_REALTIME isn't super interesting on its own, but timekeeping in general is). Timekeeping with virtual machines is an interesting problem. Also the userland-only vdso/vsyscall methods for gettimeofday() are interesting.

> 9. Closing Comments.

Linux 2.6 is all I can really speak to off the top of my head. I'm not even really sure when clock_gettime() support was merged (I'm not really sure if it was around in early 2.4). Back in the 2.4 days, the hardware was simpler, so there was less to deal with and things basically just worked.