Mach Absolute Time Units

Q: I'm trying to get precise timing measurements using mach_absolute_time. What time units does it use? Specifically, if I take two time measurements and subtract the earlier from the later, how do I convert the result to a real world value?

A: This function returns its result in terms of the Mach absolute time unit. This unit is CPU dependent, so you can't just multiply it by a constant to get a real world value. Rather, you should call a system-provided conversion function to convert it to a real world value.

The easiest conversion functions to use are AbsoluteToNanoseconds and AbsoluteToDuration from the CoreServices framework. You can also go in the other direction using NanosecondsToAbsolute and DurationToAbsolute. Listing 1 shows an example of how to get real world timing results using mach_absolute_time.

Listing 1: Converting Mach absolute time to nanoseconds using AbsoluteToNanoseconds

#include <assert.h>
#include <CoreServices/CoreServices.h>
#include <mach/mach.h>
#include <mach/mach_time.h>
#include <unistd.h>

uint64_t GetPIDTimeInNanoseconds(void)
{
    uint64_t        start;
    uint64_t        end;
    uint64_t        elapsed;
    Nanoseconds     elapsedNano;

    // Start the clock.

    start = mach_absolute_time();

    // Call getpid.  This will produce inaccurate results because
    // we're only making a single system call.  For more accurate
    // results you should call getpid multiple times and average
    // the results.

    (void) getpid();

    // Stop the clock.

    end = mach_absolute_time();

    // Calculate the duration.

    elapsed = end - start;

    // Convert to nanoseconds.

    // Have to do some pointer fun because AbsoluteToNanoseconds
    // works in terms of UnsignedWide, which is a structure rather
    // than a proper 64-bit integer.

    elapsedNano = AbsoluteToNanoseconds( *(AbsoluteTime *) &elapsed );

    return * (uint64_t *) &elapsedNano;
}

Note: For this code to work, Mach absolute time must be equivalent to CoreServices AbsoluteTime. This equivalence was previously undocumented, although it is true on all shipping versions of Mac OS X and is expected to be true on all future versions.

If your program cannot use the CoreServices framework, you can perform an equivalent conversion using the information returned by mach_timebase_info, as shown in Listing 2.

Listing 2: Converting Mach absolute time to nanoseconds using mach_timebase_info

#include <assert.h>
#include <CoreServices/CoreServices.h>
#include <mach/mach.h>
#include <mach/mach_time.h>
#include <unistd.h>

uint64_t GetPIDTimeInNanoseconds(void)
{
    uint64_t        start;
    uint64_t        end;
    uint64_t        elapsed;
    uint64_t        elapsedNano;
    static mach_timebase_info_data_t    sTimebaseInfo;

    // Start the clock.

    start = mach_absolute_time();

    // Call getpid.  This will produce inaccurate results because
    // we're only making a single system call.  For more accurate
    // results you should call getpid multiple times and average
    // the results.

    (void) getpid();

    // Stop the clock.

    end = mach_absolute_time();

    // Calculate the duration.

    elapsed = end - start;

    // Convert to nanoseconds.

    // If this is the first time we've run, get the timebase.
    // We can use denom == 0 to indicate that sTimebaseInfo is
    // uninitialised because it makes no sense to have a zero
    // denominator is a fraction.

    if ( sTimebaseInfo.denom == 0 ) {
        (void) mach_timebase_info(&sTimebaseInfo);
    }

    // Do the maths.  We hope that the multiplication doesn't
    // overflow; the price you pay for working in fixed point.

    elapsedNano = elapsed * sTimebaseInfo.numer / sTimebaseInfo.denom;

    return elapsedNano;
}

Note: The ability to convert between real time and Mach absolute time is also useful when calling mach_wait_until and thread_policy_set with the THREAD_TIME_CONSTRAINT_POLICY policy.

Document Revision History

DateNotes
2005-01-06Describes how to convert Mach absolute time units to real time, and vice versa.

Posted: 2005-01-06


Did this document help you?
Yes: Tell us what works for you.
It’s good, but: Report typos, inaccuracies, and so forth.
It wasn’t helpful: Tell us what would have helped.