1. Time never goes backwards (as other people have pointed out, time zones break this).
2. UTC time never goes backwards (as other people have pointed out, leap seconds break this).
3. The system boot time never changes. On most platforms, the current time is defined as "boot time plus uptime", and setting the current time is performed by changing the boot time.
4. System uptime never goes backwards. Some platforms handle setting the current time by changing the system uptime.
5. POSIX's CLOCK_MONOTONIC never goes backwards. On some platforms and virtualization environments this can break with CPUs shared between virtual machines.
6. On systems without virtualization, CLOCK_MONOTONIC never goes backwards. On some platforms this can occur due to clock skew between CPUs.
Ok, I oversimplified. UTC time does not go backwards, but the value returned by POSIX time(3) -- which is supposed to be the number of seconds since 1970-01-01 00:00:00 UTC -- does. (Assuming you have sub-second precision, of course; time_t isn't required to be an integer type, and there's other APIs which access the same UTC-seconds clock and provide microsecond or nanosecond precision.)
The value returned by POSIX time is commonly said to be "POSIX time" or "UNIX time". This names a time system other than UTC. In my experience, programmers don't seem to confuse these two systems.
I have seen good programmers be surprised by the fact that POSIX time goes backwards in the event of leap seconds, as I was when I learned it. I think it would have at least as much punch if you edited your "falsehood 2" to be about UNIX time instead of UTC. As a bonus, you would also be correct ;)
> 5. POSIX's CLOCK_MONOTONIC never goes backwards. On some platforms and virtualization environments this can break with CPUs shared between virtual machines.
> 6. On systems without virtualization, CLOCK_MONOTONIC never goes backwards. On some platforms this can occur due to clock skew between CPUs.
Could you explain these situations in more detail? Or cite a source I can take a look at?
CLOCK_MONOTONIC is what I use for timing quite often. I tend to do soft real time stuff and that clock seems the best suited for my tasks.
(5) is just a specific instance of the general principle "virtualization screws everything up". The most common issue is with virtualization systems trying to hide the fact that time is being "stolen" by the hypervisor and/or other domains.
(6) is a case of "synchronization is really hard" combined with "benchmarks measure system performance, not system correctness". Most high-performance timing these days involves reading an on-die clock counter, scaling, and adding a base (boot time) value. For that to work on SMP, the clocks need to be synchronized -- and they don't start that way, since CPU #0 is enabled first and does some hardware probing before it turns the other CPUs on. Even worse, on many platforms, power-saving features will slow down the clock, resulting in the counters getting out of sync.
As alexs says, CLOCK_MONOTONIC should be monotonic... but in reality, it's much faster to return a mostly-good-enough value. In FreeBSD, in addition to CLOCK_{UPTIME, REALTIME, MONOTONIC}, we have CLOCK__{FAST, PRECISE} so that applications can choose between accuracy and performance.
CLOCK_MONOTONIC is what I use for timing quite often. I tend to do soft real time stuff and that clock seems the best suited for my tasks.*
As long as you avoid virtualization, turn off all power-saving features, and your "soft real time" can tolerate non-monotonicity on the sub-microsecond scale, you should be safe.
If CLOCK_MONOTONIC goes backwards your platform's implementation is broken. As defined in POSIX it does not ever go backwards. It counts the time since an unspecified point in the past that never varies after system start-up.
If your process is rescheduled to a different CPU, it must still go forwards regardless of TSC variance between the CPUs.
Of course if your uptime hits 68 years or so, the clock will wrap. If your app can't have any downtime in 68 years though I hope you've got the budget to think about this sort of thing :)
1. Time never goes backwards (as other people have pointed out, time zones break this).
2. UTC time never goes backwards (as other people have pointed out, leap seconds break this).
3. The system boot time never changes. On most platforms, the current time is defined as "boot time plus uptime", and setting the current time is performed by changing the boot time.
4. System uptime never goes backwards. Some platforms handle setting the current time by changing the system uptime.
5. POSIX's CLOCK_MONOTONIC never goes backwards. On some platforms and virtualization environments this can break with CPUs shared between virtual machines.
6. On systems without virtualization, CLOCK_MONOTONIC never goes backwards. On some platforms this can occur due to clock skew between CPUs.