xref: /aosp_15_r20/external/perfetto/src/base/time.cc (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1*6dbdd20aSAndroid Build Coastguard Worker /*
2*6dbdd20aSAndroid Build Coastguard Worker  * Copyright (C) 2018 The Android Open Source Project
3*6dbdd20aSAndroid Build Coastguard Worker  *
4*6dbdd20aSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*6dbdd20aSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*6dbdd20aSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*6dbdd20aSAndroid Build Coastguard Worker  *
8*6dbdd20aSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*6dbdd20aSAndroid Build Coastguard Worker  *
10*6dbdd20aSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*6dbdd20aSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*6dbdd20aSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*6dbdd20aSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*6dbdd20aSAndroid Build Coastguard Worker  * limitations under the License.
15*6dbdd20aSAndroid Build Coastguard Worker  */
16*6dbdd20aSAndroid Build Coastguard Worker 
17*6dbdd20aSAndroid Build Coastguard Worker #include <atomic>
18*6dbdd20aSAndroid Build Coastguard Worker 
19*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/base/time.h"
20*6dbdd20aSAndroid Build Coastguard Worker 
21*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/base/build_config.h"
22*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/base/logging.h"
23*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/ext/base/string_utils.h"
24*6dbdd20aSAndroid Build Coastguard Worker 
25*6dbdd20aSAndroid Build Coastguard Worker #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
26*6dbdd20aSAndroid Build Coastguard Worker #include <Windows.h>
27*6dbdd20aSAndroid Build Coastguard Worker #else
28*6dbdd20aSAndroid Build Coastguard Worker #include <unistd.h>
29*6dbdd20aSAndroid Build Coastguard Worker #endif
30*6dbdd20aSAndroid Build Coastguard Worker 
31*6dbdd20aSAndroid Build Coastguard Worker namespace perfetto {
32*6dbdd20aSAndroid Build Coastguard Worker namespace base {
33*6dbdd20aSAndroid Build Coastguard Worker 
34*6dbdd20aSAndroid Build Coastguard Worker #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
35*6dbdd20aSAndroid Build Coastguard Worker #if !PERFETTO_BUILDFLAG(PERFETTO_ARCH_CPU_ARM64)
36*6dbdd20aSAndroid Build Coastguard Worker namespace {
37*6dbdd20aSAndroid Build Coastguard Worker 
38*6dbdd20aSAndroid Build Coastguard Worker // Returns the current value of the performance counter.
QPCNowRaw()39*6dbdd20aSAndroid Build Coastguard Worker int64_t QPCNowRaw() {
40*6dbdd20aSAndroid Build Coastguard Worker   LARGE_INTEGER perf_counter_now = {};
41*6dbdd20aSAndroid Build Coastguard Worker   // According to the MSDN documentation for QueryPerformanceCounter(), this
42*6dbdd20aSAndroid Build Coastguard Worker   // will never fail on systems that run XP or later.
43*6dbdd20aSAndroid Build Coastguard Worker   // https://msdn.microsoft.com/library/windows/desktop/ms644904.aspx
44*6dbdd20aSAndroid Build Coastguard Worker   ::QueryPerformanceCounter(&perf_counter_now);
45*6dbdd20aSAndroid Build Coastguard Worker   return perf_counter_now.QuadPart;
46*6dbdd20aSAndroid Build Coastguard Worker }
47*6dbdd20aSAndroid Build Coastguard Worker 
TSCTicksPerSecond()48*6dbdd20aSAndroid Build Coastguard Worker double TSCTicksPerSecond() {
49*6dbdd20aSAndroid Build Coastguard Worker   // The value returned by QueryPerformanceFrequency() cannot be used as the TSC
50*6dbdd20aSAndroid Build Coastguard Worker   // frequency, because there is no guarantee that the TSC frequency is equal to
51*6dbdd20aSAndroid Build Coastguard Worker   // the performance counter frequency.
52*6dbdd20aSAndroid Build Coastguard Worker   // The TSC frequency is cached in a static variable because it takes some time
53*6dbdd20aSAndroid Build Coastguard Worker   // to compute it.
54*6dbdd20aSAndroid Build Coastguard Worker   static std::atomic<double> tsc_ticks_per_second = 0;
55*6dbdd20aSAndroid Build Coastguard Worker   double value = tsc_ticks_per_second.load(std::memory_order_relaxed);
56*6dbdd20aSAndroid Build Coastguard Worker   if (value != 0)
57*6dbdd20aSAndroid Build Coastguard Worker     return value;
58*6dbdd20aSAndroid Build Coastguard Worker 
59*6dbdd20aSAndroid Build Coastguard Worker   // Increase the thread priority to reduces the chances of having a context
60*6dbdd20aSAndroid Build Coastguard Worker   // switch during a reading of the TSC and the performance counter.
61*6dbdd20aSAndroid Build Coastguard Worker   const int previous_priority = ::GetThreadPriority(::GetCurrentThread());
62*6dbdd20aSAndroid Build Coastguard Worker   ::SetThreadPriority(::GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
63*6dbdd20aSAndroid Build Coastguard Worker 
64*6dbdd20aSAndroid Build Coastguard Worker   // The first time that this function is called, make an initial reading of the
65*6dbdd20aSAndroid Build Coastguard Worker   // TSC and the performance counter. Initialization of static variable is
66*6dbdd20aSAndroid Build Coastguard Worker   // thread-safe. Threads can race initializing tsc_initial vs
67*6dbdd20aSAndroid Build Coastguard Worker   // perf_counter_initial, although they should be storing very similar values.
68*6dbdd20aSAndroid Build Coastguard Worker 
69*6dbdd20aSAndroid Build Coastguard Worker   static const uint64_t tsc_initial = __rdtsc();
70*6dbdd20aSAndroid Build Coastguard Worker   static const int64_t perf_counter_initial = QPCNowRaw();
71*6dbdd20aSAndroid Build Coastguard Worker 
72*6dbdd20aSAndroid Build Coastguard Worker   // Make a another reading of the TSC and the performance counter every time
73*6dbdd20aSAndroid Build Coastguard Worker   // that this function is called.
74*6dbdd20aSAndroid Build Coastguard Worker   const uint64_t tsc_now = __rdtsc();
75*6dbdd20aSAndroid Build Coastguard Worker   const int64_t perf_counter_now = QPCNowRaw();
76*6dbdd20aSAndroid Build Coastguard Worker 
77*6dbdd20aSAndroid Build Coastguard Worker   // Reset the thread priority.
78*6dbdd20aSAndroid Build Coastguard Worker   ::SetThreadPriority(::GetCurrentThread(), previous_priority);
79*6dbdd20aSAndroid Build Coastguard Worker 
80*6dbdd20aSAndroid Build Coastguard Worker   // Make sure that at least 50 ms elapsed between the 2 readings. The first
81*6dbdd20aSAndroid Build Coastguard Worker   // time that this function is called, we don't expect this to be the case.
82*6dbdd20aSAndroid Build Coastguard Worker   // Note: The longer the elapsed time between the 2 readings is, the more
83*6dbdd20aSAndroid Build Coastguard Worker   //   accurate the computed TSC frequency will be. The 50 ms value was
84*6dbdd20aSAndroid Build Coastguard Worker   //   chosen because local benchmarks show that it allows us to get a
85*6dbdd20aSAndroid Build Coastguard Worker   //   stddev of less than 1 tick/us between multiple runs.
86*6dbdd20aSAndroid Build Coastguard Worker   // Note: According to the MSDN documentation for QueryPerformanceFrequency(),
87*6dbdd20aSAndroid Build Coastguard Worker   //   this will never fail on systems that run XP or later.
88*6dbdd20aSAndroid Build Coastguard Worker   //   https://msdn.microsoft.com/library/windows/desktop/ms644905.aspx
89*6dbdd20aSAndroid Build Coastguard Worker   LARGE_INTEGER perf_counter_frequency = {};
90*6dbdd20aSAndroid Build Coastguard Worker   ::QueryPerformanceFrequency(&perf_counter_frequency);
91*6dbdd20aSAndroid Build Coastguard Worker   PERFETTO_CHECK(perf_counter_now >= perf_counter_initial);
92*6dbdd20aSAndroid Build Coastguard Worker   const int64_t perf_counter_ticks = perf_counter_now - perf_counter_initial;
93*6dbdd20aSAndroid Build Coastguard Worker   const double elapsed_time_seconds =
94*6dbdd20aSAndroid Build Coastguard Worker       static_cast<double>(perf_counter_ticks) /
95*6dbdd20aSAndroid Build Coastguard Worker       static_cast<double>(perf_counter_frequency.QuadPart);
96*6dbdd20aSAndroid Build Coastguard Worker 
97*6dbdd20aSAndroid Build Coastguard Worker   constexpr double kMinimumEvaluationPeriodSeconds = 0.05;
98*6dbdd20aSAndroid Build Coastguard Worker   if (elapsed_time_seconds < kMinimumEvaluationPeriodSeconds)
99*6dbdd20aSAndroid Build Coastguard Worker     return 0;
100*6dbdd20aSAndroid Build Coastguard Worker 
101*6dbdd20aSAndroid Build Coastguard Worker   // Compute the frequency of the TSC.
102*6dbdd20aSAndroid Build Coastguard Worker   PERFETTO_CHECK(tsc_now >= tsc_initial);
103*6dbdd20aSAndroid Build Coastguard Worker   const uint64_t tsc_ticks = tsc_now - tsc_initial;
104*6dbdd20aSAndroid Build Coastguard Worker   // Racing with another thread to write |tsc_ticks_per_second| is benign
105*6dbdd20aSAndroid Build Coastguard Worker   // because both threads will write a valid result.
106*6dbdd20aSAndroid Build Coastguard Worker   tsc_ticks_per_second.store(
107*6dbdd20aSAndroid Build Coastguard Worker       static_cast<double>(tsc_ticks) / elapsed_time_seconds,
108*6dbdd20aSAndroid Build Coastguard Worker       std::memory_order_relaxed);
109*6dbdd20aSAndroid Build Coastguard Worker 
110*6dbdd20aSAndroid Build Coastguard Worker   return tsc_ticks_per_second.load(std::memory_order_relaxed);
111*6dbdd20aSAndroid Build Coastguard Worker }
112*6dbdd20aSAndroid Build Coastguard Worker 
113*6dbdd20aSAndroid Build Coastguard Worker }  // namespace
114*6dbdd20aSAndroid Build Coastguard Worker #endif  // !PERFETTO_BUILDFLAG(PERFETTO_ARCH_CPU_ARM64)
115*6dbdd20aSAndroid Build Coastguard Worker 
GetWallTimeNs()116*6dbdd20aSAndroid Build Coastguard Worker TimeNanos GetWallTimeNs() {
117*6dbdd20aSAndroid Build Coastguard Worker   LARGE_INTEGER freq;
118*6dbdd20aSAndroid Build Coastguard Worker   ::QueryPerformanceFrequency(&freq);
119*6dbdd20aSAndroid Build Coastguard Worker   LARGE_INTEGER counter;
120*6dbdd20aSAndroid Build Coastguard Worker   ::QueryPerformanceCounter(&counter);
121*6dbdd20aSAndroid Build Coastguard Worker   double elapsed_nanoseconds = (1e9 * static_cast<double>(counter.QuadPart)) /
122*6dbdd20aSAndroid Build Coastguard Worker                                static_cast<double>(freq.QuadPart);
123*6dbdd20aSAndroid Build Coastguard Worker   return TimeNanos(static_cast<uint64_t>(elapsed_nanoseconds));
124*6dbdd20aSAndroid Build Coastguard Worker }
125*6dbdd20aSAndroid Build Coastguard Worker 
GetThreadCPUTimeNs()126*6dbdd20aSAndroid Build Coastguard Worker TimeNanos GetThreadCPUTimeNs() {
127*6dbdd20aSAndroid Build Coastguard Worker #if PERFETTO_BUILDFLAG(PERFETTO_ARCH_CPU_ARM64)
128*6dbdd20aSAndroid Build Coastguard Worker   // QueryThreadCycleTime versus TSCTicksPerSecond doesn't have much relation to
129*6dbdd20aSAndroid Build Coastguard Worker   // actual elapsed time on Windows on Arm, because QueryThreadCycleTime is
130*6dbdd20aSAndroid Build Coastguard Worker   // backed by the actual number of CPU cycles executed, rather than a
131*6dbdd20aSAndroid Build Coastguard Worker   // constant-rate timer like Intel. To work around this, use GetThreadTimes
132*6dbdd20aSAndroid Build Coastguard Worker   // (which isn't as accurate but is meaningful as a measure of elapsed
133*6dbdd20aSAndroid Build Coastguard Worker   // per-thread time).
134*6dbdd20aSAndroid Build Coastguard Worker   FILETIME dummy, kernel_ftime, user_ftime;
135*6dbdd20aSAndroid Build Coastguard Worker   ::GetThreadTimes(GetCurrentThread(), &dummy, &dummy, &kernel_ftime,
136*6dbdd20aSAndroid Build Coastguard Worker                    &user_ftime);
137*6dbdd20aSAndroid Build Coastguard Worker   uint64_t kernel_time =
138*6dbdd20aSAndroid Build Coastguard Worker       kernel_ftime.dwHighDateTime * 0x100000000 + kernel_ftime.dwLowDateTime;
139*6dbdd20aSAndroid Build Coastguard Worker   uint64_t user_time =
140*6dbdd20aSAndroid Build Coastguard Worker       user_ftime.dwHighDateTime * 0x100000000 + user_ftime.dwLowDateTime;
141*6dbdd20aSAndroid Build Coastguard Worker 
142*6dbdd20aSAndroid Build Coastguard Worker   return TimeNanos((kernel_time + user_time) * 100);
143*6dbdd20aSAndroid Build Coastguard Worker #else   // !PERFETTO_BUILDFLAG(PERFETTO_ARCH_CPU_ARM64)
144*6dbdd20aSAndroid Build Coastguard Worker   // Get the number of TSC ticks used by the current thread.
145*6dbdd20aSAndroid Build Coastguard Worker   ULONG64 thread_cycle_time = 0;
146*6dbdd20aSAndroid Build Coastguard Worker   ::QueryThreadCycleTime(GetCurrentThread(), &thread_cycle_time);
147*6dbdd20aSAndroid Build Coastguard Worker 
148*6dbdd20aSAndroid Build Coastguard Worker   // Get the frequency of the TSC.
149*6dbdd20aSAndroid Build Coastguard Worker   const double tsc_ticks_per_second = TSCTicksPerSecond();
150*6dbdd20aSAndroid Build Coastguard Worker   if (tsc_ticks_per_second == 0)
151*6dbdd20aSAndroid Build Coastguard Worker     return TimeNanos();
152*6dbdd20aSAndroid Build Coastguard Worker 
153*6dbdd20aSAndroid Build Coastguard Worker   // Return the CPU time of the current thread.
154*6dbdd20aSAndroid Build Coastguard Worker   const double thread_time_seconds =
155*6dbdd20aSAndroid Build Coastguard Worker       static_cast<double>(thread_cycle_time) / tsc_ticks_per_second;
156*6dbdd20aSAndroid Build Coastguard Worker   constexpr int64_t kNanosecondsPerSecond = 1000 * 1000 * 1000;
157*6dbdd20aSAndroid Build Coastguard Worker   return TimeNanos(
158*6dbdd20aSAndroid Build Coastguard Worker       static_cast<int64_t>(thread_time_seconds * kNanosecondsPerSecond));
159*6dbdd20aSAndroid Build Coastguard Worker #endif  // !PERFETTO_BUILDFLAG(PERFETTO_ARCH_CPU_ARM64)
160*6dbdd20aSAndroid Build Coastguard Worker }
161*6dbdd20aSAndroid Build Coastguard Worker 
SleepMicroseconds(unsigned interval_us)162*6dbdd20aSAndroid Build Coastguard Worker void SleepMicroseconds(unsigned interval_us) {
163*6dbdd20aSAndroid Build Coastguard Worker   // The Windows Sleep function takes a millisecond count. Round up so that
164*6dbdd20aSAndroid Build Coastguard Worker   // short sleeps don't turn into a busy wait. Note that the sleep granularity
165*6dbdd20aSAndroid Build Coastguard Worker   // on Windows can dynamically vary from 1 ms to ~16 ms, so don't count on this
166*6dbdd20aSAndroid Build Coastguard Worker   // being a short sleep.
167*6dbdd20aSAndroid Build Coastguard Worker   ::Sleep(static_cast<DWORD>((interval_us + 999) / 1000));
168*6dbdd20aSAndroid Build Coastguard Worker }
169*6dbdd20aSAndroid Build Coastguard Worker 
InitializeTime()170*6dbdd20aSAndroid Build Coastguard Worker void InitializeTime() {
171*6dbdd20aSAndroid Build Coastguard Worker #if !PERFETTO_BUILDFLAG(PERFETTO_ARCH_CPU_ARM64)
172*6dbdd20aSAndroid Build Coastguard Worker   // Make an early first call to TSCTicksPerSecond() to start 50 ms elapsed time
173*6dbdd20aSAndroid Build Coastguard Worker   // (see comment in TSCTicksPerSecond()).
174*6dbdd20aSAndroid Build Coastguard Worker   TSCTicksPerSecond();
175*6dbdd20aSAndroid Build Coastguard Worker #endif  // !PERFETTO_BUILDFLAG(PERFETTO_ARCH_CPU_ARM64)
176*6dbdd20aSAndroid Build Coastguard Worker }
177*6dbdd20aSAndroid Build Coastguard Worker 
178*6dbdd20aSAndroid Build Coastguard Worker #else  // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
179*6dbdd20aSAndroid Build Coastguard Worker 
180*6dbdd20aSAndroid Build Coastguard Worker void SleepMicroseconds(unsigned interval_us) {
181*6dbdd20aSAndroid Build Coastguard Worker   ::usleep(static_cast<useconds_t>(interval_us));
182*6dbdd20aSAndroid Build Coastguard Worker }
183*6dbdd20aSAndroid Build Coastguard Worker 
184*6dbdd20aSAndroid Build Coastguard Worker void InitializeTime() {}
185*6dbdd20aSAndroid Build Coastguard Worker 
186*6dbdd20aSAndroid Build Coastguard Worker #endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
187*6dbdd20aSAndroid Build Coastguard Worker 
GetTimeFmt(const std::string & fmt)188*6dbdd20aSAndroid Build Coastguard Worker std::string GetTimeFmt(const std::string& fmt) {
189*6dbdd20aSAndroid Build Coastguard Worker   time_t raw_time;
190*6dbdd20aSAndroid Build Coastguard Worker   time(&raw_time);
191*6dbdd20aSAndroid Build Coastguard Worker   struct tm local_tm;
192*6dbdd20aSAndroid Build Coastguard Worker #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
193*6dbdd20aSAndroid Build Coastguard Worker   PERFETTO_CHECK(localtime_s(&local_tm, &raw_time) == 0);
194*6dbdd20aSAndroid Build Coastguard Worker #else
195*6dbdd20aSAndroid Build Coastguard Worker   tzset();
196*6dbdd20aSAndroid Build Coastguard Worker   PERFETTO_CHECK(localtime_r(&raw_time, &local_tm) != nullptr);
197*6dbdd20aSAndroid Build Coastguard Worker #endif
198*6dbdd20aSAndroid Build Coastguard Worker   char buf[128];
199*6dbdd20aSAndroid Build Coastguard Worker   PERFETTO_CHECK(strftime(buf, 80, fmt.c_str(), &local_tm) > 0);
200*6dbdd20aSAndroid Build Coastguard Worker   return buf;
201*6dbdd20aSAndroid Build Coastguard Worker }
202*6dbdd20aSAndroid Build Coastguard Worker 
GetTimezoneOffsetMins()203*6dbdd20aSAndroid Build Coastguard Worker std::optional<int32_t> GetTimezoneOffsetMins() {
204*6dbdd20aSAndroid Build Coastguard Worker   std::string tz = GetTimeFmt("%z");
205*6dbdd20aSAndroid Build Coastguard Worker   if (tz.size() != 5 || (tz[0] != '+' && tz[0] != '-'))
206*6dbdd20aSAndroid Build Coastguard Worker     return std::nullopt;
207*6dbdd20aSAndroid Build Coastguard Worker   char sign = '\0';
208*6dbdd20aSAndroid Build Coastguard Worker   int32_t hh = 0;
209*6dbdd20aSAndroid Build Coastguard Worker   int32_t mm = 0;
210*6dbdd20aSAndroid Build Coastguard Worker   if (sscanf(tz.c_str(), "%c%2d%2d", &sign, &hh, &mm) != 3)
211*6dbdd20aSAndroid Build Coastguard Worker     return std::nullopt;
212*6dbdd20aSAndroid Build Coastguard Worker   return (hh * 60 + mm) * (sign == '-' ? -1 : 1);
213*6dbdd20aSAndroid Build Coastguard Worker }
214*6dbdd20aSAndroid Build Coastguard Worker 
215*6dbdd20aSAndroid Build Coastguard Worker }  // namespace base
216*6dbdd20aSAndroid Build Coastguard Worker }  // namespace perfetto
217