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 <stdint.h> 6*6777b538SAndroid Build Coastguard Worker #include <sys/time.h> 7*6777b538SAndroid Build Coastguard Worker #include <time.h> 8*6777b538SAndroid Build Coastguard Worker #include <unistd.h> 9*6777b538SAndroid Build Coastguard Worker 10*6777b538SAndroid Build Coastguard Worker #include <optional> 11*6777b538SAndroid Build Coastguard Worker 12*6777b538SAndroid Build Coastguard Worker #include "base/check.h" 13*6777b538SAndroid Build Coastguard Worker #include "base/notreached.h" 14*6777b538SAndroid Build Coastguard Worker #include "base/numerics/safe_math.h" 15*6777b538SAndroid Build Coastguard Worker #include "base/time/time.h" 16*6777b538SAndroid Build Coastguard Worker #include "base/time/time_override.h" 17*6777b538SAndroid Build Coastguard Worker #include "build/build_config.h" 18*6777b538SAndroid Build Coastguard Worker 19*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_ANDROID) && !defined(__LP64__) 20*6777b538SAndroid Build Coastguard Worker #include <time64.h> 21*6777b538SAndroid Build Coastguard Worker #endif 22*6777b538SAndroid Build Coastguard Worker 23*6777b538SAndroid Build Coastguard Worker // Ensure the Fuchsia and Mac builds do not include this module. Instead, 24*6777b538SAndroid Build Coastguard Worker // non-POSIX implementation is used for sampling the system clocks. 25*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_FUCHSIA) || BUILDFLAG(IS_APPLE) 26*6777b538SAndroid Build Coastguard Worker #error "This implementation is for POSIX platforms other than Fuchsia or Mac." 27*6777b538SAndroid Build Coastguard Worker #endif 28*6777b538SAndroid Build Coastguard Worker 29*6777b538SAndroid Build Coastguard Worker namespace { 30*6777b538SAndroid Build Coastguard Worker ConvertTimespecToMicros(const struct timespec & ts)31*6777b538SAndroid Build Coastguard Workerint64_t ConvertTimespecToMicros(const struct timespec& ts) { 32*6777b538SAndroid Build Coastguard Worker // On 32-bit systems, the calculation cannot overflow int64_t. 33*6777b538SAndroid Build Coastguard Worker // 2**32 * 1000000 + 2**64 / 1000 < 2**63 34*6777b538SAndroid Build Coastguard Worker if (sizeof(ts.tv_sec) <= 4 && sizeof(ts.tv_nsec) <= 8) { 35*6777b538SAndroid Build Coastguard Worker int64_t result = ts.tv_sec; 36*6777b538SAndroid Build Coastguard Worker result *= base::Time::kMicrosecondsPerSecond; 37*6777b538SAndroid Build Coastguard Worker result += (ts.tv_nsec / base::Time::kNanosecondsPerMicrosecond); 38*6777b538SAndroid Build Coastguard Worker return result; 39*6777b538SAndroid Build Coastguard Worker } 40*6777b538SAndroid Build Coastguard Worker base::CheckedNumeric<int64_t> result(ts.tv_sec); 41*6777b538SAndroid Build Coastguard Worker result *= base::Time::kMicrosecondsPerSecond; 42*6777b538SAndroid Build Coastguard Worker result += (ts.tv_nsec / base::Time::kNanosecondsPerMicrosecond); 43*6777b538SAndroid Build Coastguard Worker return result.ValueOrDie(); 44*6777b538SAndroid Build Coastguard Worker } 45*6777b538SAndroid Build Coastguard Worker 46*6777b538SAndroid Build Coastguard Worker // Helper function to get results from clock_gettime() and convert to a 47*6777b538SAndroid Build Coastguard Worker // microsecond timebase. Minimum requirement is MONOTONIC_CLOCK to be supported 48*6777b538SAndroid Build Coastguard Worker // on the system. FreeBSD 6 has CLOCK_MONOTONIC but defines 49*6777b538SAndroid Build Coastguard Worker // _POSIX_MONOTONIC_CLOCK to -1. 50*6777b538SAndroid Build Coastguard Worker #if (BUILDFLAG(IS_POSIX) && defined(_POSIX_MONOTONIC_CLOCK) && \ 51*6777b538SAndroid Build Coastguard Worker _POSIX_MONOTONIC_CLOCK >= 0) || \ 52*6777b538SAndroid Build Coastguard Worker BUILDFLAG(IS_BSD) || BUILDFLAG(IS_ANDROID) ClockNow(clockid_t clk_id)53*6777b538SAndroid Build Coastguard Workerint64_t ClockNow(clockid_t clk_id) { 54*6777b538SAndroid Build Coastguard Worker struct timespec ts; 55*6777b538SAndroid Build Coastguard Worker CHECK(clock_gettime(clk_id, &ts) == 0); 56*6777b538SAndroid Build Coastguard Worker return ConvertTimespecToMicros(ts); 57*6777b538SAndroid Build Coastguard Worker } 58*6777b538SAndroid Build Coastguard Worker MaybeClockNow(clockid_t clk_id)59*6777b538SAndroid Build Coastguard Workerstd::optional<int64_t> MaybeClockNow(clockid_t clk_id) { 60*6777b538SAndroid Build Coastguard Worker struct timespec ts; 61*6777b538SAndroid Build Coastguard Worker int res = clock_gettime(clk_id, &ts); 62*6777b538SAndroid Build Coastguard Worker if (res == 0) 63*6777b538SAndroid Build Coastguard Worker return ConvertTimespecToMicros(ts); 64*6777b538SAndroid Build Coastguard Worker return std::nullopt; 65*6777b538SAndroid Build Coastguard Worker } 66*6777b538SAndroid Build Coastguard Worker 67*6777b538SAndroid Build Coastguard Worker #else // _POSIX_MONOTONIC_CLOCK 68*6777b538SAndroid Build Coastguard Worker #error No usable tick clock function on this platform. 69*6777b538SAndroid Build Coastguard Worker #endif // _POSIX_MONOTONIC_CLOCK 70*6777b538SAndroid Build Coastguard Worker 71*6777b538SAndroid Build Coastguard Worker } // namespace 72*6777b538SAndroid Build Coastguard Worker 73*6777b538SAndroid Build Coastguard Worker namespace base { 74*6777b538SAndroid Build Coastguard Worker 75*6777b538SAndroid Build Coastguard Worker // Time ----------------------------------------------------------------------- 76*6777b538SAndroid Build Coastguard Worker 77*6777b538SAndroid Build Coastguard Worker namespace subtle { TimeNowIgnoringOverride()78*6777b538SAndroid Build Coastguard WorkerTime TimeNowIgnoringOverride() { 79*6777b538SAndroid Build Coastguard Worker struct timeval tv; 80*6777b538SAndroid Build Coastguard Worker struct timezone tz = {0, 0}; // UTC 81*6777b538SAndroid Build Coastguard Worker CHECK(gettimeofday(&tv, &tz) == 0); 82*6777b538SAndroid Build Coastguard Worker // Combine seconds and microseconds in a 64-bit field containing microseconds 83*6777b538SAndroid Build Coastguard Worker // since the epoch. That's enough for nearly 600 centuries. Adjust from 84*6777b538SAndroid Build Coastguard Worker // Unix (1970) to Windows (1601) epoch. 85*6777b538SAndroid Build Coastguard Worker return Time() + 86*6777b538SAndroid Build Coastguard Worker Microseconds((tv.tv_sec * Time::kMicrosecondsPerSecond + tv.tv_usec) + 87*6777b538SAndroid Build Coastguard Worker Time::kTimeTToMicrosecondsOffset); 88*6777b538SAndroid Build Coastguard Worker } 89*6777b538SAndroid Build Coastguard Worker TimeNowFromSystemTimeIgnoringOverride()90*6777b538SAndroid Build Coastguard WorkerTime TimeNowFromSystemTimeIgnoringOverride() { 91*6777b538SAndroid Build Coastguard Worker // Just use TimeNowIgnoringOverride() because it returns the system time. 92*6777b538SAndroid Build Coastguard Worker return TimeNowIgnoringOverride(); 93*6777b538SAndroid Build Coastguard Worker } 94*6777b538SAndroid Build Coastguard Worker } // namespace subtle 95*6777b538SAndroid Build Coastguard Worker 96*6777b538SAndroid Build Coastguard Worker // TimeTicks ------------------------------------------------------------------ 97*6777b538SAndroid Build Coastguard Worker 98*6777b538SAndroid Build Coastguard Worker namespace subtle { TimeTicksNowIgnoringOverride()99*6777b538SAndroid Build Coastguard WorkerTimeTicks TimeTicksNowIgnoringOverride() { 100*6777b538SAndroid Build Coastguard Worker return TimeTicks() + Microseconds(ClockNow(CLOCK_MONOTONIC)); 101*6777b538SAndroid Build Coastguard Worker } 102*6777b538SAndroid Build Coastguard Worker MaybeTimeTicksNowIgnoringOverride()103*6777b538SAndroid Build Coastguard Workerstd::optional<TimeTicks> MaybeTimeTicksNowIgnoringOverride() { 104*6777b538SAndroid Build Coastguard Worker std::optional<int64_t> now = MaybeClockNow(CLOCK_MONOTONIC); 105*6777b538SAndroid Build Coastguard Worker if (now.has_value()) 106*6777b538SAndroid Build Coastguard Worker return TimeTicks() + Microseconds(now.value()); 107*6777b538SAndroid Build Coastguard Worker return std::nullopt; 108*6777b538SAndroid Build Coastguard Worker } 109*6777b538SAndroid Build Coastguard Worker } // namespace subtle 110*6777b538SAndroid Build Coastguard Worker 111*6777b538SAndroid Build Coastguard Worker // static GetClock()112*6777b538SAndroid Build Coastguard WorkerTimeTicks::Clock TimeTicks::GetClock() { 113*6777b538SAndroid Build Coastguard Worker return Clock::LINUX_CLOCK_MONOTONIC; 114*6777b538SAndroid Build Coastguard Worker } 115*6777b538SAndroid Build Coastguard Worker 116*6777b538SAndroid Build Coastguard Worker // static IsHighResolution()117*6777b538SAndroid Build Coastguard Workerbool TimeTicks::IsHighResolution() { 118*6777b538SAndroid Build Coastguard Worker return true; 119*6777b538SAndroid Build Coastguard Worker } 120*6777b538SAndroid Build Coastguard Worker 121*6777b538SAndroid Build Coastguard Worker // static IsConsistentAcrossProcesses()122*6777b538SAndroid Build Coastguard Workerbool TimeTicks::IsConsistentAcrossProcesses() { 123*6777b538SAndroid Build Coastguard Worker return true; 124*6777b538SAndroid Build Coastguard Worker } 125*6777b538SAndroid Build Coastguard Worker 126*6777b538SAndroid Build Coastguard Worker // ThreadTicks ---------------------------------------------------------------- 127*6777b538SAndroid Build Coastguard Worker 128*6777b538SAndroid Build Coastguard Worker namespace subtle { ThreadTicksNowIgnoringOverride()129*6777b538SAndroid Build Coastguard WorkerThreadTicks ThreadTicksNowIgnoringOverride() { 130*6777b538SAndroid Build Coastguard Worker #if (defined(_POSIX_THREAD_CPUTIME) && (_POSIX_THREAD_CPUTIME >= 0)) || \ 131*6777b538SAndroid Build Coastguard Worker BUILDFLAG(IS_ANDROID) 132*6777b538SAndroid Build Coastguard Worker return ThreadTicks() + Microseconds(ClockNow(CLOCK_THREAD_CPUTIME_ID)); 133*6777b538SAndroid Build Coastguard Worker #else 134*6777b538SAndroid Build Coastguard Worker NOTREACHED(); 135*6777b538SAndroid Build Coastguard Worker return ThreadTicks(); 136*6777b538SAndroid Build Coastguard Worker #endif 137*6777b538SAndroid Build Coastguard Worker } 138*6777b538SAndroid Build Coastguard Worker } // namespace subtle 139*6777b538SAndroid Build Coastguard Worker 140*6777b538SAndroid Build Coastguard Worker } // namespace base 141