diff options
Diffstat (limited to 'absl/base/internal')
-rw-r--r-- | absl/base/internal/cycleclock.cc | 12 | ||||
-rw-r--r-- | absl/base/internal/cycleclock.h | 14 | ||||
-rw-r--r-- | absl/base/internal/per_thread_tls.h | 12 |
3 files changed, 33 insertions, 5 deletions
diff --git a/absl/base/internal/cycleclock.cc b/absl/base/internal/cycleclock.cc index a742df01f94a..9eb13b8cb8c0 100644 --- a/absl/base/internal/cycleclock.cc +++ b/absl/base/internal/cycleclock.cc @@ -22,6 +22,7 @@ #include "absl/base/internal/cycleclock.h" +#include <atomic> #include <chrono> // NOLINT(build/c++11) #include "absl/base/internal/unscaledcycleclock.h" @@ -52,17 +53,26 @@ static constexpr int32_t kShift = 2; #endif static constexpr double kFrequencyScale = 1.0 / (1 << kShift); +static std::atomic<CycleClockSourceFunc> cycle_clock_source; } // namespace int64_t CycleClock::Now() { - return base_internal::UnscaledCycleClock::Now() >> kShift; + auto fn = cycle_clock_source.load(std::memory_order_relaxed); + if (fn == nullptr) { + return base_internal::UnscaledCycleClock::Now() >> kShift; + } + return fn() >> kShift; } double CycleClock::Frequency() { return kFrequencyScale * base_internal::UnscaledCycleClock::Frequency(); } +void CycleClockSource::Register(CycleClockSourceFunc source) { + cycle_clock_source.store(source, std::memory_order_relaxed); +} + #else int64_t CycleClock::Now() { diff --git a/absl/base/internal/cycleclock.h b/absl/base/internal/cycleclock.h index 60e971583c57..9853a66cefa6 100644 --- a/absl/base/internal/cycleclock.h +++ b/absl/base/internal/cycleclock.h @@ -71,6 +71,20 @@ class CycleClock { CycleClock& operator=(const CycleClock&) = delete; }; +using CycleClockSourceFunc = int64_t (*)(); + +class CycleClockSource { + private: + // CycleClockSource::Register() + // + // Register a function that provides an alternate source for the unscaled CPU + // cycle count value. The source function must be async signal safe, must not + // call CycleClock::Now(), and must have a frequency that matches that of the + // unscaled clock used by CycleClock. A nullptr value resets CycleClock to use + // the default source. + static void Register(CycleClockSourceFunc source); +}; + } // namespace base_internal } // namespace absl diff --git a/absl/base/internal/per_thread_tls.h b/absl/base/internal/per_thread_tls.h index 2428bdc1238e..56359853bcb5 100644 --- a/absl/base/internal/per_thread_tls.h +++ b/absl/base/internal/per_thread_tls.h @@ -16,13 +16,17 @@ #define ABSL_BASE_INTERNAL_PER_THREAD_TLS_H_ // This header defines two macros: +// // If the platform supports thread-local storage: -// ABSL_PER_THREAD_TLS_KEYWORD is the C keyword needed to declare a -// thread-local variable ABSL_PER_THREAD_TLS is 1 +// +// * ABSL_PER_THREAD_TLS_KEYWORD is the C keyword needed to declare a +// thread-local variable +// * ABSL_PER_THREAD_TLS is 1 // // Otherwise: -// ABSL_PER_THREAD_TLS_KEYWORD is empty -// ABSL_PER_THREAD_TLS is 0 +// +// * ABSL_PER_THREAD_TLS_KEYWORD is empty +// * ABSL_PER_THREAD_TLS is 0 // // Microsoft C supports thread-local storage. // GCC supports it if the appropriate version of glibc is available, |