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 #ifdef ABSL_INTERNAL_NEED_REDUNDANT_CONSTEXPR_DECL 39 constexpr int32_t CycleClock::kShift; 40 constexpr double CycleClock::kFrequencyScale; 41 #endif 42 43 ABSL_CONST_INIT std::atomic<CycleClockSourceFunc> 44 CycleClock::cycle_clock_source_{nullptr}; 45 Register(CycleClockSourceFunc source)46void CycleClockSource::Register(CycleClockSourceFunc source) { 47 // Corresponds to the load(std::memory_order_acquire) in LoadCycleClockSource. 48 CycleClock::cycle_clock_source_.store(source, std::memory_order_release); 49 } 50 51 #ifdef _WIN32 Now()52int64_t CycleClock::Now() { 53 auto fn = LoadCycleClockSource(); 54 if (fn == nullptr) { 55 return base_internal::UnscaledCycleClock::Now() >> kShift; 56 } 57 return fn() >> kShift; 58 } 59 #endif 60 61 #else 62 63 int64_t CycleClock::Now() { 64 return std::chrono::duration_cast<std::chrono::nanoseconds>( 65 std::chrono::steady_clock::now().time_since_epoch()) 66 .count(); 67 } 68 69 double CycleClock::Frequency() { 70 return 1e9; 71 } 72 73 #endif 74 75 } // namespace base_internal 76 ABSL_NAMESPACE_END 77 } // namespace absl 78