Bruce Dawson | 2af6ef7 | 2018-05-01 15:28:39 +0100 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2018 The Android Open Source Project |
| 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | * you may not use this file except in compliance with the License. |
| 6 | * You may obtain a copy of the License at |
| 7 | * |
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | * |
| 10 | * Unless required by applicable law or agreed to in writing, software |
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | * See the License for the specific language governing permissions and |
| 14 | * limitations under the License. |
| 15 | */ |
| 16 | |
Eric Seckler | 83dcc8c | 2019-08-21 12:18:43 +0100 | [diff] [blame] | 17 | #include "perfetto/base/time.h" |
Primiano Tucci | b730b11 | 2020-12-01 14:56:11 +0100 | [diff] [blame] | 18 | |
Bruce Dawson | 2af6ef7 | 2018-05-01 15:28:39 +0100 | [diff] [blame] | 19 | #include "perfetto/base/build_config.h" |
Primiano Tucci | b730b11 | 2020-12-01 14:56:11 +0100 | [diff] [blame] | 20 | #include "perfetto/base/logging.h" |
Primiano Tucci | 731310e | 2023-10-12 15:53:16 +0100 | [diff] [blame^] | 21 | #include "perfetto/ext/base/string_utils.h" |
Bruce Dawson | 2af6ef7 | 2018-05-01 15:28:39 +0100 | [diff] [blame] | 22 | |
| 23 | #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) |
| 24 | #include <Windows.h> |
Bruce Dawson | 21c1a0d | 2018-05-18 12:01:48 +0100 | [diff] [blame] | 25 | #else |
| 26 | #include <unistd.h> |
| 27 | #endif |
Bruce Dawson | 2af6ef7 | 2018-05-01 15:28:39 +0100 | [diff] [blame] | 28 | |
| 29 | namespace perfetto { |
| 30 | namespace base { |
| 31 | |
Bruce Dawson | 21c1a0d | 2018-05-18 12:01:48 +0100 | [diff] [blame] | 32 | #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) |
| 33 | |
Bruce Dawson | 2af6ef7 | 2018-05-01 15:28:39 +0100 | [diff] [blame] | 34 | TimeNanos GetWallTimeNs() { |
| 35 | LARGE_INTEGER freq; |
| 36 | ::QueryPerformanceFrequency(&freq); |
| 37 | LARGE_INTEGER counter; |
| 38 | ::QueryPerformanceCounter(&counter); |
Primiano Tucci | 42433ab | 2020-11-30 18:42:01 +0100 | [diff] [blame] | 39 | double elapsed_nanoseconds = (1e9 * static_cast<double>(counter.QuadPart)) / |
| 40 | static_cast<double>(freq.QuadPart); |
Bruce Dawson | 2af6ef7 | 2018-05-01 15:28:39 +0100 | [diff] [blame] | 41 | return TimeNanos(static_cast<uint64_t>(elapsed_nanoseconds)); |
| 42 | } |
| 43 | |
| 44 | TimeNanos GetThreadCPUTimeNs() { |
| 45 | FILETIME dummy, kernel_ftime, user_ftime; |
| 46 | ::GetThreadTimes(GetCurrentThread(), &dummy, &dummy, &kernel_ftime, |
| 47 | &user_ftime); |
Hector Dearman | 859d8f8 | 2022-05-10 15:13:45 +0100 | [diff] [blame] | 48 | uint64_t kernel_time = |
| 49 | kernel_ftime.dwHighDateTime * 0x100000000 + kernel_ftime.dwLowDateTime; |
| 50 | uint64_t user_time = |
| 51 | user_ftime.dwHighDateTime * 0x100000000 + user_ftime.dwLowDateTime; |
Bruce Dawson | 2af6ef7 | 2018-05-01 15:28:39 +0100 | [diff] [blame] | 52 | |
| 53 | return TimeNanos((kernel_time + user_time) * 100); |
| 54 | } |
| 55 | |
Bruce Dawson | 21c1a0d | 2018-05-18 12:01:48 +0100 | [diff] [blame] | 56 | void SleepMicroseconds(unsigned interval_us) { |
| 57 | // The Windows Sleep function takes a millisecond count. Round up so that |
| 58 | // short sleeps don't turn into a busy wait. Note that the sleep granularity |
| 59 | // on Windows can dynamically vary from 1 ms to ~16 ms, so don't count on this |
| 60 | // being a short sleep. |
| 61 | ::Sleep(static_cast<DWORD>((interval_us + 999) / 1000)); |
| 62 | } |
| 63 | |
| 64 | #else // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) |
| 65 | |
| 66 | void SleepMicroseconds(unsigned interval_us) { |
| 67 | ::usleep(static_cast<useconds_t>(interval_us)); |
| 68 | } |
Bruce Dawson | 2af6ef7 | 2018-05-01 15:28:39 +0100 | [diff] [blame] | 69 | |
| 70 | #endif // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) |
Bruce Dawson | 21c1a0d | 2018-05-18 12:01:48 +0100 | [diff] [blame] | 71 | |
Primiano Tucci | b730b11 | 2020-12-01 14:56:11 +0100 | [diff] [blame] | 72 | std::string GetTimeFmt(const std::string& fmt) { |
| 73 | time_t raw_time; |
| 74 | time(&raw_time); |
| 75 | struct tm* local_tm; |
| 76 | local_tm = localtime(&raw_time); |
| 77 | char buf[128]; |
| 78 | PERFETTO_CHECK(strftime(buf, 80, fmt.c_str(), local_tm) > 0); |
| 79 | return buf; |
| 80 | } |
| 81 | |
Primiano Tucci | 731310e | 2023-10-12 15:53:16 +0100 | [diff] [blame^] | 82 | std::optional<int32_t> GetTimezoneOffsetMins() { |
| 83 | std::string tz = GetTimeFmt("%z"); |
| 84 | if (tz.size() != 5 || (tz[0] != '+' && tz[0] != '-')) |
| 85 | return std::nullopt; |
| 86 | char sign = '\0'; |
| 87 | int32_t hh = 0; |
| 88 | int32_t mm = 0; |
| 89 | if (sscanf(tz.c_str(), "%c%2d%2d", &sign, &hh, &mm) != 3) |
| 90 | return std::nullopt; |
| 91 | return (hh * 60 + mm) * (sign == '-' ? -1 : 1); |
| 92 | } |
| 93 | |
Bruce Dawson | 21c1a0d | 2018-05-18 12:01:48 +0100 | [diff] [blame] | 94 | } // namespace base |
| 95 | } // namespace perfetto |