I started using the
mach_absolute_time function on iOS to get proper event timing information. It works well, I think; the problem is that I actually don’t know what this function is supposed to do. It seems related to
UITouch timestamps, which I need, but maybe that’s a local coincidence. Despite the function being used in an abundance of examples there is no real documentation on it!
The best reference on the
mach_absolute_time function appears to be a QA article in the Mac developer library. It shows how to get the current system time in nanoseconds.
It has no link to documentation about the functions it uses. The developer library search also yields no documentation. There are a few other functions that reference these functions, but nothing describes their behaviour. Curiously, I did find a Firefox issue with comments complaining about this lack of documentation.
It seems clear from the article what these functions do, but it’d be nice to have a guarantee of some kind. The timer is a critical piece of our system!
I need accurate time information to properly detect velocity on touch events.
UITouch has a
timestamp field indicating when the event actually happened. The difference between this time and the current system time is sometimes large enough to make a noticable difference in gesture response. The effect is magnified if there happens to be a frame-drop near the event.
My recent changes were to allow gestures to work correctly even with low or jittery frame rates. Obviously we do everything we can to avoid low FPS, but we don’t restrict what the user codes. One inadvertent long running function, or suboptimal layout, might cause an occasional frame to be lost. Even if not visible to the user, it can certainly mess with time sensitive functions, like gesture detection.
For some gestures on their own, like scrolling, these timestamps are sufficient. But it’d be nice to to relate these timestamps to the current system time. For a gesture like “long-press” it’s actually essential, as I don’t have a followup touch event with a timestamp. I need to be able to measure a delta between the first touch even and the current system time.
timestamp field is documented to have the same base as
systemUptime. Unfortunately the documentation there is sparse, revealing only it’s “The time interval since the computer was restarted.” Is this the same time base as
To the source code
I was able to find the declaration of
mach_absolute_time in the Xnu package, header file
mach_time.h. It unfortunately does not provide any additional documentation.
I also found an x86 assembler version of the function in
mach_absolute_time.s. It describes the algorithm they use but not what the output is. The 64 bit version does however mention a 64-bit nanotime as output. They both use
rdtsc op, so they are based on the chip’s time stamp counter.
Looking around I find mention of “Core Audio Clock Services” as well. Under this header in the library it also mentions
mach_absolute_time as a way to get timing information. I also found something called
CMClockRef in the core media framework. This one explicitly mentions that on Mac OSX
mach_absolute_time is being used as a time source.
All the same?
In practice it seems that
mach_absolute_time are using the same timing system: the event times are strongly correlated to the absolute time near their generation. This appears to work on OSX on a MacBook Pro and on an iPhone4s and 5s. From StackOverflow I can ascertain that people use this for timing information on many other devices as well.
It’s probably the same time the native controls use for media playback, given the hint in core services. There’s no guarantee of any of this though. This is very unfortunate. Timing on multi-core CPUs with frequency scaling is a complex topic; it’s dangerous to make assumptions!
Lacking documentation though it’s all I can do. I just have to assume the “sane” interpretation is the valid one.