00001 // Copyright 2017 The Abseil Authors. 00002 // 00003 // Licensed under the Apache License, Version 2.0 (the "License"); 00004 // you may not use this file except in compliance with the License. 00005 // You may obtain a copy of the License at 00006 // 00007 // https://www.apache.org/licenses/LICENSE-2.0 00008 // 00009 // Unless required by applicable law or agreed to in writing, software 00010 // distributed under the License is distributed on an "AS IS" BASIS, 00011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00012 // See the License for the specific language governing permissions and 00013 // limitations under the License. 00014 // 00015 // UnscaledCycleClock 00016 // An UnscaledCycleClock yields the value and frequency of a cycle counter 00017 // that increments at a rate that is approximately constant. 00018 // This class is for internal / whitelisted use only, you should consider 00019 // using CycleClock instead. 00020 // 00021 // Notes: 00022 // The cycle counter frequency is not necessarily the core clock frequency. 00023 // That is, CycleCounter cycles are not necessarily "CPU cycles". 00024 // 00025 // An arbitrary offset may have been added to the counter at power on. 00026 // 00027 // On some platforms, the rate and offset of the counter may differ 00028 // slightly when read from different CPUs of a multiprocessor. Usually, 00029 // we try to ensure that the operating system adjusts values periodically 00030 // so that values agree approximately. If you need stronger guarantees, 00031 // consider using alternate interfaces. 00032 // 00033 // The CPU is not required to maintain the ordering of a cycle counter read 00034 // with respect to surrounding instructions. 00035 00036 #ifndef ABSL_BASE_INTERNAL_UNSCALEDCYCLECLOCK_H_ 00037 #define ABSL_BASE_INTERNAL_UNSCALEDCYCLECLOCK_H_ 00038 00039 #include <cstdint> 00040 00041 #if defined(__APPLE__) 00042 #include <TargetConditionals.h> 00043 #endif 00044 00045 #include "absl/base/port.h" 00046 00047 // The following platforms have an implementation of a hardware counter. 00048 #if defined(__i386__) || defined(__x86_64__) || defined(__aarch64__) || \ 00049 defined(__powerpc__) || defined(__ppc__) || \ 00050 defined(_M_IX86) || defined(_M_X64) 00051 #define ABSL_HAVE_UNSCALED_CYCLECLOCK_IMPLEMENTATION 1 00052 #else 00053 #define ABSL_HAVE_UNSCALED_CYCLECLOCK_IMPLEMENTATION 0 00054 #endif 00055 00056 // The following platforms often disable access to the hardware 00057 // counter (through a sandbox) even if the underlying hardware has a 00058 // usable counter. The CycleTimer interface also requires a *scaled* 00059 // CycleClock that runs at atleast 1 MHz. We've found some Android 00060 // ARM64 devices where this is not the case, so we disable it by 00061 // default on Android ARM64. 00062 #if defined(__native_client__) || \ 00063 (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) || \ 00064 (defined(__ANDROID__) && defined(__aarch64__)) 00065 #define ABSL_USE_UNSCALED_CYCLECLOCK_DEFAULT 0 00066 #else 00067 #define ABSL_USE_UNSCALED_CYCLECLOCK_DEFAULT 1 00068 #endif 00069 00070 // UnscaledCycleClock is an optional internal feature. 00071 // Use "#if ABSL_USE_UNSCALED_CYCLECLOCK" to test for its presence. 00072 // Can be overridden at compile-time via -DABSL_USE_UNSCALED_CYCLECLOCK=0|1 00073 #if !defined(ABSL_USE_UNSCALED_CYCLECLOCK) 00074 #define ABSL_USE_UNSCALED_CYCLECLOCK \ 00075 (ABSL_HAVE_UNSCALED_CYCLECLOCK_IMPLEMENTATION && \ 00076 ABSL_USE_UNSCALED_CYCLECLOCK_DEFAULT) 00077 #endif 00078 00079 #if ABSL_USE_UNSCALED_CYCLECLOCK 00080 00081 // This macro can be used to test if UnscaledCycleClock::Frequency() 00082 // is NominalCPUFrequency() on a particular platform. 00083 #if (defined(__i386__) || defined(__x86_64__) || \ 00084 defined(_M_IX86) || defined(_M_X64)) 00085 #define ABSL_INTERNAL_UNSCALED_CYCLECLOCK_FREQUENCY_IS_CPU_FREQUENCY 00086 #endif 00087 00088 namespace absl { 00089 namespace time_internal { 00090 class UnscaledCycleClockWrapperForGetCurrentTime; 00091 } // namespace time_internal 00092 00093 namespace base_internal { 00094 class CycleClock; 00095 class UnscaledCycleClockWrapperForInitializeFrequency; 00096 00097 class UnscaledCycleClock { 00098 private: 00099 UnscaledCycleClock() = delete; 00100 00101 // Return the value of a cycle counter that counts at a rate that is 00102 // approximately constant. 00103 static int64_t Now(); 00104 00105 // Return the how much UnscaledCycleClock::Now() increases per second. 00106 // This is not necessarily the core CPU clock frequency. 00107 // It may be the nominal value report by the kernel, rather than a measured 00108 // value. 00109 static double Frequency(); 00110 00111 // Whitelisted friends. 00112 friend class base_internal::CycleClock; 00113 friend class time_internal::UnscaledCycleClockWrapperForGetCurrentTime; 00114 friend class base_internal::UnscaledCycleClockWrapperForInitializeFrequency; 00115 }; 00116 00117 } // namespace base_internal 00118 } // namespace absl 00119 00120 #endif // ABSL_USE_UNSCALED_CYCLECLOCK 00121 00122 #endif // ABSL_BASE_INTERNAL_UNSCALEDCYCLECLOCK_H_