diff options
author | Fangrui Song <maskray@google.com> | 2024-02-01 15:05:42 -0800 |
---|---|---|
committer | Copybara-Service <copybara-worker@google.com> | 2024-02-01 15:06:59 -0800 |
commit | 971eada3489dcc991b59df44c559078bfaa1c024 (patch) | |
tree | 897699bb9320ef32b5c912ca9ad92a2b68676a1b /absl/time | |
parent | 7339447a7f457f1d8efa6322c971e71afc304d32 (diff) | |
download | abseil-971eada3489dcc991b59df44c559078bfaa1c024.tar.gz abseil-971eada3489dcc991b59df44c559078bfaa1c024.tar.bz2 abseil-971eada3489dcc991b59df44c559078bfaa1c024.zip |
Decrease the precision of absl::Now in x86-64 debug builds
CycleClock::Now utilizes ABSL_INTERNAL_CYCLECLOCK_SHIFT to discourage reliance
on the raw CPU cycle counter values. As a side effect, it discourages
strictly-increasing assumption. Apply the idea to discourage over-reliance on
the precision of absl::Now/absl::GetCurrentTimeNanos.
Programs relying on a very high precision often exhibit portability issues on
machines with a lower cycle counter precision, or worse, race conditions. For
example, Apple M1 emulated x86 RDTSC only guarantees weakly-increasing RDTSC
values.
x86 clock speed is usually measured in GHz and is still precise after we drop 8
least significant bits.
PiperOrigin-RevId: 603493500
Change-Id: Ib1b00075109283f5dbcb39a43fe0ab722351a1e2
Diffstat (limited to 'absl/time')
-rw-r--r-- | absl/time/clock.cc | 16 |
1 files changed, 15 insertions, 1 deletions
diff --git a/absl/time/clock.cc b/absl/time/clock.cc index aa74367b..ecd539e5 100644 --- a/absl/time/clock.cc +++ b/absl/time/clock.cc @@ -88,11 +88,25 @@ ABSL_NAMESPACE_END namespace absl { ABSL_NAMESPACE_BEGIN namespace time_internal { + +// On some processors, consecutive reads of the cycle counter may yield the +// same value (weakly-increasing). In debug mode, clear the least significant +// bits to discourage depending on a strictly-increasing Now() value. +// In x86-64's debug mode, discourage depending on a strictly-increasing Now() +// value. +#if !defined(NDEBUG) && defined(__x86_64__) +constexpr int64_t kCycleClockNowMask = ~int64_t{0xff}; +#else +constexpr int64_t kCycleClockNowMask = ~int64_t{0}; +#endif + // This is a friend wrapper around UnscaledCycleClock::Now() // (needed to access UnscaledCycleClock). class UnscaledCycleClockWrapperForGetCurrentTime { public: - static int64_t Now() { return base_internal::UnscaledCycleClock::Now(); } + static int64_t Now() { + return base_internal::UnscaledCycleClock::Now() & kCycleClockNowMask; + } }; } // namespace time_internal |