Monotonic clock on OSX

Brett picture Brett · Jul 27, 2012 · Viewed 12.5k times · Source

CLOCK_MONOTONIC does not seem available, so clock_gettime is out.

I've read in some places that mach_absolute_time() might be the right way to go, but after reading that it was a 'cpu dependent value', it instantly made me wonder if it is using rtdsc underneath. Thus, the value could drift over time even if it is monotonic. Also, issues with thread affinity could result in meaningfully different results from calling the function (making it not monotonic across all cores).

Of course, that is just speculation. Does anyone know how mach_absolute_time actually works? I'm actually looking for a replacement to clock_gettime(CLOCK_MONOTONIC... or something like it for OSX. No matter what the clock source is, I expect at least millisecond precision and millisecond accuracy.

I'd just like to understand what clocks are available, which clocks are monotonic, if certain clocks drift, have thread affinity issues, aren't supported on all Mac hardware, or take a 'super high' number of cpu cycles to execute.

Here are the links I was able to find about this topic (some are already dead links and not findable on archive.org):

https://developer.apple.com/library/mac/#qa/qa1398/_index.html http://www.wand.net.nz/~smr26/wordpress/2009/01/19/monotonic-time-in-mac-os-x/ http://www.meandmark.com/timing.pdf

Thanks! Brett

Answer

zneak picture zneak · Jul 27, 2012

The Mach kernel provides access to system clocks, out of which at least one (SYSTEM_CLOCK) is advertised by the documentation as being monotonically incrementing.

#include <mach/clock.h>
#include <mach/mach.h>

clock_serv_t cclock;
mach_timespec_t mts;

host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &cclock);
clock_get_time(cclock, &mts);
mach_port_deallocate(mach_task_self(), cclock);

mach_timespec_t has nanosecond precision. I'm not sure about the accuracy, though.

Mac OS X supports three clocks:

  • SYSTEM_CLOCK returns the time since boot time;
  • CALENDAR_CLOCK returns the UTC time since 1970-01-01;
  • REALTIME_CLOCK is deprecated and is the same as SYSTEM_CLOCK in its current implementation.

The documentation for clock_get_time says the clocks are monotonically incrementing unless someone calls clock_set_time. Calls to clock_set_time are discouraged as it could break the monotonic property of the clocks, and in fact, the current implementation returns KERN_FAILURE without doing anything.