xref: /aosp_15_r20/external/libchrome/base/time/time_now_posix.cc (revision 635a864187cb8b6c713ff48b7e790a6b21769273)
1*635a8641SAndroid Build Coastguard Worker // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2*635a8641SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*635a8641SAndroid Build Coastguard Worker // found in the LICENSE file.
4*635a8641SAndroid Build Coastguard Worker 
5*635a8641SAndroid Build Coastguard Worker #include "base/time/time.h"
6*635a8641SAndroid Build Coastguard Worker 
7*635a8641SAndroid Build Coastguard Worker #include <stdint.h>
8*635a8641SAndroid Build Coastguard Worker #include <sys/time.h>
9*635a8641SAndroid Build Coastguard Worker #include <time.h>
10*635a8641SAndroid Build Coastguard Worker #if defined(OS_ANDROID) && !defined(__LP64__)
11*635a8641SAndroid Build Coastguard Worker #include <time64.h>
12*635a8641SAndroid Build Coastguard Worker #endif
13*635a8641SAndroid Build Coastguard Worker #include <unistd.h>
14*635a8641SAndroid Build Coastguard Worker 
15*635a8641SAndroid Build Coastguard Worker #include "base/logging.h"
16*635a8641SAndroid Build Coastguard Worker #include "base/numerics/safe_math.h"
17*635a8641SAndroid Build Coastguard Worker #include "base/time/time_override.h"
18*635a8641SAndroid Build Coastguard Worker #include "build/build_config.h"
19*635a8641SAndroid Build Coastguard Worker 
20*635a8641SAndroid Build Coastguard Worker // Ensure the Fuchsia and Mac builds do not include this module. Instead,
21*635a8641SAndroid Build Coastguard Worker // non-POSIX implementation is used for sampling the system clocks.
22*635a8641SAndroid Build Coastguard Worker #if defined(OS_FUCHSIA) || defined(OS_MACOSX)
23*635a8641SAndroid Build Coastguard Worker #error "This implementation is for POSIX platforms other than Fuchsia or Mac."
24*635a8641SAndroid Build Coastguard Worker #endif
25*635a8641SAndroid Build Coastguard Worker 
26*635a8641SAndroid Build Coastguard Worker namespace {
27*635a8641SAndroid Build Coastguard Worker 
ConvertTimespecToMicros(const struct timespec & ts)28*635a8641SAndroid Build Coastguard Worker int64_t ConvertTimespecToMicros(const struct timespec& ts) {
29*635a8641SAndroid Build Coastguard Worker   // On 32-bit systems, the calculation cannot overflow int64_t.
30*635a8641SAndroid Build Coastguard Worker   // 2**32 * 1000000 + 2**64 / 1000 < 2**63
31*635a8641SAndroid Build Coastguard Worker   if (sizeof(ts.tv_sec) <= 4 && sizeof(ts.tv_nsec) <= 8) {
32*635a8641SAndroid Build Coastguard Worker     int64_t result = ts.tv_sec;
33*635a8641SAndroid Build Coastguard Worker     result *= base::Time::kMicrosecondsPerSecond;
34*635a8641SAndroid Build Coastguard Worker     result += (ts.tv_nsec / base::Time::kNanosecondsPerMicrosecond);
35*635a8641SAndroid Build Coastguard Worker     return result;
36*635a8641SAndroid Build Coastguard Worker   } else {
37*635a8641SAndroid Build Coastguard Worker     base::CheckedNumeric<int64_t> result(ts.tv_sec);
38*635a8641SAndroid Build Coastguard Worker     result *= base::Time::kMicrosecondsPerSecond;
39*635a8641SAndroid Build Coastguard Worker     result += (ts.tv_nsec / base::Time::kNanosecondsPerMicrosecond);
40*635a8641SAndroid Build Coastguard Worker     return result.ValueOrDie();
41*635a8641SAndroid Build Coastguard Worker   }
42*635a8641SAndroid Build Coastguard Worker }
43*635a8641SAndroid Build Coastguard Worker 
44*635a8641SAndroid Build Coastguard Worker // Helper function to get results from clock_gettime() and convert to a
45*635a8641SAndroid Build Coastguard Worker // microsecond timebase. Minimum requirement is MONOTONIC_CLOCK to be supported
46*635a8641SAndroid Build Coastguard Worker // on the system. FreeBSD 6 has CLOCK_MONOTONIC but defines
47*635a8641SAndroid Build Coastguard Worker // _POSIX_MONOTONIC_CLOCK to -1.
48*635a8641SAndroid Build Coastguard Worker #if (defined(OS_POSIX) && defined(_POSIX_MONOTONIC_CLOCK) && \
49*635a8641SAndroid Build Coastguard Worker      _POSIX_MONOTONIC_CLOCK >= 0) ||                         \
50*635a8641SAndroid Build Coastguard Worker     defined(OS_BSD) || defined(OS_ANDROID)
ClockNow(clockid_t clk_id)51*635a8641SAndroid Build Coastguard Worker int64_t ClockNow(clockid_t clk_id) {
52*635a8641SAndroid Build Coastguard Worker   struct timespec ts;
53*635a8641SAndroid Build Coastguard Worker   CHECK(clock_gettime(clk_id, &ts) == 0);
54*635a8641SAndroid Build Coastguard Worker   return ConvertTimespecToMicros(ts);
55*635a8641SAndroid Build Coastguard Worker }
56*635a8641SAndroid Build Coastguard Worker #else  // _POSIX_MONOTONIC_CLOCK
57*635a8641SAndroid Build Coastguard Worker #error No usable tick clock function on this platform.
58*635a8641SAndroid Build Coastguard Worker #endif  // _POSIX_MONOTONIC_CLOCK
59*635a8641SAndroid Build Coastguard Worker 
60*635a8641SAndroid Build Coastguard Worker }  // namespace
61*635a8641SAndroid Build Coastguard Worker 
62*635a8641SAndroid Build Coastguard Worker namespace base {
63*635a8641SAndroid Build Coastguard Worker 
64*635a8641SAndroid Build Coastguard Worker // Time -----------------------------------------------------------------------
65*635a8641SAndroid Build Coastguard Worker 
66*635a8641SAndroid Build Coastguard Worker namespace subtle {
TimeNowIgnoringOverride()67*635a8641SAndroid Build Coastguard Worker Time TimeNowIgnoringOverride() {
68*635a8641SAndroid Build Coastguard Worker   struct timeval tv;
69*635a8641SAndroid Build Coastguard Worker   struct timezone tz = {0, 0};  // UTC
70*635a8641SAndroid Build Coastguard Worker   CHECK(gettimeofday(&tv, &tz) == 0);
71*635a8641SAndroid Build Coastguard Worker   // Combine seconds and microseconds in a 64-bit field containing microseconds
72*635a8641SAndroid Build Coastguard Worker   // since the epoch.  That's enough for nearly 600 centuries.  Adjust from
73*635a8641SAndroid Build Coastguard Worker   // Unix (1970) to Windows (1601) epoch.
74*635a8641SAndroid Build Coastguard Worker   return Time() + TimeDelta::FromMicroseconds(
75*635a8641SAndroid Build Coastguard Worker                       (tv.tv_sec * Time::kMicrosecondsPerSecond + tv.tv_usec) +
76*635a8641SAndroid Build Coastguard Worker                       Time::kTimeTToMicrosecondsOffset);
77*635a8641SAndroid Build Coastguard Worker }
78*635a8641SAndroid Build Coastguard Worker 
TimeNowFromSystemTimeIgnoringOverride()79*635a8641SAndroid Build Coastguard Worker Time TimeNowFromSystemTimeIgnoringOverride() {
80*635a8641SAndroid Build Coastguard Worker   // Just use TimeNowIgnoringOverride() because it returns the system time.
81*635a8641SAndroid Build Coastguard Worker   return TimeNowIgnoringOverride();
82*635a8641SAndroid Build Coastguard Worker }
83*635a8641SAndroid Build Coastguard Worker }  // namespace subtle
84*635a8641SAndroid Build Coastguard Worker 
85*635a8641SAndroid Build Coastguard Worker // TimeTicks ------------------------------------------------------------------
86*635a8641SAndroid Build Coastguard Worker 
87*635a8641SAndroid Build Coastguard Worker namespace subtle {
TimeTicksNowIgnoringOverride()88*635a8641SAndroid Build Coastguard Worker TimeTicks TimeTicksNowIgnoringOverride() {
89*635a8641SAndroid Build Coastguard Worker   return TimeTicks() + TimeDelta::FromMicroseconds(ClockNow(CLOCK_MONOTONIC));
90*635a8641SAndroid Build Coastguard Worker }
91*635a8641SAndroid Build Coastguard Worker }  // namespace subtle
92*635a8641SAndroid Build Coastguard Worker 
93*635a8641SAndroid Build Coastguard Worker // static
GetClock()94*635a8641SAndroid Build Coastguard Worker TimeTicks::Clock TimeTicks::GetClock() {
95*635a8641SAndroid Build Coastguard Worker   return Clock::LINUX_CLOCK_MONOTONIC;
96*635a8641SAndroid Build Coastguard Worker }
97*635a8641SAndroid Build Coastguard Worker 
98*635a8641SAndroid Build Coastguard Worker // static
IsHighResolution()99*635a8641SAndroid Build Coastguard Worker bool TimeTicks::IsHighResolution() {
100*635a8641SAndroid Build Coastguard Worker   return true;
101*635a8641SAndroid Build Coastguard Worker }
102*635a8641SAndroid Build Coastguard Worker 
103*635a8641SAndroid Build Coastguard Worker // static
IsConsistentAcrossProcesses()104*635a8641SAndroid Build Coastguard Worker bool TimeTicks::IsConsistentAcrossProcesses() {
105*635a8641SAndroid Build Coastguard Worker   return true;
106*635a8641SAndroid Build Coastguard Worker }
107*635a8641SAndroid Build Coastguard Worker 
108*635a8641SAndroid Build Coastguard Worker // ThreadTicks ----------------------------------------------------------------
109*635a8641SAndroid Build Coastguard Worker 
110*635a8641SAndroid Build Coastguard Worker namespace subtle {
ThreadTicksNowIgnoringOverride()111*635a8641SAndroid Build Coastguard Worker ThreadTicks ThreadTicksNowIgnoringOverride() {
112*635a8641SAndroid Build Coastguard Worker #if (defined(_POSIX_THREAD_CPUTIME) && (_POSIX_THREAD_CPUTIME >= 0)) || \
113*635a8641SAndroid Build Coastguard Worker     defined(OS_ANDROID)
114*635a8641SAndroid Build Coastguard Worker   return ThreadTicks() +
115*635a8641SAndroid Build Coastguard Worker          TimeDelta::FromMicroseconds(ClockNow(CLOCK_THREAD_CPUTIME_ID));
116*635a8641SAndroid Build Coastguard Worker #else
117*635a8641SAndroid Build Coastguard Worker   NOTREACHED();
118*635a8641SAndroid Build Coastguard Worker   return ThreadTicks();
119*635a8641SAndroid Build Coastguard Worker #endif
120*635a8641SAndroid Build Coastguard Worker }
121*635a8641SAndroid Build Coastguard Worker }  // namespace subtle
122*635a8641SAndroid Build Coastguard Worker 
123*635a8641SAndroid Build Coastguard Worker }  // namespace base
124