cacc4e75dbbff469c10a505168208f064c6c385cvboxsync/* $Id$ */
cacc4e75dbbff469c10a505168208f064c6c385cvboxsync/** @file
5b281ba489ca18f0380d7efc7a5108b606cce449vboxsync * IPRT - Time, Darwin.
cacc4e75dbbff469c10a505168208f064c6c385cvboxsync */
cacc4e75dbbff469c10a505168208f064c6c385cvboxsync
cacc4e75dbbff469c10a505168208f064c6c385cvboxsync/*
6cf438776892898b86c5c34c92e32fc446b057d2vboxsync * Copyright (C) 2006-2014 Oracle Corporation
c98fb3e16fcd571a790eab772c0c66173d225205vboxsync *
c98fb3e16fcd571a790eab772c0c66173d225205vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
c98fb3e16fcd571a790eab772c0c66173d225205vboxsync * available from http://www.virtualbox.org. This file is free software;
c98fb3e16fcd571a790eab772c0c66173d225205vboxsync * you can redistribute it and/or modify it under the terms of the GNU
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * General Public License (GPL) as published by the Free Software
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync *
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * The contents of this file may alternatively be used under the terms
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * of the Common Development and Distribution License Version 1.0
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * VirtualBox OSE distribution, in which case the provisions of the
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * CDDL are applicable instead of those of the GPL.
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync *
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * You may elect to license modified versions of this file under the
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * terms and conditions of either the GPL or the CDDL or both.
cacc4e75dbbff469c10a505168208f064c6c385cvboxsync */
cacc4e75dbbff469c10a505168208f064c6c385cvboxsync
cacc4e75dbbff469c10a505168208f064c6c385cvboxsync
cacc4e75dbbff469c10a505168208f064c6c385cvboxsync/*******************************************************************************
cacc4e75dbbff469c10a505168208f064c6c385cvboxsync* Header Files *
cacc4e75dbbff469c10a505168208f064c6c385cvboxsync*******************************************************************************/
cacc4e75dbbff469c10a505168208f064c6c385cvboxsync#define LOG_GROUP RTLOGGROUP_TIME
cacc4e75dbbff469c10a505168208f064c6c385cvboxsync#define RTTIME_INCL_TIMEVAL
cacc4e75dbbff469c10a505168208f064c6c385cvboxsync#include <mach/mach_time.h>
cacc4e75dbbff469c10a505168208f064c6c385cvboxsync#include <mach/kern_return.h>
cacc4e75dbbff469c10a505168208f064c6c385cvboxsync#include <sys/time.h>
cacc4e75dbbff469c10a505168208f064c6c385cvboxsync#include <time.h>
cacc4e75dbbff469c10a505168208f064c6c385cvboxsync
cacc4e75dbbff469c10a505168208f064c6c385cvboxsync#include <iprt/time.h>
41362345e58e563b5341f0012f05327d0f36ffe1vboxsync#include <iprt/assert.h>
cacc4e75dbbff469c10a505168208f064c6c385cvboxsync#include "internal/time.h"
cacc4e75dbbff469c10a505168208f064c6c385cvboxsync
cacc4e75dbbff469c10a505168208f064c6c385cvboxsync
41362345e58e563b5341f0012f05327d0f36ffe1vboxsync/*******************************************************************************
41362345e58e563b5341f0012f05327d0f36ffe1vboxsync* Global Variables *
41362345e58e563b5341f0012f05327d0f36ffe1vboxsync*******************************************************************************/
41362345e58e563b5341f0012f05327d0f36ffe1vboxsyncstatic struct mach_timebase_info g_Info = { 0, 0 };
41362345e58e563b5341f0012f05327d0f36ffe1vboxsyncstatic double g_rdFactor = 0.0;
41362345e58e563b5341f0012f05327d0f36ffe1vboxsyncstatic bool g_fFailedToGetTimeBaseInfo = false;
cacc4e75dbbff469c10a505168208f064c6c385cvboxsync
41362345e58e563b5341f0012f05327d0f36ffe1vboxsync
41362345e58e563b5341f0012f05327d0f36ffe1vboxsync/**
41362345e58e563b5341f0012f05327d0f36ffe1vboxsync * Perform lazy init (pray we're not racing anyone in a bad way).
41362345e58e563b5341f0012f05327d0f36ffe1vboxsync */
41362345e58e563b5341f0012f05327d0f36ffe1vboxsyncstatic void rtTimeDarwinLazyInit(void)
41362345e58e563b5341f0012f05327d0f36ffe1vboxsync{
41362345e58e563b5341f0012f05327d0f36ffe1vboxsync struct mach_timebase_info Info;
41362345e58e563b5341f0012f05327d0f36ffe1vboxsync if (mach_timebase_info(&Info) == KERN_SUCCESS)
cacc4e75dbbff469c10a505168208f064c6c385cvboxsync {
41362345e58e563b5341f0012f05327d0f36ffe1vboxsync g_rdFactor = (double)Info.numer / (double)Info.denom;
41362345e58e563b5341f0012f05327d0f36ffe1vboxsync g_Info = Info;
cacc4e75dbbff469c10a505168208f064c6c385cvboxsync }
41362345e58e563b5341f0012f05327d0f36ffe1vboxsync else
41362345e58e563b5341f0012f05327d0f36ffe1vboxsync {
41362345e58e563b5341f0012f05327d0f36ffe1vboxsync g_fFailedToGetTimeBaseInfo = true;
41362345e58e563b5341f0012f05327d0f36ffe1vboxsync Assert(g_Info.denom == 0 && g_Info.numer == 0 && g_rdFactor == 0.0);
41362345e58e563b5341f0012f05327d0f36ffe1vboxsync }
41362345e58e563b5341f0012f05327d0f36ffe1vboxsync}
41362345e58e563b5341f0012f05327d0f36ffe1vboxsync
41362345e58e563b5341f0012f05327d0f36ffe1vboxsync
41362345e58e563b5341f0012f05327d0f36ffe1vboxsync/**
41362345e58e563b5341f0012f05327d0f36ffe1vboxsync * Internal worker.
41362345e58e563b5341f0012f05327d0f36ffe1vboxsync * @returns Nanosecond timestamp.
41362345e58e563b5341f0012f05327d0f36ffe1vboxsync */
41362345e58e563b5341f0012f05327d0f36ffe1vboxsyncDECLINLINE(uint64_t) rtTimeGetSystemNanoTS(void)
41362345e58e563b5341f0012f05327d0f36ffe1vboxsync{
41362345e58e563b5341f0012f05327d0f36ffe1vboxsync /* Lazy init. */
41362345e58e563b5341f0012f05327d0f36ffe1vboxsync if (RT_UNLIKELY(g_Info.denom == 0 && !g_fFailedToGetTimeBaseInfo))
41362345e58e563b5341f0012f05327d0f36ffe1vboxsync rtTimeDarwinLazyInit();
cacc4e75dbbff469c10a505168208f064c6c385cvboxsync
cacc4e75dbbff469c10a505168208f064c6c385cvboxsync /* special case: absolute time is in nanoseconds */
41362345e58e563b5341f0012f05327d0f36ffe1vboxsync if (g_Info.denom == 1 && g_Info.numer == 1)
cacc4e75dbbff469c10a505168208f064c6c385cvboxsync return mach_absolute_time();
cacc4e75dbbff469c10a505168208f064c6c385cvboxsync
cacc4e75dbbff469c10a505168208f064c6c385cvboxsync /* general case: multiply by factor to get nanoseconds. */
41362345e58e563b5341f0012f05327d0f36ffe1vboxsync if (g_rdFactor != 0.0)
41362345e58e563b5341f0012f05327d0f36ffe1vboxsync return mach_absolute_time() * g_rdFactor;
cacc4e75dbbff469c10a505168208f064c6c385cvboxsync
cacc4e75dbbff469c10a505168208f064c6c385cvboxsync /* worst case: fallback to gettimeofday(). */
cacc4e75dbbff469c10a505168208f064c6c385cvboxsync struct timeval tv;
cacc4e75dbbff469c10a505168208f064c6c385cvboxsync gettimeofday(&tv, NULL);
6cf438776892898b86c5c34c92e32fc446b057d2vboxsync return (uint64_t)tv.tv_sec * RT_NS_1SEC_64
6cf438776892898b86c5c34c92e32fc446b057d2vboxsync + (uint64_t)(tv.tv_usec * RT_NS_1US);
cacc4e75dbbff469c10a505168208f064c6c385cvboxsync}
cacc4e75dbbff469c10a505168208f064c6c385cvboxsync
cacc4e75dbbff469c10a505168208f064c6c385cvboxsync
cacc4e75dbbff469c10a505168208f064c6c385cvboxsyncRTDECL(uint64_t) RTTimeSystemNanoTS(void)
cacc4e75dbbff469c10a505168208f064c6c385cvboxsync{
cacc4e75dbbff469c10a505168208f064c6c385cvboxsync return rtTimeGetSystemNanoTS();
cacc4e75dbbff469c10a505168208f064c6c385cvboxsync}
cacc4e75dbbff469c10a505168208f064c6c385cvboxsync
cacc4e75dbbff469c10a505168208f064c6c385cvboxsync
cacc4e75dbbff469c10a505168208f064c6c385cvboxsyncRTDECL(uint64_t) RTTimeSystemMilliTS(void)
cacc4e75dbbff469c10a505168208f064c6c385cvboxsync{
6cf438776892898b86c5c34c92e32fc446b057d2vboxsync return rtTimeGetSystemNanoTS() / RT_NS_1MS;
cacc4e75dbbff469c10a505168208f064c6c385cvboxsync}
cacc4e75dbbff469c10a505168208f064c6c385cvboxsync
cacc4e75dbbff469c10a505168208f064c6c385cvboxsync
cacc4e75dbbff469c10a505168208f064c6c385cvboxsyncRTDECL(PRTTIMESPEC) RTTimeNow(PRTTIMESPEC pTime)
cacc4e75dbbff469c10a505168208f064c6c385cvboxsync{
cacc4e75dbbff469c10a505168208f064c6c385cvboxsync /** @todo find nanosecond API for getting time of day. */
cacc4e75dbbff469c10a505168208f064c6c385cvboxsync struct timeval tv;
cacc4e75dbbff469c10a505168208f064c6c385cvboxsync gettimeofday(&tv, NULL);
cacc4e75dbbff469c10a505168208f064c6c385cvboxsync return RTTimeSpecSetTimeval(pTime, &tv);
cacc4e75dbbff469c10a505168208f064c6c385cvboxsync}
cacc4e75dbbff469c10a505168208f064c6c385cvboxsync