gettimeofday() should never be used to measure time
blog.habets.pp.se
blog.habets.pp.se
Not to mention: if the monotonic clock can keep such accurate timing, then everyone would just use that and NTP would not be so necessary.
Really: Under what conditions do you have a usefully functioning system when the clock is so off you need to do multi minute jumps? Even HyperV, with the utterly atrocious w32time manages to keep it with a minute or two (and a Linux guest can easily have ~ms accuracy).
The leap second point is valid, but that's an argument against leap seconds which serve no use in today's society other than to introduce unnecessary problems. Even Google just gives up and purposely introduces inaccuracies in their clocks for a day so that when the leap second comes around they're synced again. A leap hour would be a far better solution, as it's something many people are (unfortunately) used to from DST, and it wouldn't bother us for a dozen centuries.
One example is embedded systems. Many don't have an RTC, or boot after the RTC has lost power. If a network connection finally comes up, NTP will instantly fast-forward the clock by years
Stable and accurate is not the same thing.
And if you have two NTP servers, and one is off (example from the article), then yes multi-minute jumps do happen. A misconfigured NTP server caused TCP sessions in a load balancer to drop and ping commands to just hang. That is not OK.
Side-note: The misconfiguration in that example was "the NTP server ran on a virtual machine, where timer ticks from hardware to VM drifted, and the time difference to upstream became so big that the NTP daemon stopped trusting it and ignored it". I'm not defending that design, I didn't do it, and I fixed it when I found it.
Edit: Good suggestion BTW :)
Imagine you want to do something every second. You Sleep(1000) or some such. But it takes time to do the thing, so its actually a bit longer between loops. Maybe it doesn't matter; maybe it does. But you're stuck doing stuff like that.
Why not Wait(timetowaitfor). Not a duration; the actual time you want to be woken up. Now it still takes time to wake up and run. And it takes time to make the call. But now, your stuff actually runs say 60 times per minute (e.g. if you wait for successive seconds), hour after hour and day after day.
Also, what's with limited resolution on the time? Its due to the common implementation of timers as a counter of ticks, where a tick is whatever regular interval some hardware timer is set to interrupt. Why not instead interrogate a free-running counter? And if I want to wait 1 second plus 150 nanoseconds, then I Wait for that time to arrive, and the library (or OS) set a real timer interrupt to go off when that time has arrived? Sure there's latency in calling me back; that's inevitable. What's not inevitable is some limited multi-millisecond tick resolution.
Anyway, whenever I'm in charge of designing an OS or application environment, I provide real timers like this. It's about time the big OS providers catch up to the 21st century.
There's a lot of "what ifs" that need to be answered for something that seems so simple:
* What clock are you using? Machine ticks? Wall clock? Is it correct? Is it stable enough?
* What if the clock misses the time that I asked for? Do you run it anyway? Do you skip that invocation?
* What if the clock moves backwards? Will you trigger twice? Will you even notice?
* What if I have a leap second so there are 61 seconds in the hour? What if a second is removed so there are 59 seconds in the hour?
The reason why people don't touch this stuff or get it wrong is because it's really hard. There's a lot of corner cases when it comes to time handling.
If you're looking at measuring relative timing (for example for games or animation), you should instead use `double currentTime = CACurrentMediaTime();` That's the correct way.
Am I missing something ?
The first thing is ensured in the code, the 2nd thing can be ensured by, for example, checking for the existence of CLOCK_MONOTONIC in an initialization function, which we don't see in this example.
So I'd say that this is a case where you can relinquish checking the return value without feeling bad about it.
Same thing about sleep/usleep: All possible situations (sleeping correctly, and being interrupted) are handled correctly by the code (if you don't intend to handle signals, of course...).
of course clock_gettime() should have its return value checked, just like you always check the return value of gettimeofday() and time()
The miserable APIs are New Jersey/Worse-is-better answers to intractable problems.
Basically, my takeaway from this is: if you /can/ avoid the complexity, by dealing with absolute relative timings (if something takes 2 seconds, then it takes 2 seconds, even if one of them is a leap-second), then you /should/.
And the best way to do this is using the techniques mentioned in the article
But it is a self contained advice, that should be adhered to.
the fact that it doesn't already work this way is a design fail.
all the nonsense about NTP and clock slew and monotonicity are implementation details that should be hidden below this layer.
The correct call is to clock_gettime(CLOCK_MONOTONIC_RAW...
while (ts_remaining.tv_nsec > 1000000000) {
ts_remaining.tv_sec++;
ts_remaining.tv_nsec -= 1000000000;
}
should be int secs_in_nsec = ts_remaining.tv_nsec / 1000000000;
ts_remaining.tv_sec += secs_in_nsec;
ts_remaining.tv_nsec %= 1000000000;
Right? I mean maybe he microbenchmarked it and looping is faster because no div or mod, but intuitively this seems like it would be better. If the loops are a result of benchmarking, it should probably be called out in comments.Apple has really awesome developers who don't need to do stuff like this, and that's probably why iPhone alarms fail to go off every other leap year and reliably sound at 2 AM on January 32nd of years ending in '3'. Time-related code is like rolling your own encryption, in a sense. It's a trap for amateurs and pros alike.
could ever be true. I thought we had a-b, with a<1000000000 and b>=0.
For the negative check, the loop should only be able to run once, so could be changed to an 'if' for clarity. Regarding the timing, branching is probably faster.
It is my understanding that the c percent operator can produce a negative number by the way, so your code wouldn't work.
Hardware clocks don't always tick at one second per second.
Indeed. I'll go back and update posts if they are no longer true.
/Author