xref: /aosp_15_r20/external/cronet/base/time/time_now_posix.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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 Worker int64_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 Worker int64_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 Worker std::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 Worker Time 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 Worker Time 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 Worker TimeTicks 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 Worker std::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 Worker TimeTicks::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 Worker bool 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 Worker bool 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 Worker ThreadTicks 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