1 // Copyright 2017 The Abseil Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // https://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // The implementation of CycleClock::Frequency. 16 // 17 // NOTE: only i386 and x86_64 have been well tested. 18 // PPC, sparc, alpha, and ia64 are based on 19 // http://peter.kuscsik.com/wordpress/?p=14 20 // with modifications by m3b. See also 21 // https://setisvn.ssl.berkeley.edu/svn/lib/fftw-3.0.1/kernel/cycle.h 22 23 #include "absl/base/internal/cycleclock.h" 24 25 #include <atomic> 26 #include <chrono> // NOLINT(build/c++11) 27 28 #include "absl/base/attributes.h" 29 #include "absl/base/config.h" 30 #include "absl/base/internal/unscaledcycleclock.h" 31 32 namespace absl { 33 ABSL_NAMESPACE_BEGIN 34 namespace base_internal { 35 36 #if ABSL_USE_UNSCALED_CYCLECLOCK 37 38 ABSL_CONST_INIT std::atomic<CycleClockSourceFunc> 39 CycleClock::cycle_clock_source_{nullptr}; 40 Register(CycleClockSourceFunc source)41void CycleClockSource::Register(CycleClockSourceFunc source) { 42 // Corresponds to the load(std::memory_order_acquire) in LoadCycleClockSource. 43 CycleClock::cycle_clock_source_.store(source, std::memory_order_release); 44 } 45 46 #ifdef _WIN32 Now()47int64_t CycleClock::Now() { 48 auto fn = LoadCycleClockSource(); 49 if (fn == nullptr) { 50 return base_internal::UnscaledCycleClock::Now() >> kShift; 51 } 52 return fn() >> kShift; 53 } 54 #endif 55 56 #else 57 58 int64_t CycleClock::Now() { 59 return std::chrono::duration_cast<std::chrono::nanoseconds>( 60 std::chrono::steady_clock::now().time_since_epoch()) 61 .count(); 62 } 63 64 double CycleClock::Frequency() { 65 return 1e9; 66 } 67 68 #endif 69 70 } // namespace base_internal 71 ABSL_NAMESPACE_END 72 } // namespace absl 73