diff --git a/src/butil/time.cpp b/src/butil/time.cpp index 2c726d9b52..7a1b2a717e 100644 --- a/src/butil/time.cpp +++ b/src/butil/time.cpp @@ -153,6 +153,18 @@ int64_t read_invariant_cpu_frequency() { } int64_t invariant_cpu_freq = -1; + +static void __attribute__((constructor)) init_invariant_cpu_freq() { + int64_t baseFreq = -1; +#if defined(__aarch64__) + __asm__ __volatile__("mrs %0, CNTFRQ_EL0" : "=r"(baseFreq)); +#else + baseFreq = detail::read_invariant_cpu_frequency(); +#endif + + detail::invariant_cpu_freq = baseFreq; +} + } // namespace detail } // namespace butil diff --git a/src/butil/time.h b/src/butil/time.h index c57000ea99..d701979e95 100644 --- a/src/butil/time.h +++ b/src/butil/time.h @@ -279,7 +279,7 @@ extern int64_t invariant_cpu_freq; // note: Inlining shortens time cost per-call for 15ns in a loop of many // calls to this function. inline int64_t cpuwide_time_ns() { -#if !defined(BAIDU_INTERNAL) +#if !defined(BAIDU_INTERNAL) && !defined(__aarch64__) // nearly impossible to get the correct invariant cpu frequency on // different CPU and machines. CPU-ID rarely works and frequencies // in "model name" and "cpu Mhz" are both unreliable. @@ -301,11 +301,6 @@ inline int64_t cpuwide_time_ns() { } else if (!cpu_freq) { // Lack of necessary features, return system-wide monotonic time instead. return monotonic_time_ns(); - } else { - // Use a thread-unsafe method(OK to us) to initialize the freq - // to save a "if" test comparing to using a local static variable - detail::invariant_cpu_freq = detail::read_invariant_cpu_frequency(); - return cpuwide_time_ns(); } #endif // defined(BAIDU_INTERNAL) }