6 ms·
gettimeofday() should never be used to measure time
- shared4you 12y agoOP or mods: please add [2010] tag to the title.
- theoh 12y agoIf adding the year to every post that's not "news" is to become a convention, it should be added to the guidelines. I doubt this is going to happen because, really, what difference does it make for an article like this?
- jonsen 12y agogetyearofpost() should never be used to measure timeliness
- thomashabets2 12y agoHa! Indeed. I'll go back and update posts if they are no longer true. /Author
- brianshaler 12y agoOn articles more than a year old, I find the year helps me know at a glance if a familiar sounding title is something I've read before or fresh content with the coincidentally familiar headline.
- wmf 12y agoOld posts tend to contain outdated information, although I don't think that's the case here. The real issue is that almost every old post has already been discussed on HN previously, and posting it again just wastes time by restarting the discussion from scratch.
- conradk 12y agoIronic that the "What to use instead" part doesn't even feel the need to check return values of functions. Am I missing something ?
- cnvogel 12y agoAccording to the API, clock_gettime() can only error out for two reasons: EFAULT when the 2nd argument points to invalid memory or EINVAL when the clock is not supported on the system. 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...).
- thomashabets2 12y agoExample code often skip error handling, because that's not the point. of course clock_gettime() should have its return value checked, just like you always check the return value of gettimeofday() and time()
- conradk 12y agoIn an article that tries to tell us we're doing it wrong, doing it right would be nice.
- pstrateman 12y agoThis isn't even right.... The correct call is to clock_gettime(CLOCK_MONOTONIC_RAW...
- obstinate 12y agowhile (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.
- CamperBob2 12y agoI sometimes deliberately write really slow, stupid C code when dealing with time or other things that are both extremely important and (if I'm honest with myself) unlikely to be tested exhaustively. 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.
- im3w1l 12y agoI don't really understand how ts_remaining.tv_nsec > 1000000000 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.
- bdonlan 12y agoWell, that depends. CLOCK_MONOTONIC_RAW does avoid NTP slewing, but NTP doesn't just adjust the time scale to adjust for offsets - it also attempts to correct for frequency error in your system clock itself. If you use CLOCK_MONOTONIC_RAW, you don't get that correction; you get something that on desktop hardware can easily be tens of ppm off from actual time. Of course, your MONOTONIC_RAW clock is still subject to the vagaries of physics; as temperature or system load changes, depending on the quality of your time source, you might get significant changes in the rate of CLOCK_MONOTONIC_RAW as well (which NTP will correct for in CLOCK_MONOTONIC, given enough time to adjust).
- MichaelGG 12y agoExcept when doing a pcap, I actually want the actual time it is. Maybe in some cases you'd explicitly want an offset, but not in general. It's really a plea to get your clocks synced up, so you aren't forced to choose between reporting an incorrect time or an incorrect duration. If I'm running a pcap and the system time changes over a day by several seconds, I'd prefer each packet to report the closest concept of the right time instead of being way off as time goes by. 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.
- mct 12y agoUnder what conditions do you have a usefully functioning system when the clock is so off you need to do multi minute jumps? 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
- toast0 12y agofor debian based embedded systems, the fake-hwclock package is helpful here (it's a script to periodically save the current time, and restore on boot). You'll still have big jumps after a power loss, but probably not years. It's also helpful in case you ever change the motherboard on a regular system with a RTC.
- cperciva 12y agoMany embedded systems don't have any writable durable storage.
- dsjoerg 12y agothe semantics you'd like the OS + standard library to provide would be some kind of gettime() call that returns a time thingie, and a secondsbetween(a,b) call that reliably tells you the time between the two time thingies. 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.
- JoeAltmaier 12y agoOS time handling is feeble across the industry. Its inherited from 20-year-old ideas about APIs. Not just the antique time structures that are useful for rendering but not much else. Also the abominable Sleep() and such. 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.
- rwmj 12y agoYou probably want to look at setitimer.
- JoeAltmaier 12y agoWhy? That still uses intervals instead of real time indexes.
- hmpc 12y agoYou can already do this in POSIX.1-2001-conforming systems like Linux using `clock_nanosleep` (http://man7.org/linux/man-pages/man2/clock_nanosleep.2.html http://man7.org/linux/man-pages/man2/clock_nanosleep.2.html).
- 12y ago
- vojfox 12y agoIt's a similar situation on iOS, where new developers sometimes use (in Objective-C) `[[NSDate date] timeIntervalSince1970]` which is natural, but wrong. NSDate draws from the network synchronized clock and will occasionally hiccup when re-synching it against the network, among other reasons. 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.
- sargun 12y agoLet's talk about the sad state of clocks today. There exists a few ways to query NTP time on Linux. (1) Directly through NTP (2) the adjtimex syscall, (3) the ntp_gettime call. I found it hard to find many codebases using the proper NTP. In fact codebases that need reliable time, like Cassandra and OpenLDAP. don't use NTP time APIs to check whether the system clock is in sync, or to get accurate time. Even if we were to make PTP accessible to the world, it would be some time before its usage actually became ubiquitous. The understandability of time keeping, and clock yielding in our community is a sore point.
- Matumio 12y agoI think NTP usually synchronizes the system time, so programs don't have to use any NTP specific API to get NTP time. PTP won't help here: all it does is increase the accuracy from milliseconds to microseconds - not much use if the Linux scheduler tick is 1ms. PTP time is mainly useful together with hardware event timestamping, where stuff like interrupt latency can be excluded. If you want, for example, to send a frame every two seconds as soon as the device boots, you still should use CLOCK_MONOTONIC, otherwise you produce a glitch when PTP ramps up.
- teddyh 12y agoI wish that HN would use the Public Suffix List (https://publicsuffix.org/ https://publicsuffix.org/) in its algorithm to display domain names of submissions. That way, we wouldn’t get things like this, where the domain given (pp.se) does not say anything about what the actual site is.
- cpach 12y agoI think the HN admins/devs will have a better chance to see your suggestion if you send it to hn@ycombinator.com Edit: Good suggestion BTW :)
- shanwang 12y agothe last time I tested them on redhat 6, clock_gettime(REALTIME) and gettimeofday are slightly faster than clock_gettime(CLOCK_MONOTONIC), and gettimeofday is much faster than any clock_gettime on older platforms.
- dbrower 12y agoI think the article and much of the discussion misses a larger point -- time is hard, and very very hard when there are multiple systems with different clocks. The APIs are the way they are because there just aren't solutions especially since all systems ultimately have unreliable connections to good time sources. The miserable APIs are New Jersey/Worse-is-better answers to intractable problems.
- stestagg 12y agoThat's just not the point of this article. 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
- thomashabets2 12y agoThis is but one chapter of what could be a huge book on time programming, I agree. But it is a self contained advice, that should be adhered to.