1

Savvy engineers use clock_gettime( CLOCK_MONOTONIC, &my_timspec_struct ) to get a continuously increasing epoch-style clock that is "unaffected" by changes to the system clock. (Where the epoch-start is not defined).

However, CLOCK_MONOTONIC is effected by NTP daemon time-changes known as clock "slewing".

By the definition of CLOCK_MONOTONIC, we know that it will never jump backwards. But how does it it mitigate changes by NTP? If the system-clock is suddenly set 5 hours in the past by NTP, does the monotonic clock run a bit slower until it catches up? Maybe it just stops "ticking" until the difference evens-out?

What really does happen? If it's system dependent, what happens on Linux?

I have some timing related code that's failing where the hardware clocks are very flaky. They're being re-adjusted to a GPS source every few minutes. And while this reads like it shouldn't effect CLOCK_MONOTONIC, sometimes (1 in 20) timing related code is just not working. I can't just change everything to CLOCK_MONOTONIC_RAW, because libraries (e.g.: Qt) still use non-raw (Ref: Qt 5.15 source).

Kingsley
  • 14,398
  • 5
  • 31
  • 53
  • 1
    That the hardware clocks are flaky suggests that the system's clock *source(s)* may be unreliable. Perhaps it stalls from time to time, or doesn't reliably produce the required voltage levels. I would expect such effects to impact `CLOCK_MONOTONIC` and probably `CLOCK_MONOTONIC_RAW`, too. They shouldn't move backwards, but they might stop moving *forwards* for a time, or they might advance at inconsistent speed. – John Bollinger Nov 29 '22 at 23:49

1 Answers1

1

What really does happen? If it's system dependent, what happens on Linux?

It is system-dependent whether there even is a CLOCK_MONOTONIC. The only clock that POSIX requires implementations to provide is CLOCK_REALTIME. So, what happens on Linux?

The docs have this to say about CLOCK_MONOTONIC:

Clock that cannot be set and represents monotonic time since some unspecified starting point. This clock is not affected by discontinuous jumps in the system time (e.g., if the system administrator manually changes the clock), but is affected by the incremental adjustments performed by adjtime(3) and NTP.

The docs for adjtime() add:

If the adjustment in delta is positive, then the system clock is speeded up by some small percentage (i.e., by adding a small amount of time to the clock value in each second) until the adjustment has been completed. If the adjustment in delta is negative, then the clock is slowed down in a similar fashion.

From that we can conclude that CLOCK_MONOTONIC moves at the same speed as the system clock, which is why it is affected when NTP slews the clock or adjtime() is used, but that it is not updated when the system clock is set. It just keeps counting up, monotonically.

John Bollinger
  • 160,171
  • 8
  • 81
  • 157
  • 1
    Note also that as far as I am aware, the unspecified starting point for `CLOCK_MONOTONIC` time is not required to remain the same across reboots. – John Bollinger Nov 29 '22 at 23:31