How to use Mach clocks

2006-11-26 14:20:12 UTC

Inspired by my previous post, in which I used them to time calloc and malloc…

You may have noticed that gettimeofday returns microseconds, and that this isn’t always a fine enough resolution (especially on the fast computers of today). On OS X, one solution is to use a Mach clock instead. (Another one is mach_absolute_time and AbsoluteToNanoseconds, as described by QA1398. With all the union or pointer magic you have to do with AbsoluteToNanoseconds, though, there’s not really an advantage; I think Mach clocks are slightly cleaner.)

  1. Get a Mach clock port using host_get_clock_service:

    clock_serv_t host_clock;
    kern_return_t status = host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &host_clock);

    There’s no difference in resolution between SYSTEM_CLOCK and CALENDAR_CLOCK as of Mac OS X 10.4.8. The difference between them is that SYSTEM_CLOCK is time since system boot, whereas CALENDAR_CLOCK is since the epoch (1970-01-01).

  2. Get the time using clock_get_time:

    mach_timespec_t now;
    clock_get_time(host_clock, &now);

    mach_timespec_t is basically the same as a struct timespec from time.h.

Implications

  • As I mentioned above, Mach clocks are one way to time things to nanosecond precision.
  • Mach clocks are also an easy way to implement half of uptime(1). CALENDAR_CLOCK gives you the wall-clock time, and SYSTEM_CLOCK gives you the actual uptime. (For the load averages, look at getrusage. You’re on your own for the number of logged-in users.)

Related reading

  • The Mach Kernel Interface manual. You may want to adapt that URL to your OS/machine combination (for example, 10.4.7.ppc for my Cube — no, I never got around to updating it to 10.4.8). You’ll need an APSL login, in any case.
  • Specifically, host_get_clock_service and clock_get_time. Those are opendarwin.org URLs, so you won’t need a APSL login to read them. Slightly old, but the current documentation doesn’t look any newer.
  • Also useful-looking are clock_get_attributes and clock_sleep. The former will tell you, among other things, the resolution of a clock (given a clock port from host_get_clock_service). The latter will sleep for some amount of time or until some time is reached.
  • clock_map_time looks like it would be very handy for an app that had to update a time display very very frequently.

Leave a Reply

Do not delete the second sentence.