1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2015 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker *
4*795d594fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker *
8*795d594fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker *
10*795d594fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker */
16*795d594fSAndroid Build Coastguard Worker
17*795d594fSAndroid Build Coastguard Worker #define _POSIX_THREAD_SAFE_FUNCTIONS // For mingw localtime_r().
18*795d594fSAndroid Build Coastguard Worker
19*795d594fSAndroid Build Coastguard Worker #include "time_utils.h"
20*795d594fSAndroid Build Coastguard Worker
21*795d594fSAndroid Build Coastguard Worker #include <inttypes.h>
22*795d594fSAndroid Build Coastguard Worker #include <stdio.h>
23*795d594fSAndroid Build Coastguard Worker
24*795d594fSAndroid Build Coastguard Worker #include <limits>
25*795d594fSAndroid Build Coastguard Worker #include <sstream>
26*795d594fSAndroid Build Coastguard Worker
27*795d594fSAndroid Build Coastguard Worker #include "android-base/stringprintf.h"
28*795d594fSAndroid Build Coastguard Worker
29*795d594fSAndroid Build Coastguard Worker #include "logging.h"
30*795d594fSAndroid Build Coastguard Worker
31*795d594fSAndroid Build Coastguard Worker #if defined(__APPLE__)
32*795d594fSAndroid Build Coastguard Worker #include <sys/time.h>
33*795d594fSAndroid Build Coastguard Worker #endif
34*795d594fSAndroid Build Coastguard Worker
35*795d594fSAndroid Build Coastguard Worker namespace art {
36*795d594fSAndroid Build Coastguard Worker
37*795d594fSAndroid Build Coastguard Worker namespace {
38*795d594fSAndroid Build Coastguard Worker
39*795d594fSAndroid Build Coastguard Worker #if !defined(__linux__)
GetTimeOfDay(struct timeval * tv,struct timezone * tz)40*795d594fSAndroid Build Coastguard Worker int GetTimeOfDay(struct timeval* tv, struct timezone* tz) {
41*795d594fSAndroid Build Coastguard Worker #ifdef _WIN32
42*795d594fSAndroid Build Coastguard Worker return mingw_gettimeofday(tv, tz);
43*795d594fSAndroid Build Coastguard Worker #else
44*795d594fSAndroid Build Coastguard Worker return gettimeofday(tv, tz);
45*795d594fSAndroid Build Coastguard Worker #endif
46*795d594fSAndroid Build Coastguard Worker }
47*795d594fSAndroid Build Coastguard Worker #endif
48*795d594fSAndroid Build Coastguard Worker
49*795d594fSAndroid Build Coastguard Worker } // namespace
50*795d594fSAndroid Build Coastguard Worker
51*795d594fSAndroid Build Coastguard Worker using android::base::StringPrintf;
52*795d594fSAndroid Build Coastguard Worker
PrettyDuration(uint64_t nano_duration,size_t max_fraction_digits)53*795d594fSAndroid Build Coastguard Worker std::string PrettyDuration(uint64_t nano_duration, size_t max_fraction_digits) {
54*795d594fSAndroid Build Coastguard Worker if (nano_duration == 0) {
55*795d594fSAndroid Build Coastguard Worker return "0";
56*795d594fSAndroid Build Coastguard Worker } else {
57*795d594fSAndroid Build Coastguard Worker return FormatDuration(nano_duration, GetAppropriateTimeUnit(nano_duration),
58*795d594fSAndroid Build Coastguard Worker max_fraction_digits);
59*795d594fSAndroid Build Coastguard Worker }
60*795d594fSAndroid Build Coastguard Worker }
61*795d594fSAndroid Build Coastguard Worker
GetAppropriateTimeUnit(uint64_t nano_duration)62*795d594fSAndroid Build Coastguard Worker TimeUnit GetAppropriateTimeUnit(uint64_t nano_duration) {
63*795d594fSAndroid Build Coastguard Worker const uint64_t one_sec = 1000 * 1000 * 1000;
64*795d594fSAndroid Build Coastguard Worker const uint64_t one_ms = 1000 * 1000;
65*795d594fSAndroid Build Coastguard Worker const uint64_t one_us = 1000;
66*795d594fSAndroid Build Coastguard Worker if (nano_duration >= one_sec) {
67*795d594fSAndroid Build Coastguard Worker return kTimeUnitSecond;
68*795d594fSAndroid Build Coastguard Worker } else if (nano_duration >= one_ms) {
69*795d594fSAndroid Build Coastguard Worker return kTimeUnitMillisecond;
70*795d594fSAndroid Build Coastguard Worker } else if (nano_duration >= one_us) {
71*795d594fSAndroid Build Coastguard Worker return kTimeUnitMicrosecond;
72*795d594fSAndroid Build Coastguard Worker } else {
73*795d594fSAndroid Build Coastguard Worker return kTimeUnitNanosecond;
74*795d594fSAndroid Build Coastguard Worker }
75*795d594fSAndroid Build Coastguard Worker }
76*795d594fSAndroid Build Coastguard Worker
GetNsToTimeUnitDivisor(TimeUnit time_unit)77*795d594fSAndroid Build Coastguard Worker uint64_t GetNsToTimeUnitDivisor(TimeUnit time_unit) {
78*795d594fSAndroid Build Coastguard Worker const uint64_t one_sec = 1000 * 1000 * 1000;
79*795d594fSAndroid Build Coastguard Worker const uint64_t one_ms = 1000 * 1000;
80*795d594fSAndroid Build Coastguard Worker const uint64_t one_us = 1000;
81*795d594fSAndroid Build Coastguard Worker
82*795d594fSAndroid Build Coastguard Worker switch (time_unit) {
83*795d594fSAndroid Build Coastguard Worker case kTimeUnitSecond:
84*795d594fSAndroid Build Coastguard Worker return one_sec;
85*795d594fSAndroid Build Coastguard Worker case kTimeUnitMillisecond:
86*795d594fSAndroid Build Coastguard Worker return one_ms;
87*795d594fSAndroid Build Coastguard Worker case kTimeUnitMicrosecond:
88*795d594fSAndroid Build Coastguard Worker return one_us;
89*795d594fSAndroid Build Coastguard Worker case kTimeUnitNanosecond:
90*795d594fSAndroid Build Coastguard Worker return 1;
91*795d594fSAndroid Build Coastguard Worker }
92*795d594fSAndroid Build Coastguard Worker return 0;
93*795d594fSAndroid Build Coastguard Worker }
94*795d594fSAndroid Build Coastguard Worker
FormatDuration(uint64_t nano_duration,TimeUnit time_unit,size_t max_fraction_digits)95*795d594fSAndroid Build Coastguard Worker std::string FormatDuration(uint64_t nano_duration, TimeUnit time_unit,
96*795d594fSAndroid Build Coastguard Worker size_t max_fraction_digits) {
97*795d594fSAndroid Build Coastguard Worker const char* unit = nullptr;
98*795d594fSAndroid Build Coastguard Worker uint64_t divisor = GetNsToTimeUnitDivisor(time_unit);
99*795d594fSAndroid Build Coastguard Worker switch (time_unit) {
100*795d594fSAndroid Build Coastguard Worker case kTimeUnitSecond:
101*795d594fSAndroid Build Coastguard Worker unit = "s";
102*795d594fSAndroid Build Coastguard Worker break;
103*795d594fSAndroid Build Coastguard Worker case kTimeUnitMillisecond:
104*795d594fSAndroid Build Coastguard Worker unit = "ms";
105*795d594fSAndroid Build Coastguard Worker break;
106*795d594fSAndroid Build Coastguard Worker case kTimeUnitMicrosecond:
107*795d594fSAndroid Build Coastguard Worker unit = "us";
108*795d594fSAndroid Build Coastguard Worker break;
109*795d594fSAndroid Build Coastguard Worker case kTimeUnitNanosecond:
110*795d594fSAndroid Build Coastguard Worker unit = "ns";
111*795d594fSAndroid Build Coastguard Worker break;
112*795d594fSAndroid Build Coastguard Worker }
113*795d594fSAndroid Build Coastguard Worker const uint64_t whole_part = nano_duration / divisor;
114*795d594fSAndroid Build Coastguard Worker uint64_t fractional_part = nano_duration % divisor;
115*795d594fSAndroid Build Coastguard Worker if (fractional_part == 0) {
116*795d594fSAndroid Build Coastguard Worker return StringPrintf("%" PRIu64 "%s", whole_part, unit);
117*795d594fSAndroid Build Coastguard Worker } else {
118*795d594fSAndroid Build Coastguard Worker static constexpr size_t kMaxDigits = 30;
119*795d594fSAndroid Build Coastguard Worker size_t avail_digits = kMaxDigits;
120*795d594fSAndroid Build Coastguard Worker char fraction_buffer[kMaxDigits];
121*795d594fSAndroid Build Coastguard Worker char* ptr = fraction_buffer;
122*795d594fSAndroid Build Coastguard Worker uint64_t multiplier = 10;
123*795d594fSAndroid Build Coastguard Worker // This infinite loops if fractional part is 0.
124*795d594fSAndroid Build Coastguard Worker while (avail_digits > 1 && fractional_part * multiplier < divisor) {
125*795d594fSAndroid Build Coastguard Worker multiplier *= 10;
126*795d594fSAndroid Build Coastguard Worker *ptr++ = '0';
127*795d594fSAndroid Build Coastguard Worker avail_digits--;
128*795d594fSAndroid Build Coastguard Worker }
129*795d594fSAndroid Build Coastguard Worker snprintf(ptr, avail_digits, "%" PRIu64, fractional_part);
130*795d594fSAndroid Build Coastguard Worker fraction_buffer[std::min(kMaxDigits - 1, max_fraction_digits)] = '\0';
131*795d594fSAndroid Build Coastguard Worker return StringPrintf("%" PRIu64 ".%s%s", whole_part, fraction_buffer, unit);
132*795d594fSAndroid Build Coastguard Worker }
133*795d594fSAndroid Build Coastguard Worker }
134*795d594fSAndroid Build Coastguard Worker
GetIsoDate()135*795d594fSAndroid Build Coastguard Worker std::string GetIsoDate() {
136*795d594fSAndroid Build Coastguard Worker tm tmbuf;
137*795d594fSAndroid Build Coastguard Worker int ns;
138*795d594fSAndroid Build Coastguard Worker if (__builtin_available(macOS 10.12, *)) {
139*795d594fSAndroid Build Coastguard Worker timespec now;
140*795d594fSAndroid Build Coastguard Worker clock_gettime(CLOCK_REALTIME, &now);
141*795d594fSAndroid Build Coastguard Worker localtime_r(&now.tv_sec, &tmbuf);
142*795d594fSAndroid Build Coastguard Worker ns = now.tv_nsec;
143*795d594fSAndroid Build Coastguard Worker } else {
144*795d594fSAndroid Build Coastguard Worker time_t now = time(nullptr);
145*795d594fSAndroid Build Coastguard Worker localtime_r(&now, &tmbuf);
146*795d594fSAndroid Build Coastguard Worker ns = 0;
147*795d594fSAndroid Build Coastguard Worker }
148*795d594fSAndroid Build Coastguard Worker char zone[16] = {};
149*795d594fSAndroid Build Coastguard Worker strftime(zone, sizeof(zone), "%z", &tmbuf);
150*795d594fSAndroid Build Coastguard Worker return StringPrintf("%04d-%02d-%02d %02d:%02d:%02d.%09d%s",
151*795d594fSAndroid Build Coastguard Worker tmbuf.tm_year + 1900, tmbuf.tm_mon+1, tmbuf.tm_mday,
152*795d594fSAndroid Build Coastguard Worker tmbuf.tm_hour, tmbuf.tm_min, tmbuf.tm_sec, ns, zone);
153*795d594fSAndroid Build Coastguard Worker }
154*795d594fSAndroid Build Coastguard Worker
MilliTime()155*795d594fSAndroid Build Coastguard Worker uint64_t MilliTime() {
156*795d594fSAndroid Build Coastguard Worker #if defined(__linux__)
157*795d594fSAndroid Build Coastguard Worker timespec now;
158*795d594fSAndroid Build Coastguard Worker clock_gettime(CLOCK_MONOTONIC, &now);
159*795d594fSAndroid Build Coastguard Worker return static_cast<uint64_t>(now.tv_sec) * UINT64_C(1000) + now.tv_nsec / UINT64_C(1000000);
160*795d594fSAndroid Build Coastguard Worker #else
161*795d594fSAndroid Build Coastguard Worker timeval now;
162*795d594fSAndroid Build Coastguard Worker GetTimeOfDay(&now, nullptr);
163*795d594fSAndroid Build Coastguard Worker return static_cast<uint64_t>(now.tv_sec) * UINT64_C(1000) + now.tv_usec / UINT64_C(1000);
164*795d594fSAndroid Build Coastguard Worker #endif
165*795d594fSAndroid Build Coastguard Worker }
166*795d594fSAndroid Build Coastguard Worker
MicroTime()167*795d594fSAndroid Build Coastguard Worker uint64_t MicroTime() {
168*795d594fSAndroid Build Coastguard Worker #if defined(__linux__)
169*795d594fSAndroid Build Coastguard Worker timespec now;
170*795d594fSAndroid Build Coastguard Worker clock_gettime(CLOCK_MONOTONIC, &now);
171*795d594fSAndroid Build Coastguard Worker return static_cast<uint64_t>(now.tv_sec) * UINT64_C(1000000) + now.tv_nsec / UINT64_C(1000);
172*795d594fSAndroid Build Coastguard Worker #else
173*795d594fSAndroid Build Coastguard Worker timeval now;
174*795d594fSAndroid Build Coastguard Worker GetTimeOfDay(&now, nullptr);
175*795d594fSAndroid Build Coastguard Worker return static_cast<uint64_t>(now.tv_sec) * UINT64_C(1000000) + now.tv_usec;
176*795d594fSAndroid Build Coastguard Worker #endif
177*795d594fSAndroid Build Coastguard Worker }
178*795d594fSAndroid Build Coastguard Worker
NanoTime()179*795d594fSAndroid Build Coastguard Worker uint64_t NanoTime() {
180*795d594fSAndroid Build Coastguard Worker #if defined(__linux__)
181*795d594fSAndroid Build Coastguard Worker timespec now;
182*795d594fSAndroid Build Coastguard Worker clock_gettime(CLOCK_MONOTONIC, &now);
183*795d594fSAndroid Build Coastguard Worker return static_cast<uint64_t>(now.tv_sec) * UINT64_C(1000000000) + now.tv_nsec;
184*795d594fSAndroid Build Coastguard Worker #else
185*795d594fSAndroid Build Coastguard Worker timeval now;
186*795d594fSAndroid Build Coastguard Worker GetTimeOfDay(&now, nullptr);
187*795d594fSAndroid Build Coastguard Worker return static_cast<uint64_t>(now.tv_sec) * UINT64_C(1000000000) + now.tv_usec * UINT64_C(1000);
188*795d594fSAndroid Build Coastguard Worker #endif
189*795d594fSAndroid Build Coastguard Worker }
190*795d594fSAndroid Build Coastguard Worker
ThreadCpuNanoTime()191*795d594fSAndroid Build Coastguard Worker uint64_t ThreadCpuNanoTime() {
192*795d594fSAndroid Build Coastguard Worker #if defined(__linux__)
193*795d594fSAndroid Build Coastguard Worker timespec now;
194*795d594fSAndroid Build Coastguard Worker clock_gettime(CLOCK_THREAD_CPUTIME_ID, &now);
195*795d594fSAndroid Build Coastguard Worker return static_cast<uint64_t>(now.tv_sec) * UINT64_C(1000000000) + now.tv_nsec;
196*795d594fSAndroid Build Coastguard Worker #else
197*795d594fSAndroid Build Coastguard Worker UNIMPLEMENTED(WARNING);
198*795d594fSAndroid Build Coastguard Worker return -1;
199*795d594fSAndroid Build Coastguard Worker #endif
200*795d594fSAndroid Build Coastguard Worker }
201*795d594fSAndroid Build Coastguard Worker
ProcessCpuNanoTime()202*795d594fSAndroid Build Coastguard Worker uint64_t ProcessCpuNanoTime() {
203*795d594fSAndroid Build Coastguard Worker #if defined(__linux__)
204*795d594fSAndroid Build Coastguard Worker timespec now;
205*795d594fSAndroid Build Coastguard Worker clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &now);
206*795d594fSAndroid Build Coastguard Worker return static_cast<uint64_t>(now.tv_sec) * UINT64_C(1000000000) + now.tv_nsec;
207*795d594fSAndroid Build Coastguard Worker #else
208*795d594fSAndroid Build Coastguard Worker // We cannot use clock_gettime() here. Return the process wall clock time
209*795d594fSAndroid Build Coastguard Worker // (using art::NanoTime, which relies on gettimeofday()) as approximation of
210*795d594fSAndroid Build Coastguard Worker // the process CPU time instead.
211*795d594fSAndroid Build Coastguard Worker //
212*795d594fSAndroid Build Coastguard Worker // Note: clock_gettime() is available from macOS 10.12 (Darwin 16), but we try
213*795d594fSAndroid Build Coastguard Worker // to keep things simple here.
214*795d594fSAndroid Build Coastguard Worker return NanoTime();
215*795d594fSAndroid Build Coastguard Worker #endif
216*795d594fSAndroid Build Coastguard Worker }
217*795d594fSAndroid Build Coastguard Worker
NanoSleep(uint64_t ns)218*795d594fSAndroid Build Coastguard Worker void NanoSleep(uint64_t ns) {
219*795d594fSAndroid Build Coastguard Worker timespec tm;
220*795d594fSAndroid Build Coastguard Worker tm.tv_sec = SaturatedTimeT(ns / MsToNs(1000));
221*795d594fSAndroid Build Coastguard Worker tm.tv_nsec = ns - static_cast<uint64_t>(tm.tv_sec) * MsToNs(1000);
222*795d594fSAndroid Build Coastguard Worker nanosleep(&tm, nullptr);
223*795d594fSAndroid Build Coastguard Worker }
224*795d594fSAndroid Build Coastguard Worker
InitTimeSpec(bool absolute,int clock,int64_t ms,int32_t ns,timespec * ts)225*795d594fSAndroid Build Coastguard Worker void InitTimeSpec(bool absolute, int clock, int64_t ms, int32_t ns, timespec* ts) {
226*795d594fSAndroid Build Coastguard Worker if (absolute) {
227*795d594fSAndroid Build Coastguard Worker #if defined(__linux__)
228*795d594fSAndroid Build Coastguard Worker clock_gettime(clock, ts);
229*795d594fSAndroid Build Coastguard Worker #else
230*795d594fSAndroid Build Coastguard Worker UNUSED(clock);
231*795d594fSAndroid Build Coastguard Worker timeval tv;
232*795d594fSAndroid Build Coastguard Worker GetTimeOfDay(&tv, nullptr);
233*795d594fSAndroid Build Coastguard Worker ts->tv_sec = tv.tv_sec;
234*795d594fSAndroid Build Coastguard Worker ts->tv_nsec = tv.tv_usec * 1000;
235*795d594fSAndroid Build Coastguard Worker #endif
236*795d594fSAndroid Build Coastguard Worker } else {
237*795d594fSAndroid Build Coastguard Worker ts->tv_sec = 0;
238*795d594fSAndroid Build Coastguard Worker ts->tv_nsec = 0;
239*795d594fSAndroid Build Coastguard Worker }
240*795d594fSAndroid Build Coastguard Worker
241*795d594fSAndroid Build Coastguard Worker int64_t end_sec = ts->tv_sec + ms / 1000;
242*795d594fSAndroid Build Coastguard Worker constexpr int32_t int32_max = std::numeric_limits<int32_t>::max();
243*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(end_sec >= int32_max)) {
244*795d594fSAndroid Build Coastguard Worker // Either ms was intended to denote an infinite timeout, or we have a
245*795d594fSAndroid Build Coastguard Worker // problem. The former generally uses the largest possible millisecond
246*795d594fSAndroid Build Coastguard Worker // or nanosecond value. Log only in the latter case.
247*795d594fSAndroid Build Coastguard Worker constexpr int64_t int64_max = std::numeric_limits<int64_t>::max();
248*795d594fSAndroid Build Coastguard Worker if (ms != int64_max && ms != int64_max / (1000 * 1000)) {
249*795d594fSAndroid Build Coastguard Worker LOG(INFO) << "Note: end time exceeds INT32_MAX: " << end_sec;
250*795d594fSAndroid Build Coastguard Worker }
251*795d594fSAndroid Build Coastguard Worker end_sec = int32_max - 1; // Allow for increment below.
252*795d594fSAndroid Build Coastguard Worker }
253*795d594fSAndroid Build Coastguard Worker ts->tv_sec = end_sec;
254*795d594fSAndroid Build Coastguard Worker ts->tv_nsec = (ts->tv_nsec + (ms % 1000) * 1000000) + ns;
255*795d594fSAndroid Build Coastguard Worker
256*795d594fSAndroid Build Coastguard Worker // Catch rollover.
257*795d594fSAndroid Build Coastguard Worker if (ts->tv_nsec >= 1000000000L) {
258*795d594fSAndroid Build Coastguard Worker ts->tv_sec++;
259*795d594fSAndroid Build Coastguard Worker ts->tv_nsec -= 1000000000L;
260*795d594fSAndroid Build Coastguard Worker }
261*795d594fSAndroid Build Coastguard Worker }
262*795d594fSAndroid Build Coastguard Worker
263*795d594fSAndroid Build Coastguard Worker } // namespace art
264