The Life of a Programmer

API forensics for iOS system time: missing documentation

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!

QA Article

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!

UITouch.Timestamp

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.

The 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 mach_absolute_time?

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 UITouch.Timestamp and 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.

Please join me on Discord to discuss, or ping me on Mastadon.

API forensics for iOS system time: missing documentation

A Harmony of People. Code That Runs the World. And the Individual Behind the Keyboard.

Mailing List

Signup to my mailing list to get notified of each article I publish.

Recent Posts