1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/ipc/chromium/src/base/time_mac.cc Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,125 @@ 1.4 +// Copyright (c) 2008 The Chromium Authors. All rights reserved. 1.5 +// Use of this source code is governed by a BSD-style license that can be 1.6 +// found in the LICENSE file. 1.7 + 1.8 +#include "base/time.h" 1.9 + 1.10 +#include <CoreFoundation/CFDate.h> 1.11 +#include <CoreFoundation/CFTimeZone.h> 1.12 +#include <mach/mach_time.h> 1.13 +#include <sys/time.h> 1.14 +#include <time.h> 1.15 + 1.16 +#include "base/basictypes.h" 1.17 +#include "base/logging.h" 1.18 +#include "base/scoped_cftyperef.h" 1.19 + 1.20 +namespace base { 1.21 + 1.22 +// The Time routines in this file use Mach and CoreFoundation APIs, since the 1.23 +// POSIX definition of time_t in Mac OS X wraps around after 2038--and 1.24 +// there are already cookie expiration dates, etc., past that time out in 1.25 +// the field. Using CFDate prevents that problem, and using mach_absolute_time 1.26 +// for TimeTicks gives us nice high-resolution interval timing. 1.27 + 1.28 +// Time ----------------------------------------------------------------------- 1.29 + 1.30 +// The internal representation of Time uses a 64-bit microsecond count 1.31 +// from 1970-01-01 00:00:00 UTC. Core Foundation uses a double second count 1.32 +// since 2001-01-01 00:00:00 UTC. 1.33 + 1.34 +// Some functions in time.cc use time_t directly, so we provide a zero offset 1.35 +// for them. The epoch is 1970-01-01 00:00:00 UTC. 1.36 +// static 1.37 +const int64_t Time::kTimeTToMicrosecondsOffset = GG_INT64_C(0); 1.38 + 1.39 +// static 1.40 +Time Time::Now() { 1.41 + CFAbsoluteTime now = 1.42 + CFAbsoluteTimeGetCurrent() + kCFAbsoluteTimeIntervalSince1970; 1.43 + return Time(static_cast<int64_t>(now * kMicrosecondsPerSecond)); 1.44 +} 1.45 + 1.46 +// static 1.47 +Time Time::NowFromSystemTime() { 1.48 + // Just use Now() because Now() returns the system time. 1.49 + return Now(); 1.50 +} 1.51 + 1.52 +// static 1.53 +Time Time::FromExploded(bool is_local, const Exploded& exploded) { 1.54 + CFGregorianDate date; 1.55 + date.second = exploded.second + 1.56 + exploded.millisecond / static_cast<double>(kMillisecondsPerSecond); 1.57 + date.minute = exploded.minute; 1.58 + date.hour = exploded.hour; 1.59 + date.day = exploded.day_of_month; 1.60 + date.month = exploded.month; 1.61 + date.year = exploded.year; 1.62 + 1.63 + scoped_cftyperef<CFTimeZoneRef> 1.64 + time_zone(is_local ? CFTimeZoneCopySystem() : NULL); 1.65 + CFAbsoluteTime seconds = CFGregorianDateGetAbsoluteTime(date, time_zone) + 1.66 + kCFAbsoluteTimeIntervalSince1970; 1.67 + return Time(static_cast<int64_t>(seconds * kMicrosecondsPerSecond)); 1.68 +} 1.69 + 1.70 +void Time::Explode(bool is_local, Exploded* exploded) const { 1.71 + CFAbsoluteTime seconds = 1.72 + (static_cast<double>(us_) / kMicrosecondsPerSecond) - 1.73 + kCFAbsoluteTimeIntervalSince1970; 1.74 + 1.75 + scoped_cftyperef<CFTimeZoneRef> 1.76 + time_zone(is_local ? CFTimeZoneCopySystem() : NULL); 1.77 + CFGregorianDate date = CFAbsoluteTimeGetGregorianDate(seconds, time_zone); 1.78 + 1.79 + exploded->year = date.year; 1.80 + exploded->month = date.month; 1.81 + exploded->day_of_month = date.day; 1.82 + exploded->hour = date.hour; 1.83 + exploded->minute = date.minute; 1.84 + exploded->second = date.second; 1.85 + exploded->millisecond = 1.86 + static_cast<int>(date.second * kMillisecondsPerSecond) % 1.87 + kMillisecondsPerSecond; 1.88 +} 1.89 + 1.90 +// TimeTicks ------------------------------------------------------------------ 1.91 + 1.92 +// static 1.93 +TimeTicks TimeTicks::Now() { 1.94 + uint64_t absolute_micro; 1.95 + 1.96 + static mach_timebase_info_data_t timebase_info; 1.97 + if (timebase_info.denom == 0) { 1.98 + // Zero-initialization of statics guarantees that denom will be 0 before 1.99 + // calling mach_timebase_info. mach_timebase_info will never set denom to 1.100 + // 0 as that would be invalid, so the zero-check can be used to determine 1.101 + // whether mach_timebase_info has already been called. This is 1.102 + // recommended by Apple's QA1398. 1.103 + kern_return_t kr = mach_timebase_info(&timebase_info); 1.104 + DCHECK(kr == KERN_SUCCESS); 1.105 + } 1.106 + 1.107 + // mach_absolute_time is it when it comes to ticks on the Mac. Other calls 1.108 + // with less precision (such as TickCount) just call through to 1.109 + // mach_absolute_time. 1.110 + 1.111 + // timebase_info converts absolute time tick units into nanoseconds. Convert 1.112 + // to microseconds up front to stave off overflows. 1.113 + absolute_micro = mach_absolute_time() / Time::kNanosecondsPerMicrosecond * 1.114 + timebase_info.numer / timebase_info.denom; 1.115 + 1.116 + // Don't bother with the rollover handling that the Windows version does. 1.117 + // With numer and denom = 1 (the expected case), the 64-bit absolute time 1.118 + // reported in nanoseconds is enough to last nearly 585 years. 1.119 + 1.120 + return TimeTicks(absolute_micro); 1.121 +} 1.122 + 1.123 +// static 1.124 +TimeTicks TimeTicks::HighResNow() { 1.125 + return Now(); 1.126 +} 1.127 + 1.128 +} // namespace base