Commit 971eada3 by Fangrui Song Committed by Copybara-Service

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
parent 7339447a
...@@ -88,11 +88,25 @@ ABSL_NAMESPACE_END ...@@ -88,11 +88,25 @@ ABSL_NAMESPACE_END
namespace absl { namespace absl {
ABSL_NAMESPACE_BEGIN ABSL_NAMESPACE_BEGIN
namespace time_internal { 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() // This is a friend wrapper around UnscaledCycleClock::Now()
// (needed to access UnscaledCycleClock). // (needed to access UnscaledCycleClock).
class UnscaledCycleClockWrapperForGetCurrentTime { class UnscaledCycleClockWrapperForGetCurrentTime {
public: public:
static int64_t Now() { return base_internal::UnscaledCycleClock::Now(); } static int64_t Now() {
return base_internal::UnscaledCycleClock::Now() & kCycleClockNowMask;
}
}; };
} // namespace time_internal } // namespace time_internal
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment