1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/ipc/chromium/src/base/time_posix.cc Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,195 @@ 1.4 +// Copyright (c) 2006-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 +#ifdef OS_MACOSX 1.11 +#include <mach/mach_time.h> 1.12 +#endif 1.13 +#include <sys/time.h> 1.14 +#ifdef ANDROID 1.15 +#include <time64.h> 1.16 +#else 1.17 +#include <time.h> 1.18 +#endif 1.19 +#if defined(ANDROID) || defined(OS_POSIX) 1.20 +#include <unistd.h> 1.21 +#endif 1.22 + 1.23 +#include <limits> 1.24 + 1.25 +#include "base/basictypes.h" 1.26 +#include "base/logging.h" 1.27 + 1.28 +namespace base { 1.29 + 1.30 +// The Time routines in this file use standard POSIX routines, or almost- 1.31 +// standard routines in the case of timegm. We need to use a Mach-specific 1.32 +// function for TimeTicks::Now() on Mac OS X. 1.33 + 1.34 +// Time ----------------------------------------------------------------------- 1.35 + 1.36 +// Some functions in time.cc use time_t directly, so we provide a zero offset 1.37 +// for them. The epoch is 1970-01-01 00:00:00 UTC. 1.38 +// static 1.39 +const int64_t Time::kTimeTToMicrosecondsOffset = GG_INT64_C(0); 1.40 + 1.41 +// static 1.42 +Time Time::Now() { 1.43 + struct timeval tv; 1.44 + struct timezone tz = { 0, 0 }; // UTC 1.45 + if (gettimeofday(&tv, &tz) != 0) { 1.46 + DCHECK(0) << "Could not determine time of day"; 1.47 + } 1.48 + // Combine seconds and microseconds in a 64-bit field containing microseconds 1.49 + // since the epoch. That's enough for nearly 600 centuries. 1.50 + return tv.tv_sec * kMicrosecondsPerSecond + tv.tv_usec; 1.51 +} 1.52 + 1.53 +// static 1.54 +Time Time::NowFromSystemTime() { 1.55 + // Just use Now() because Now() returns the system time. 1.56 + return Now(); 1.57 +} 1.58 + 1.59 +// static 1.60 +Time Time::FromExploded(bool is_local, const Exploded& exploded) { 1.61 + struct tm timestruct; 1.62 + timestruct.tm_sec = exploded.second; 1.63 + timestruct.tm_min = exploded.minute; 1.64 + timestruct.tm_hour = exploded.hour; 1.65 + timestruct.tm_mday = exploded.day_of_month; 1.66 + timestruct.tm_mon = exploded.month - 1; 1.67 + timestruct.tm_year = exploded.year - 1900; 1.68 + timestruct.tm_wday = exploded.day_of_week; // mktime/timegm ignore this 1.69 + timestruct.tm_yday = 0; // mktime/timegm ignore this 1.70 + timestruct.tm_isdst = -1; // attempt to figure it out 1.71 + timestruct.tm_gmtoff = 0; // not a POSIX field, so mktime/timegm ignore 1.72 + timestruct.tm_zone = NULL; // not a POSIX field, so mktime/timegm ignore 1.73 + 1.74 + time_t seconds; 1.75 +#ifdef ANDROID 1.76 + seconds = mktime(×truct); 1.77 +#else 1.78 + if (is_local) 1.79 + seconds = mktime(×truct); 1.80 + else 1.81 + seconds = timegm(×truct); 1.82 +#endif 1.83 + 1.84 + int64_t milliseconds; 1.85 + // Handle overflow. Clamping the range to what mktime and timegm might 1.86 + // return is the best that can be done here. It's not ideal, but it's better 1.87 + // than failing here or ignoring the overflow case and treating each time 1.88 + // overflow as one second prior to the epoch. 1.89 + if (seconds == -1 && 1.90 + (exploded.year < 1969 || exploded.year > 1970)) { 1.91 + // If exploded.year is 1969 or 1970, take -1 as correct, with the 1.92 + // time indicating 1 second prior to the epoch. (1970 is allowed to handle 1.93 + // time zone and DST offsets.) Otherwise, return the most future or past 1.94 + // time representable. Assumes the time_t epoch is 1970-01-01 00:00:00 UTC. 1.95 + // 1.96 + // The minimum and maximum representible times that mktime and timegm could 1.97 + // return are used here instead of values outside that range to allow for 1.98 + // proper round-tripping between exploded and counter-type time 1.99 + // representations in the presence of possible truncation to time_t by 1.100 + // division and use with other functions that accept time_t. 1.101 + // 1.102 + // When representing the most distant time in the future, add in an extra 1.103 + // 999ms to avoid the time being less than any other possible value that 1.104 + // this function can return. 1.105 + if (exploded.year < 1969) { 1.106 + milliseconds = std::numeric_limits<time_t>::min() * 1.107 + kMillisecondsPerSecond; 1.108 + } else { 1.109 + milliseconds = (std::numeric_limits<time_t>::max() * 1.110 + kMillisecondsPerSecond) + 1.111 + kMillisecondsPerSecond - 1; 1.112 + } 1.113 + } else { 1.114 + milliseconds = seconds * kMillisecondsPerSecond + exploded.millisecond; 1.115 + } 1.116 + 1.117 + return Time(milliseconds * kMicrosecondsPerMillisecond); 1.118 +} 1.119 + 1.120 +void Time::Explode(bool is_local, Exploded* exploded) const { 1.121 + // Time stores times with microsecond resolution, but Exploded only carries 1.122 + // millisecond resolution, so begin by being lossy. 1.123 + int64_t milliseconds = us_ / kMicrosecondsPerMillisecond; 1.124 + time_t seconds = milliseconds / kMillisecondsPerSecond; 1.125 + 1.126 + struct tm timestruct; 1.127 + if (is_local) 1.128 + localtime_r(&seconds, ×truct); 1.129 + else 1.130 + gmtime_r(&seconds, ×truct); 1.131 + 1.132 + exploded->year = timestruct.tm_year + 1900; 1.133 + exploded->month = timestruct.tm_mon + 1; 1.134 + exploded->day_of_week = timestruct.tm_wday; 1.135 + exploded->day_of_month = timestruct.tm_mday; 1.136 + exploded->hour = timestruct.tm_hour; 1.137 + exploded->minute = timestruct.tm_min; 1.138 + exploded->second = timestruct.tm_sec; 1.139 + exploded->millisecond = milliseconds % kMillisecondsPerSecond; 1.140 +} 1.141 + 1.142 +// TimeTicks ------------------------------------------------------------------ 1.143 + 1.144 +// static 1.145 +TimeTicks TimeTicks::Now() { 1.146 + uint64_t absolute_micro; 1.147 + 1.148 +#if defined(OS_MACOSX) 1.149 + static mach_timebase_info_data_t timebase_info; 1.150 + if (timebase_info.denom == 0) { 1.151 + // Zero-initialization of statics guarantees that denom will be 0 before 1.152 + // calling mach_timebase_info. mach_timebase_info will never set denom to 1.153 + // 0 as that would be invalid, so the zero-check can be used to determine 1.154 + // whether mach_timebase_info has already been called. This is 1.155 + // recommended by Apple's QA1398. 1.156 + kern_return_t kr = mach_timebase_info(&timebase_info); 1.157 + DCHECK(kr == KERN_SUCCESS); 1.158 + } 1.159 + 1.160 + // mach_absolute_time is it when it comes to ticks on the Mac. Other calls 1.161 + // with less precision (such as TickCount) just call through to 1.162 + // mach_absolute_time. 1.163 + 1.164 + // timebase_info converts absolute time tick units into nanoseconds. Convert 1.165 + // to microseconds up front to stave off overflows. 1.166 + absolute_micro = mach_absolute_time() / Time::kNanosecondsPerMicrosecond * 1.167 + timebase_info.numer / timebase_info.denom; 1.168 + 1.169 + // Don't bother with the rollover handling that the Windows version does. 1.170 + // With numer and denom = 1 (the expected case), the 64-bit absolute time 1.171 + // reported in nanoseconds is enough to last nearly 585 years. 1.172 + 1.173 +#elif defined(OS_OPENBSD) || defined(OS_POSIX) && \ 1.174 + defined(_POSIX_MONOTONIC_CLOCK) && _POSIX_MONOTONIC_CLOCK >= 0 1.175 + 1.176 + struct timespec ts; 1.177 + if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) { 1.178 + NOTREACHED() << "clock_gettime(CLOCK_MONOTONIC) failed."; 1.179 + return TimeTicks(); 1.180 + } 1.181 + 1.182 + absolute_micro = 1.183 + (static_cast<int64_t>(ts.tv_sec) * Time::kMicrosecondsPerSecond) + 1.184 + (static_cast<int64_t>(ts.tv_nsec) / Time::kNanosecondsPerMicrosecond); 1.185 + 1.186 +#else // _POSIX_MONOTONIC_CLOCK 1.187 +#error No usable tick clock function on this platform. 1.188 +#endif // _POSIX_MONOTONIC_CLOCK 1.189 + 1.190 + return TimeTicks(absolute_micro); 1.191 +} 1.192 + 1.193 +// static 1.194 +TimeTicks TimeTicks::HighResNow() { 1.195 + return Now(); 1.196 +} 1.197 + 1.198 +} // namespace base