1*6777b538SAndroid Build Coastguard Worker// Copyright 2012 The Chromium Authors 2*6777b538SAndroid Build Coastguard Worker// Use of this source code is governed by a BSD-style license that can be 3*6777b538SAndroid Build Coastguard Worker// found in the LICENSE file. 4*6777b538SAndroid Build Coastguard Worker 5*6777b538SAndroid Build Coastguard Worker#include "base/time/time.h" 6*6777b538SAndroid Build Coastguard Worker 7*6777b538SAndroid Build Coastguard Worker#import <Foundation/Foundation.h> 8*6777b538SAndroid Build Coastguard Worker#include <mach/mach.h> 9*6777b538SAndroid Build Coastguard Worker#include <mach/mach_time.h> 10*6777b538SAndroid Build Coastguard Worker#include <stddef.h> 11*6777b538SAndroid Build Coastguard Worker#include <stdint.h> 12*6777b538SAndroid Build Coastguard Worker#include <sys/sysctl.h> 13*6777b538SAndroid Build Coastguard Worker#include <sys/time.h> 14*6777b538SAndroid Build Coastguard Worker#include <sys/types.h> 15*6777b538SAndroid Build Coastguard Worker#include <time.h> 16*6777b538SAndroid Build Coastguard Worker 17*6777b538SAndroid Build Coastguard Worker#include "base/apple/mach_logging.h" 18*6777b538SAndroid Build Coastguard Worker#include "base/apple/scoped_cftyperef.h" 19*6777b538SAndroid Build Coastguard Worker#include "base/apple/scoped_mach_port.h" 20*6777b538SAndroid Build Coastguard Worker#include "base/logging.h" 21*6777b538SAndroid Build Coastguard Worker#include "base/numerics/safe_conversions.h" 22*6777b538SAndroid Build Coastguard Worker#include "base/time/time_override.h" 23*6777b538SAndroid Build Coastguard Worker#include "build/build_config.h" 24*6777b538SAndroid Build Coastguard Worker 25*6777b538SAndroid Build Coastguard Workernamespace { 26*6777b538SAndroid Build Coastguard Worker 27*6777b538SAndroid Build Coastguard Worker// Returns a pointer to the initialized Mach timebase info struct. 28*6777b538SAndroid Build Coastguard Workermach_timebase_info_data_t* MachTimebaseInfo() { 29*6777b538SAndroid Build Coastguard Worker static mach_timebase_info_data_t timebase_info = []() { 30*6777b538SAndroid Build Coastguard Worker mach_timebase_info_data_t info; 31*6777b538SAndroid Build Coastguard Worker kern_return_t kr = mach_timebase_info(&info); 32*6777b538SAndroid Build Coastguard Worker MACH_DCHECK(kr == KERN_SUCCESS, kr) << "mach_timebase_info"; 33*6777b538SAndroid Build Coastguard Worker DCHECK(info.numer); 34*6777b538SAndroid Build Coastguard Worker DCHECK(info.denom); 35*6777b538SAndroid Build Coastguard Worker return info; 36*6777b538SAndroid Build Coastguard Worker }(); 37*6777b538SAndroid Build Coastguard Worker return &timebase_info; 38*6777b538SAndroid Build Coastguard Worker} 39*6777b538SAndroid Build Coastguard Worker 40*6777b538SAndroid Build Coastguard Workerint64_t MachTimeToMicroseconds(uint64_t mach_time) { 41*6777b538SAndroid Build Coastguard Worker // timebase_info gives us the conversion factor between absolute time tick 42*6777b538SAndroid Build Coastguard Worker // units and nanoseconds. 43*6777b538SAndroid Build Coastguard Worker mach_timebase_info_data_t* timebase_info = MachTimebaseInfo(); 44*6777b538SAndroid Build Coastguard Worker 45*6777b538SAndroid Build Coastguard Worker // Take the fast path when the conversion is 1:1. The result will for sure fit 46*6777b538SAndroid Build Coastguard Worker // into an int_64 because we're going from nanoseconds to microseconds. 47*6777b538SAndroid Build Coastguard Worker if (timebase_info->numer == timebase_info->denom) { 48*6777b538SAndroid Build Coastguard Worker return static_cast<int64_t>(mach_time / 49*6777b538SAndroid Build Coastguard Worker base::Time::kNanosecondsPerMicrosecond); 50*6777b538SAndroid Build Coastguard Worker } 51*6777b538SAndroid Build Coastguard Worker 52*6777b538SAndroid Build Coastguard Worker uint64_t microseconds = 0; 53*6777b538SAndroid Build Coastguard Worker const uint64_t divisor = 54*6777b538SAndroid Build Coastguard Worker timebase_info->denom * base::Time::kNanosecondsPerMicrosecond; 55*6777b538SAndroid Build Coastguard Worker 56*6777b538SAndroid Build Coastguard Worker // Microseconds is mach_time * timebase.numer / 57*6777b538SAndroid Build Coastguard Worker // (timebase.denom * kNanosecondsPerMicrosecond). Divide first to reduce 58*6777b538SAndroid Build Coastguard Worker // the chance of overflow. Also stash the remainder right now, a likely 59*6777b538SAndroid Build Coastguard Worker // byproduct of the division. 60*6777b538SAndroid Build Coastguard Worker microseconds = mach_time / divisor; 61*6777b538SAndroid Build Coastguard Worker const uint64_t mach_time_remainder = mach_time % divisor; 62*6777b538SAndroid Build Coastguard Worker 63*6777b538SAndroid Build Coastguard Worker // Now multiply, keeping an eye out for overflow. 64*6777b538SAndroid Build Coastguard Worker CHECK(!__builtin_umulll_overflow(microseconds, timebase_info->numer, 65*6777b538SAndroid Build Coastguard Worker µseconds)); 66*6777b538SAndroid Build Coastguard Worker 67*6777b538SAndroid Build Coastguard Worker // By dividing first we lose precision. Regain it by adding back the 68*6777b538SAndroid Build Coastguard Worker // microseconds from the remainder, with an eye out for overflow. 69*6777b538SAndroid Build Coastguard Worker uint64_t least_significant_microseconds = 70*6777b538SAndroid Build Coastguard Worker (mach_time_remainder * timebase_info->numer) / divisor; 71*6777b538SAndroid Build Coastguard Worker CHECK(!__builtin_uaddll_overflow(microseconds, least_significant_microseconds, 72*6777b538SAndroid Build Coastguard Worker µseconds)); 73*6777b538SAndroid Build Coastguard Worker 74*6777b538SAndroid Build Coastguard Worker // Don't bother with the rollover handling that the Windows version does. 75*6777b538SAndroid Build Coastguard Worker // The returned time in microseconds is enough for 292,277 years (starting 76*6777b538SAndroid Build Coastguard Worker // from 2^63 because the returned int64_t is signed, 77*6777b538SAndroid Build Coastguard Worker // 9223372036854775807 / (1e6 * 60 * 60 * 24 * 365.2425) = 292,277). 78*6777b538SAndroid Build Coastguard Worker return base::checked_cast<int64_t>(microseconds); 79*6777b538SAndroid Build Coastguard Worker} 80*6777b538SAndroid Build Coastguard Worker 81*6777b538SAndroid Build Coastguard Worker// Returns monotonically growing number of ticks in microseconds since some 82*6777b538SAndroid Build Coastguard Worker// unspecified starting point. 83*6777b538SAndroid Build Coastguard Workerint64_t ComputeCurrentTicks() { 84*6777b538SAndroid Build Coastguard Worker // mach_absolute_time is it when it comes to ticks on the Mac. Other calls 85*6777b538SAndroid Build Coastguard Worker // with less precision (such as TickCount) just call through to 86*6777b538SAndroid Build Coastguard Worker // mach_absolute_time. 87*6777b538SAndroid Build Coastguard Worker return MachTimeToMicroseconds(mach_absolute_time()); 88*6777b538SAndroid Build Coastguard Worker} 89*6777b538SAndroid Build Coastguard Worker 90*6777b538SAndroid Build Coastguard Workerint64_t ComputeThreadTicks() { 91*6777b538SAndroid Build Coastguard Worker struct timespec ts = {}; 92*6777b538SAndroid Build Coastguard Worker CHECK(clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts) == 0); 93*6777b538SAndroid Build Coastguard Worker base::CheckedNumeric<int64_t> absolute_micros(ts.tv_sec); 94*6777b538SAndroid Build Coastguard Worker absolute_micros *= base::Time::kMicrosecondsPerSecond; 95*6777b538SAndroid Build Coastguard Worker absolute_micros += (ts.tv_nsec / base::Time::kNanosecondsPerMicrosecond); 96*6777b538SAndroid Build Coastguard Worker return absolute_micros.ValueOrDie(); 97*6777b538SAndroid Build Coastguard Worker} 98*6777b538SAndroid Build Coastguard Worker 99*6777b538SAndroid Build Coastguard Worker} // namespace 100*6777b538SAndroid Build Coastguard Worker 101*6777b538SAndroid Build Coastguard Workernamespace base { 102*6777b538SAndroid Build Coastguard Worker 103*6777b538SAndroid Build Coastguard Worker// The Time routines in this file use Mach and CoreFoundation APIs, since the 104*6777b538SAndroid Build Coastguard Worker// POSIX definition of time_t in macOS wraps around after 2038--and 105*6777b538SAndroid Build Coastguard Worker// there are already cookie expiration dates, etc., past that time out in 106*6777b538SAndroid Build Coastguard Worker// the field. Using CFDate prevents that problem, and using mach_absolute_time 107*6777b538SAndroid Build Coastguard Worker// for TimeTicks gives us nice high-resolution interval timing. 108*6777b538SAndroid Build Coastguard Worker 109*6777b538SAndroid Build Coastguard Worker// Time ----------------------------------------------------------------------- 110*6777b538SAndroid Build Coastguard Worker 111*6777b538SAndroid Build Coastguard Workernamespace subtle { 112*6777b538SAndroid Build Coastguard WorkerTime TimeNowIgnoringOverride() { 113*6777b538SAndroid Build Coastguard Worker return Time::FromCFAbsoluteTime(CFAbsoluteTimeGetCurrent()); 114*6777b538SAndroid Build Coastguard Worker} 115*6777b538SAndroid Build Coastguard Worker 116*6777b538SAndroid Build Coastguard WorkerTime TimeNowFromSystemTimeIgnoringOverride() { 117*6777b538SAndroid Build Coastguard Worker // Just use TimeNowIgnoringOverride() because it returns the system time. 118*6777b538SAndroid Build Coastguard Worker return TimeNowIgnoringOverride(); 119*6777b538SAndroid Build Coastguard Worker} 120*6777b538SAndroid Build Coastguard Worker} // namespace subtle 121*6777b538SAndroid Build Coastguard Worker 122*6777b538SAndroid Build Coastguard Worker// static 123*6777b538SAndroid Build Coastguard WorkerTime Time::FromCFAbsoluteTime(CFAbsoluteTime t) { 124*6777b538SAndroid Build Coastguard Worker static_assert(std::numeric_limits<CFAbsoluteTime>::has_infinity, 125*6777b538SAndroid Build Coastguard Worker "CFAbsoluteTime must have an infinity value"); 126*6777b538SAndroid Build Coastguard Worker if (t == 0) { 127*6777b538SAndroid Build Coastguard Worker return Time(); // Consider 0 as a null Time. 128*6777b538SAndroid Build Coastguard Worker } 129*6777b538SAndroid Build Coastguard Worker return (t == std::numeric_limits<CFAbsoluteTime>::infinity()) 130*6777b538SAndroid Build Coastguard Worker ? Max() 131*6777b538SAndroid Build Coastguard Worker : (UnixEpoch() + 132*6777b538SAndroid Build Coastguard Worker Seconds(double{t + kCFAbsoluteTimeIntervalSince1970})); 133*6777b538SAndroid Build Coastguard Worker} 134*6777b538SAndroid Build Coastguard Worker 135*6777b538SAndroid Build Coastguard WorkerCFAbsoluteTime Time::ToCFAbsoluteTime() const { 136*6777b538SAndroid Build Coastguard Worker static_assert(std::numeric_limits<CFAbsoluteTime>::has_infinity, 137*6777b538SAndroid Build Coastguard Worker "CFAbsoluteTime must have an infinity value"); 138*6777b538SAndroid Build Coastguard Worker if (is_null()) { 139*6777b538SAndroid Build Coastguard Worker return 0; // Consider 0 as a null Time. 140*6777b538SAndroid Build Coastguard Worker } 141*6777b538SAndroid Build Coastguard Worker return is_max() ? std::numeric_limits<CFAbsoluteTime>::infinity() 142*6777b538SAndroid Build Coastguard Worker : (CFAbsoluteTime{(*this - UnixEpoch()).InSecondsF()} - 143*6777b538SAndroid Build Coastguard Worker kCFAbsoluteTimeIntervalSince1970); 144*6777b538SAndroid Build Coastguard Worker} 145*6777b538SAndroid Build Coastguard Worker 146*6777b538SAndroid Build Coastguard Worker// static 147*6777b538SAndroid Build Coastguard WorkerTime Time::FromNSDate(NSDate* date) { 148*6777b538SAndroid Build Coastguard Worker DCHECK(date); 149*6777b538SAndroid Build Coastguard Worker return FromCFAbsoluteTime(date.timeIntervalSinceReferenceDate); 150*6777b538SAndroid Build Coastguard Worker} 151*6777b538SAndroid Build Coastguard Worker 152*6777b538SAndroid Build Coastguard WorkerNSDate* Time::ToNSDate() const { 153*6777b538SAndroid Build Coastguard Worker return [NSDate dateWithTimeIntervalSinceReferenceDate:ToCFAbsoluteTime()]; 154*6777b538SAndroid Build Coastguard Worker} 155*6777b538SAndroid Build Coastguard Worker 156*6777b538SAndroid Build Coastguard Worker// TimeDelta ------------------------------------------------------------------ 157*6777b538SAndroid Build Coastguard Worker 158*6777b538SAndroid Build Coastguard Worker// static 159*6777b538SAndroid Build Coastguard WorkerTimeDelta TimeDelta::FromMachTime(uint64_t mach_time) { 160*6777b538SAndroid Build Coastguard Worker return Microseconds(MachTimeToMicroseconds(mach_time)); 161*6777b538SAndroid Build Coastguard Worker} 162*6777b538SAndroid Build Coastguard Worker 163*6777b538SAndroid Build Coastguard Worker// TimeTicks ------------------------------------------------------------------ 164*6777b538SAndroid Build Coastguard Worker 165*6777b538SAndroid Build Coastguard Workernamespace subtle { 166*6777b538SAndroid Build Coastguard WorkerTimeTicks TimeTicksNowIgnoringOverride() { 167*6777b538SAndroid Build Coastguard Worker return TimeTicks() + Microseconds(ComputeCurrentTicks()); 168*6777b538SAndroid Build Coastguard Worker} 169*6777b538SAndroid Build Coastguard Worker} // namespace subtle 170*6777b538SAndroid Build Coastguard Worker 171*6777b538SAndroid Build Coastguard Worker// static 172*6777b538SAndroid Build Coastguard Workerbool TimeTicks::IsHighResolution() { 173*6777b538SAndroid Build Coastguard Worker return true; 174*6777b538SAndroid Build Coastguard Worker} 175*6777b538SAndroid Build Coastguard Worker 176*6777b538SAndroid Build Coastguard Worker// static 177*6777b538SAndroid Build Coastguard Workerbool TimeTicks::IsConsistentAcrossProcesses() { 178*6777b538SAndroid Build Coastguard Worker return true; 179*6777b538SAndroid Build Coastguard Worker} 180*6777b538SAndroid Build Coastguard Worker 181*6777b538SAndroid Build Coastguard Worker// static 182*6777b538SAndroid Build Coastguard WorkerTimeTicks TimeTicks::FromMachAbsoluteTime(uint64_t mach_absolute_time) { 183*6777b538SAndroid Build Coastguard Worker return TimeTicks(MachTimeToMicroseconds(mach_absolute_time)); 184*6777b538SAndroid Build Coastguard Worker} 185*6777b538SAndroid Build Coastguard Worker 186*6777b538SAndroid Build Coastguard Worker// static 187*6777b538SAndroid Build Coastguard Workermach_timebase_info_data_t TimeTicks::SetMachTimebaseInfoForTesting( 188*6777b538SAndroid Build Coastguard Worker mach_timebase_info_data_t timebase) { 189*6777b538SAndroid Build Coastguard Worker mach_timebase_info_data_t orig_timebase = *MachTimebaseInfo(); 190*6777b538SAndroid Build Coastguard Worker 191*6777b538SAndroid Build Coastguard Worker *MachTimebaseInfo() = timebase; 192*6777b538SAndroid Build Coastguard Worker 193*6777b538SAndroid Build Coastguard Worker return orig_timebase; 194*6777b538SAndroid Build Coastguard Worker} 195*6777b538SAndroid Build Coastguard Worker 196*6777b538SAndroid Build Coastguard Worker// static 197*6777b538SAndroid Build Coastguard WorkerTimeTicks::Clock TimeTicks::GetClock() { 198*6777b538SAndroid Build Coastguard Worker return Clock::MAC_MACH_ABSOLUTE_TIME; 199*6777b538SAndroid Build Coastguard Worker} 200*6777b538SAndroid Build Coastguard Worker 201*6777b538SAndroid Build Coastguard Worker// ThreadTicks ---------------------------------------------------------------- 202*6777b538SAndroid Build Coastguard Worker 203*6777b538SAndroid Build Coastguard Workernamespace subtle { 204*6777b538SAndroid Build Coastguard WorkerThreadTicks ThreadTicksNowIgnoringOverride() { 205*6777b538SAndroid Build Coastguard Worker return ThreadTicks() + Microseconds(ComputeThreadTicks()); 206*6777b538SAndroid Build Coastguard Worker} 207*6777b538SAndroid Build Coastguard Worker} // namespace subtle 208*6777b538SAndroid Build Coastguard Worker 209*6777b538SAndroid Build Coastguard Worker} // namespace base 210